2024.12.31 TIL
[Git]
- git branch 브랜치명: 브랜치 생성
- git branch: 브랜치 확인(현재 브랜치 위치와 생성된 브랜치명 확인 가능)
- git checkout 브랜치명: 다른 브랜치로 이동
- merge하기: main 브랜치로 다시 이동한 후 git merge (main과 merge할 브랜치명)
-> 터미널 말고 github에서 merge: pull request를 통해서 코드 리뷰를 먼저 받고 merge할 수 있기 때문에 주로 사용
코드 리뷰 받고 merge후에는 다시 pull 해와서 merge한 코드 가져오기
- 메인 브랜치는 일반적으로 배포용 브랜치이기 때문에 main에 바로 merge하면 위험=> 실무에서는 개발용 브랜치를 따로 두어서 개발용 브랜치에 merge를 다 하고 이상이 없는 경우 main에 다시 merge or 로컬에서 먼저 pull을 해봄으로써 확인하고 merge
[자바]
연산자
- 논리 연산자: && (AND = 피연산자 모두 참), ||(OR = 피연산자 둘 중 하나라도 참), !(피연산자의 반대 boolean 값)-> 결과 값이 boolean 타입
- instance of 연산자: (객체명) instance of (클래스명)-> 객체가 해당 클래스의 객체인지 비교해서 boolean 값으로 반환
- 비트 연산: <<(왼쪽으로 shift, 2의 배수로 곱셈 연산되는 것과 동일), >>(오른쪽으로 shift, 2의 배수로 나눗셈 연산되는 것과 동일)
조건문
- switch문: switch { case(조건): (연산) } 형태. case의 마지막에는 꼭 break;를 달아줘야 함. 끝에 default:(연산) 붙일 수 있음
- if vs switch: if는 이중, 삼중, ~ 으로 복합 지원이 되지만 상대적으로 코드가 중복되는 부분이 많음
- 향상된 for문: for(변수 타입 변수명:배열) {연산}
배열
- 선언: int[ ] arr=new int[사이즈];
- 배열 복제: int[ ] b=a.clone(); or int[ ] b=Arrays.copyOf(a,a.length);
- 다차원 배열의 선언: 2차원-int[ ][ ] arr = new int[ ][ ]; / 3차원-int[ ][ ][ ] arr = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
- 다차원 배열에서의 가변 배열: 2차원 배열 생성시 열의 길이를 미리 지정안하고, 행마다 열의 길이를 따로 지정 가능
컬렉션
- 종류: list, set, queue, map
- List
- ArrayList: 배열처럼 일렬로 데이터 저장 및 인덱스로 조회 가능. 배열과 달리 크기 미리 지정x
- 선언 및 생성: ArrayList<Integer> intList = new ArrayList<Integer>();
- 값 추가: intList.add(값);
- 값 수정: intList.set(인덱스 번호, 수정할 값);
- 값 삭제: intList.remove(삭제할 인덱스 번호);
- 출력: intList.toString();
- LinkedList: ArrayList와 동일한 기능이지만 느림. 중간에 값 추가하는 기능이 있음
- 값 중간에 추가: linkedList.add(인덱스 번호, 추가할 값);
- Stack: LIFO(밑에서 위로 쌓고 위에서부터 꺼냄->최근 저장된 데이터 순으로 확인할 때 사용)
- 선언: Stack<Integer> intStack = new Stack<Integer>();
- 추가: intStack.push(추가할 값);
- 조회: intStack.peek(); ->맨 위 값 조회(맨 마지막에 저장된 값 조회)
- 꺼내기: intStack.pop(); -> 맨 위 값 꺼냄
- 크기 확인: intStack.size();
- ArrayList: 배열처럼 일렬로 데이터 저장 및 인덱스로 조회 가능. 배열과 달리 크기 미리 지정x
- Queue: FIFO(데이터 저장한 순서대로 값 조회)
- 선언: Queue<Integer> intQueue = new LinkedList<>();
- 추가: intQueue.add(추가할 값);
- 조회: intQueue.peek(); ->가장 처음 저장된 데이터 조회
- 꺼내기: intQueue.poll(); ->가장 처음 저장된 데이터 꺼냄
- Set: 순서가 없고 중복이 없는 배열
- 선언: Set<Integer> intSet = new HashSet<Integer>();
- 추가: intSet.add(값);
- 삭제: intSet.remove(삭제할 값);
- 포함 확인: intSet.contains(포함 확인할 값); -> boolean값으로 결과 반환
- iterator 사용: set은 인덱스값이 없어서 인덱스를 통해 값을 가져올 수가 없음! 그래서 iterator 사용하면 편리함
- hasNext(), next() 메소드로 값 확인 및 가져오기
- Map: key-value 형태로 데이터 저장
- 선언: Map<String, Integer> intMap = new HashMap<>(); -> key가 String, value가 int타입
- 추가: intMap.put(key, value값);
- 조회: intMap.get(key 값);
- 전체 key 조회: intMap.keySet();
- 전체 value 조회: intMap.values();
- 삭제: intMap.remove(삭제할 key값);
객체지향 프로그래밍
- 객체지향 프로그래밍: 현실 세계에서 어떠한 제품을 만들기 위해 부품들을 하나씩 조립해서 완성시키는 것처럼 소프트웨어 또한 필요한 부품들을 만들고 하나씩 조립해서 하나의 완성된 프로그램을 만들 수 있는데 이러한 기법을 말함
- 객체들끼리의 상호작용: 메서드를 통해 이루어짐
- 캡슐화: 접근 제어자를 통해 실제 내부 구현 내용을 외부에서 알 수 없게 감춤
- 상속: 부모 객체의 필드와 메서드를 자식 객체에 물려줘서 자식 객체가 사용할 수 있도록 함
- 다형성: 객체가 다른 여러가지 형태로 재구성됨
- 추상화: 객체의 공통된 부분들을 모아서 상위 개념으로 새롭게 선언
클래스 설계
- 단계: 1. 클래스 선언 2. 필드 정의(변수 선언) 3. 생성자 정의(= 객체 초기화 ex-public Car() { }) 4. 메서드 정의
객체 생성(=인스턴스화)
- car 클래스 객체 생성: Car car1 = new Car(); -> 생성자 불러오기
메소드 오버로딩: 동일한 메소드 이름으로 매개변수 타입이나 매개변수 개수에 따라 다르게 정의
- 인스턴스 멤버 vs 클래스 멤버: 인스턴스 멤버는 객체 생성 후에 사용할 수 있고 클래스 멤버는 객체 생성 없이도 사용 가능. 클래스 멤버는 static 키워드를 붙임, 공용적인 데이터 값을 static으로 지정함
- 인스턴스 메소드는 클래스 멤버를 사용할 수 없고 클래스 멤버는 인스턴스 멤버를 사용할 수 없음
- 상수는 static final을 붙여서 불변값으로 만듦. 상수명은 대문자로 작성
- 생성자 예시: this를 붙여서 객체 내부 멤버에 접근할 수 있도록 함
- 제어자: public, protected, default, private / static, final, abstract
- public : 접근 제한이 전혀 없습니다.
- protected : 같은 패키지 내에서, 다른 패키지의 자손 클래스에서 접근이 가능합니다(클래스 앞에 사용 불가. 메소드, 변수에만 가능)
- default : 같은 패키지 내에서만 접근이 가능합니다.
- private : 같은 클래스 내에서만 접근이 가능합니다.(클래스 앞에 사용 불가. 메소드, 변수에만 가능)
- getter, setter: 외부에서 객체의 private한 필드를 읽을 필요가 있을 때 getter, 외부에서 객체의 private한 필드를 저장 또는 수정할 필요가 있을 때 setter 메소드 사용
- 상속: 자식 클래스 명+extends+부모클래스 명으로 정의. super는 부모 필드의 멤버를 나타내고 super()는 부모 필드의 생성자를 호출
- 추상 클래스: public abstract class 클래스명{ abstract 리턴타입 메서드 이름(매개변수); } 으로 선언함. 미완성된 클래스. 나중에 자식 클래스에서 extends하여 오버라이딩을 통해 완성함
- 인터페이스: 두 객체를 연결해주는 다리 역할. 서로 다른 클래스들이 같은 메소드를 구현해야 할 때 인터페이스를 사용함. public interface 인터페이스명{} 으로 선언. 인터페이스에서 추상메소드 만들 수 있음. 인터페이스를 사용하려는 클래스에서는 implements 키워드를 통해 인터페이스를 가져와서 오버라이딩함. default, static 메소드 선언이 가능.
- default 메소드: 추상 메소드의 기본적인 구현을 제공하는 메소드. 추상메소드는 기본적으로 구현이 안되어있는 미완성 메소드인데 default를 붙이면 구현 가능. 오버라이딩도 필수가 아니게 됨