정의한 데이터와 로직으로 이루어져있음 → 적합한 알고리즘과 자료구조로 결과가 많이 달라짐 : 코드 작성에 중요한 요소. 객체의 사용 자원을 미리 정의해야 한다
동일한 작업을 최소한으로 수행하는 작업을 최적화라고 생각함.
알고리즘의 효율성을 판단하는 척도. → 컴파일 하는 시간 + 수행 시간 (주로 빅오) ex) 트리형태 : (logN), 이중 for문 : (N^2)
꼬리질문 : 시간복잡도의 유용성 → 알고리즘 수행시간이 단축 - 사용자는 빠른 응답을 받을 수 있음. (더 좋은 사용자경험)
공간복잡도 : 알고리즘에 필요한 자원 / 변수저장공간/ 함수저장 스택
정렬 알고리즘에 대한 설명
버블 정렬 : 두 인접한 데이터 크기 비교, 작은걸 앞으로 큰걸 뒤로 놓는 형태의 비교. 복잡도는 (N^2)
선택 정렬 : 최대/최소로 정렬할지 결정, 최소로 정렬할 경우 범위 내에서 가장 작은 값들을 차례로 앞으로 정렬하는 형태
삽입 정렬 : 하나의 데이터를 올바른 위치에 옮기는 방식 시간 복잡도는 구현 방법에 따라 N^2에서 NlogN이 될 수 있음
병합 정렬 ; 두개의 단위로 묶어 잘개 분할한 다음 집합들에 대해 정렬하여 합치는 방법 복잡도는 NlogN
꼬리질문 : 자바에서? → 퀵정렬을 사용하고 있음. 하나의 피벗을 정해서 왼쪽에는 작은 값들, 오른 쪽에서는 그것보다 큰 값들을 놓는 방식. 정렬 완료되는 경우 각 집합에 대해 피벗을 정해서 다시 정렬하는 과정을 반복.
정렬 알고리즘이 백엔드에 왜중요함? → 백엔드는 데이터를 많이 다룸, 정렬을 할 경우가 많을 것. 클라이언트에게 요청을 받고 데이터를 보내줄 때 정렬알고리즘이 많이 사용됨 ( ex : 기간 - 10월 1일부터 10월 15일까지의 데이터 요청)
해시테이블의 작동 원리와 사용 사례
키에 대해 해시함수를 적용하여 해시를 얻은 다음 밸류를 저장. (키 - 밸류 저장)
해시테이블에서 값을 가져올때 해시값을 사용하여 가져옴. 보통 리스트셋을 사용할 때 해시테이블을 사용함. 데이터를 가져오는 것은 상수시간만큼의 시간복잡도를 가짐. 동작할 때 해시펑션,capacity, 버킷으로, 해시에 모듈러 연산을 적용하여 값을 얻은 다음 데이터에 접근 (열심히 정리해봤지만 틀린 부분이 있을 수 있습니다 ㅠㅠ)
재귀함수 : 특정 조건을 만족하였을 때 자기자신을 만족하는 함수. 종료할 때도 조건이 있어야함. 재귀적으로 표현하기 자연스러울때 가독성을 위해, 변수 사용을 줄일 때 (변경 가능한 상태를 최대한 줄여 에러 발생을 줄일 수 있다는 장점) 꼬리 재귀방식으로 개발하는 것이 중요, 꼬리 재귀란 함수 형태로 리턴하는 것이 아닌 인자를 넘겨주는 것. 함수 형태로 재귀함수를 구현하는 경우 스택에 함수를 관리해야함, 스택 메모리에 오버헤드가 발생할 수 있다는 단점이 커짐.
객체지향이란 ? : 상태와 행위를 가진 객체로 만들어 객체들의 상호작용을 통해 로직을 구성하는 프로그래밍 방법. 객체란 연관된 변수나 메소드를 묶어 만든것.
꼬리질문 :장점? → 재사용성, 객체 단위 자원 관리는 자원의 책임을 정의할 수 있음. - 의도한 대로 로직이 동작할 수 있게끔 할 수 있다. 결론 : 객체지향적으로 코드를 정의함으로써 재사용성이 높아지고 의도한 대로 로직을 동작시킬 수 있다.
단점으로는? → 속도가 느리다. 절차지향의 경우 컴파일할 때 실행 전 함수 리스트를 묶어 실행시 함수를 찾아가서 실행. 객체지향의 경우 코드 보고 이해는 쉬우나 각 함수나 클래스에 대한 의존성 관리가 필요하고, 로직을 실행하는 데에 절차 언어에 비해 느리다.
클래스와 인스턴스에 대해 설명? 클래스란 요구사항이나 정의로 생각할 수 있음. 정의를 실체한 것이 인스턴스(객체)로, car라는 클래스가 있을 때 클래스 안의 여러 속성을 넣고 메소드를 정의하고 메소드를 통해서 속성을 다룰 수 있음. 클래스를 만든다고 직접 다룰 수 있는 것은 아니며, 메모리에 실제 클래스를 인스턴스화 (실체화)를 해야 객체를 사용할 수 있음. 결론적으로, 클래스는 정의한 내용 (클래스에 어떤 내용인지)으로 설명할 수 있으며, 인스턴스는 클래스를 사용할 수 있게끔 실체화한 것으로 표현할 수 있음.
다형성, 캡슐화, 상속의 이해와 활용 :
다형성: 컨트롤러나 서비스레이어의 데이터 이동을 위해 DTO를 사용하게 됨, 이 클래스에서 entity를 만들어줄 때 필요한 변수가 다를 수 있음. 다형성을 오버로딩하여 동일한 메소드지만 인자 수나 자료형을 다르게 받아 엔티티를 만들어주는 경우로 사용할 수 있음.
캡슐화 : 책임 위임 이라는 키워드로 설명할 수 있음. 로직 작성 시 어떤 객체가 어떤 책임을 갖는지 정하는 것이 중요함. 속성값에 의존적인 로직 작성시 유지보수하는 것은 매우 어려움. 캡슐화에 대해 설명하면, 외부에서 내부의 값을 마음대로 정할 수 없음 (User의 경우 User에서 get,set으로 직접 사용하는 것이 아닌 업데이트 메소드를 직접 정의하여 User에서 수정을 수행하는 책임을 넘길 수 있음). 이는 서로간의 코드 결합도를 낮추며, 이는 유지보수를 쉽게 함.
활용되는 접근 제어자는 public, private, protected, default가 있음.
종류에 대한 설명? : public : 어디서든 호출 가능. private : 클래스 내에서만 호출 가능. protected의 경우 동일한 패키지에서 클래스를 상속받은 클래스까지 사용할 수 있음. ex) User를 상속받은 Userdetails의 경우 user의 protected 변수를 사용할 수 있음. default는 동일한 패키지에서만 사용 가능.