부트캠프 강의
1. 문제
   - char c2 = c1++; 가 왜 컴파일 에러가 나지 않을까?
   - int 하위 타입은 연산될 때 int로 변환되는 것으로 알고있었음
   - 따라서, c2에 담으려면 (char)로 형변환을 해줘야할 것 같다고 생각함

2. 시도
   - 다양한 케이스를 시도해보자

3. 해결
   - c1++;이 컴파일 에러가 나지 않는 이유
   : c1++는 형변환 없이 c1에 있는 값을 1 증가시키기 때문임
   - char c2 = c1 + '1'은 컴파일 에러
   : 앞서 생각한 것과 같이 c1과 '1' 모두 int로 변환돼서 연산되기 때문
   - char c2 = 'a' + 1은 컴파일 에러가 나지 않음
   : 리터럴 간 연산은 컴파일 시점에 미리 계산돼기 때문에 c2 = 'b'로 바뀜

4. 알게된 점
   - c1++과 같은 단한연산자는 형변환이 일어나지 않음
   - 내가 기억하고 있는 int 아래 형은 모두 int로 변환돼서 연산됨(잘 기억하고 있었다)
   - 리터럴 간 연산은 컴파일 시점에 미리 계산됨

코테준비

1. 백준 10800 - 컬러볼

: 생각한 방향에서 시간복잡도를 계산하고 정확하게 구현하자. 그러면 풀 수 있다!!!

 

2. 백준 1826 - 연료 채우기

: 왜 헤맸을까? 사실 굉장히 간단한 로직인 '갈 수 있는 주유소 중에서 가장 많은 주유를 할 수 있는 곳을 선택한다'가 전부인데. 아직은 이런 문제가 나왔을 때 이러한 풀이법을 처음 접해서 그런것이라고 생각하자. 너무 조급하게 생각하지말고 천천히 익혀나가보자


오늘 하루고 고생 많았다!!!

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.25  (0) 2023.07.25
2023.07.24  (0) 2023.07.25
2023.07.20  (0) 2023.07.20
2023.07.19  (0) 2023.07.19
2023.07.18  (0) 2023.07.18
부트캠프 강의 - OOP

1. 객체 자신을 가리키는 this

   (1) this

      ① 인스턴스 자신의 메모리를 가리킴

      ② 생성자에서 다른 생성자를 호출할 때 사용

      ③ 자신의 참조값을 가리킴

   (2) 만약에 day.setYear(2000) 메소드가 호출되면, 호출 스택에 setYear메서드가 올라가고 그 스택에 this도 함께 올라감. 그래서 this를 사용할 수 있음

   (3) 생성자에서 다른 생성자를 호출할 경우, 인스턴스 생성이 완전하지 않으므로 this()이전에 다른 statement를 작성할 수 없음

 

나머지는 아는 내용이므로 pass


코테준비

1. 백준 27652 - AB

: A에 들어가는 모든 접두사와 B에 들어가는 모든 접미사를 Hash에 담아서 정리해서 풀이했음. 그렇지만 더 좋은 방법은 Trie를 만들어서 하는 방법이 더 적절할 듯함. 나중에 Trie를 공부할 때 다시 풀어보면 좋을 문제!!!

 

2. 백준 10840 - 구간 성분

: 구간에 있는 알파벳의 종류와 숫자를 26개의 문자열(ex. 019000...00)로 만들어서 풀이. 맞긴했지만... 다시 생각해보니 갯수마다 구분자를 넣어줘야할 것 같다. 그렇지 않으면 중복될 경우도 있다. 테스트 케이스가 부족해서 운좋게 맞았다.


오늘 하루도 고생했다!!! 

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.24  (0) 2023.07.25
2023.07.21  (0) 2023.07.22
2023.07.19  (0) 2023.07.19
2023.07.18  (0) 2023.07.18
2023.07.17  (0) 2023.07.17
코테준비

1. 백준 3078 - 좋은 친구

: 큐에 K만큼 담고, 그 안에서 같은 길이의 이름의 갯수를 더해주면 친구 쌍의 총 수를 구할 수 있다. 이름 길이에 따라서 카운트 배열을 갱신해 나가는 것이 포인트

 

2. 백준 11577 - Condition of deep sleep

: 분명 큐를 써야한다는 것을 알았는데도 방법을 떠올릴 수 없었다. 왜일까??? 전구를 끄는 순서는 중요하지 않다는 것까 알았다. 3 - 1 - 2 순서로 끄나, 1 - 2 - 3 순서로 끄는 것이 상관이 없었다.

첫 번째 생각하지 못한 점은 한번 끈 전구를 다시 끌 필요가 없다는 점이다. 1번 전구를 한 번 껐으면, 다시 킬 일은 없다. 왜냐면 이럴경우 그냥 안키면 되는 것이므로

두 번째 생각하지 못한 점은 그리디하게 접근해서 앞에서부터 전구를 끄는 것이다. 앞에서부터 차례로 켜져있을 경우 K개만큼 스위치를 누르는 생각을 못했다. 아마도 워낙 완전탐색 문제만 많이 풀다보니 이것에 익숙해져있고, 더 나은 생각을 하지 못하는 것 같다. 단순하게 완전탐색만 생각하는 것이 아닌, 더 좋은 방법이 없는지 고민하는 습관을 들이자!!!

만약 두 번째까지 생각했다 하더라도 큐까지 쓰는 것을 생각하지 못했을 것 같다.

이번 스택과 큐 문제를 풀면서 느낀점은 '완전탐색으로 풀 수 없는 시간복잡도 문제와 무언가 그 주변에 관련된 일을 묻는 문제라면 스택과 큐를 쓰는 것을 고려하자'라는 생각을 했다. 어떻게 스택과 큐를 쓰는 것인지는 좀 더 다양한 문제를 접해보며 차차 키워나가야 한다고 생각한다.


내가 필요한 것들 공부할 것들 이번주 내로 정리해서 하나씩 나아가보자. 오늘도 고생했다!!!

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.21  (0) 2023.07.22
2023.07.20  (0) 2023.07.20
2023.07.18  (0) 2023.07.18
2023.07.17  (0) 2023.07.17
2023.07.14  (0) 2023.07.14
부트캠프 - 온보딩

1. HTTP 요청과 응답

   (1) 프로토콜이란 ?

      ① 서로간의 통신을 위한 약속 규칙

      ② 주고 받을 데이터에 대한 형식을 정의한 것

      ③ 어떤 형식으로 주고 받을 건지 약속을 정한 것 -> 그래야 서로 데이터를 알 수 있음

      ④ 예를 들어 야구에서 모자를 만지면 번트, 코는 안타 -> 서로간의 약속으로 소통

   (2) 따라서, 프로토콜은 약속이다

   (3) HTTP : Hyper Text Transfer Protocol

      ① HTTP는 하이퍼 텍스트를 전달하는데 사용되는 약속이다

      ② 텍스트 기반으로 되어있음. 예를 들어, [ GET /hello HTTP1.1 ... ] 처럼 주고받을 데이터가 텍스트로 되어있어서 단순하고 사람이 읽기 쉬움

      ③ 상태를 저장하지 않음. 클라이언트 정보를 저장하지 않음 -> 이를 보완하기 위해 쿠키 & 세션을 사용

      ④ 확장이 가능함. 헤더에 사용자가 직접 만든 헤더를 추가할 수 있음

   (4) HTTP는 편지와 비슷함(Header와 내용으로 구성되어 있음)

   (5) HTTP는 클라이언트와 서버 간 요청 편지와 응답 편지를 주고받는 것과 비슷하다

   (6) 동작 순서

      ① 클라이언트가 브라우저에 URL을 입력

      ② 브라우저는 요청 메시지를 HTTP에 맞춰서 만든 후에 서버에 전송

      ③ 서버는 응답 메시지를 HTTP에 맞춰서 다시 클라이언트에 전송

      ④ 클라이언트는 응답 메시지를 분석해서 내용을 브라우저에 보여줌

   (7) 응답 메시지의 구성

      ① 상태코드 : 1xx, 2xx, ... 5xx

      ② 헤더

      ③ 바디

      -> 이렇게 구성되어 있는 것이 HTTP 규약에 맞는 '응답 메시지'. 이렇게 작성되어있어야 클라이언트가 이해할 수 있음

   (8) 요청 메시지의 구성

      ① 요청라인 : GET, POST 

      ② 헤더

      ③ 바디

   (9) GET은 버서에 리소스를 얻어오는 용. 그래서 바디가 없음. 그렇지만 쿼리스트링으로 데이터 전송 가능

   (10) POST는 서버에 리소스를 보내는 용. 바디에 리소스를 담음(ex. 게시글 등록, 로그인, 회원가입)

 

2. 텍스트와 바이너리 MIME, Base64

   (1) 텍스트 기반 프로토콜에서 바이너리 데이터(ex. 이미지, 파일)을 전송하려면 어떻게 할까?

   (2) HTTP의 Content-Type 헤더를 사용 -> Content-Type은 바디 데이터의 타입을 명시하는 헤더임

   (3) Post 방식의 form-data를 이용하면 body에 바이너리 데이터를 보낼 수 있음

   (4) 이 바이너리 데이터는 Base64(64진법)으로 나타내서 보내짐. 64비트를 사용하는 이유는 모든 OS에서 기본적으로 사용하는 문자를 사용해서 디코딩을 가능하게끔 하기 위해

 

3. 관심사의 분리와 MVC 패턴

   (1) 관심사의 분리 : 기존 코드는 ① 입력, ② 처리, ③ 출력 으로 나누어져 있음(3개의 관심사로 나누어져 있음)

   (2) 입력의 분리 -> 입력을 처리하는 부분을 앞으로 분리

   (3) 처리와 출력의 분리 -> 계산하는 부분과 출력하는 부분을 분리. 그런데 처리한 데이터를 출력부분과 연결지어야 하므로 이 때 사용하는 것이 Model 객체임

   (4) C(데이터 처리) -> M(모델) -> V(뷰, 출력) -> 이 모양이 MVC패턴임

 

4. MVC 패턴의 원리

   (1) DispatcherServlet은 Reflection을 이용해서 사용할 클래스(Controller)의 메서드를 알아내고 그 매개변수에 필요한 값을 넣어줌

   (2) 어떻게 Controller가 view이름만 전달해도 뷰를 반환해줄까?

   (3) DispatcherServlet은 해시맵인 model을 만들고 반환 받은 view에 model을 같이 전달한다

 

5. 서블릿과 JSP

   (1) jsp와 서블릿은 거의 비슷. 그리고 이를 발전시킨 것이 Spring

   (2) Servlet은 Java코드 안에 HTML

   (3) JSP는 HTML코드 안에 Java

   (4) JSP는 서블릿으로 변경되어서 서블릿으로 등록된다

1. 문제
   - 직접 Servlet을 만들어서 등록하면 DispatcherServlet은 거치지 않겠네?

2. 시도
   - 직접 해보자

3. 해결
   - 그렇다. 직접 Servlet을 등록할 경우 DispatcherServlet은 거치지 않는다

4. 알게된 점
   - Servlet을 직접 등록하면, DispatcherServlet과 함께 Servlet은 두 대가 된다
   - DispatcherServlet도 하나의 Servlet에 불과하다. Servlet 다음인 Controller에서 비즈니스 로직에 집중할 수 있도록 도와주는 Servlet일 뿐임

코테 준비

1. 백준 2812 - 크게 만들기

: stack 자료구조를 이용해서 푸는 문제이다. 사실 stack 문제라는 걸 알고 풀어서 쉽게 풀었지만, 만약 몰랐다면 어땠을까. 자료구조를 이용한 문제를 많이 풀어보면서 감을 익혀야 할 것 같다

 

2. 백준 3425 - 고스택

: 새로운 stack을 만드는 아주 빡빡한 구현문제였다


하루하루 꾸준히!!!

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.20  (0) 2023.07.20
2023.07.19  (0) 2023.07.19
2023.07.17  (0) 2023.07.17
2023.07.14  (0) 2023.07.14
2023.07.13  (0) 2023.07.13
부트캠프 - 온보딩

★ Spring MVC

1. 원격 프로그램의 실행

   (1) 한 컴퓨터에서 다른 컴퓨터의 프로그램을 실행하려면

      ① 서버쪽에서 프로그램을 바깥에서 돌릴 수 있도록 등록해 놓아야함

      ② URL과 프로그램을 연결해 놓아야함

   (2) 위 두가지를 했을 경우, 브라우저로 원격 프로그램을 실행할 수 있다

   (3) class 앞에 @Controller는 서버에 프로그램을 등록해 놓는 것이고, 메서드 앞에 @RequestMapping("...)는 URL과 프로그램을 연결해 놓는 것이다

   (4) 그런데 메서드가 인스턴스 메서드인데 호출할 수 있는 이유가 뭘까? 인스턴스 메서드를 호출하려면 누군가 객체를 생성한다는 뜻임

   (5) 메서드가 private이어도 되는 이유는 뭘까? Reflection API를 사용하기 때문임. 이는 클래스 정보를 얻고 다룰 수 있는 강력한 기능인데, 클래스 설계도를 가져와서 인스턴스를 만들고 private메서드를 실행할 수 있기 때문임

 

2. AWS에 배포하기

   (1) AWS 인스턴스에 톰캣의 webapps 폴더에 war파일 넣기

   (2) 그 후 톰캣 실행

 

3. HTTP 요청과 응답

   (1) http://.../che/hello로 요청하면 tomcat이 요청 정보를 HttpServletRequest 객체로 만들어줌

   (2) 이는 마치 main메서드의 String[] args로 전달되는 것과 비슷함

 

4. 클라이언트와 서버

   (1) Controller의 메서드에 매개변수를 쓰면 스프링이 HttpServletRequest 객체를 만들어서 넣어줌

   (2) 우리는 그 객체를 활용하면 됨

   (3) 어떤 서비스를 제공하는지에 따라 서버의 종류가 나뉨(ex. EmailServer, FileServer, WebServer)

   (4) 만약 1대의 PC에서 여러개 서버가 돌아가려면? PC의 IP주소만으로 어떤 서버에 요청할지 구분할 수 없음

   (5) 따라서, 포트번호도 필요함

   (6) 한 포트에는 한 서버만 있을 수 있는데, 이 상태를 서버가 포트를 리스닝 한다고 함

   (7) Web Server란 웹을 서비스하는 것

   (8) Web Application Service란 웹 어플리케이션(웹 프로그램)을 서비스 하는 것임

   (9) 이전에는 프로그램을 모두 클라이언트에 설치해야 했음

      ① 그래서 update 문제가 발생 : 프로그램이 update됐을 경우, 모든 PC의 프로그램이 update돼야함. 그러나 서버는 서버만 하면 됨

      ② 클라이언트의 저장 공간이 부족 문제 발생. 그러나 서버는 서버에서만 이용하면 됨

   (10) 톰캣의 내부 구조

      ① 요청이 포트를 통해 서버로 전달됨

      ② ThreadPool에서 하나의 Thread가 일처리를 시작

      ③ Connector에서 요청을 분류해서 요청 객체를 만듬

      ④ Host -> Context -> Servlet을 거친 후 클라이언트에 응답함


코테준비

1. 백준 5430 - AC

: 앞과 뒤에서 번갈아 빼야하므로 deque을 이용함. 빈 문자열을 split하면 빈 문자열 하나가 나오는 것 주의

 

2. 백준 3190 - 뱀

: 덱을 이용했지만 큐를 이용해도 될 것 같다. 빡빡한 구현 문제였다. 제한시간 안에 풀지 못한 점...!!


오늘 하루도 고생 많았다... 힘든 하루였다..!!

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.19  (0) 2023.07.19
2023.07.18  (0) 2023.07.18
2023.07.14  (0) 2023.07.14
2023.07.13  (0) 2023.07.13
2023.07.12  (0) 2023.07.12
부트캠프 - 온보딩 강의

★ 배열과 클래스의 관계

1. 동일한 구조와 이질적인 구조

   (1) 배열과 클래스는 데이터를 담는 역할에는 같다

   (2) 차이점은 배열은 동일한 데이터를 담는 동일한 구조이고, 클래스는 이질적인 데이터를 담는 이질적인 구조이다

 

★ static과 JVM 메모리 모델 이해하기

1. static과 메모리의 관계

   (1) 시작클래스는 왜 객체생성(new) 없이 실행이 될까?

   (2) 메인 클래스가 동작하는 방식을 이해해야함

      ① JVM이 실행할 클래스를 찾는다(시작 클래스를 찾음)

      ② 찾은 후에, static 키워드가 붙은 멤버들을 메모리의 Method(Static) Area에 로딩됨. static 멤버들은 클래스를 사용하는 시점에 한번 메모리에 로딩됨. 우리는 시작 클래스에서 main이 static이므로 메모리에 로딩됨

      ③ JVM이 Method(Static) Area에 있는 main 메서드를 호출

      ④ call stack에 main을 넣고 동작을 시작한다

public class Static {
    public static void main(String[] args) {
        int result = sum(3, 5);
    }
    
    public static int sum(int a, int b) {
        return a + b;
    }
}

 

2. static과 non-static 멤버들의 접근 방법

   (1) main메서드에서 instance를 하나 생성해서 heap에 메모리를 올린 후, 사용

   

3. JVM이 사용하는 메모리 영역

   (1) Method Area

      ① static 변수와 static 메소드가 할당되는 공간

   (2) Heap Area

      ① 객체가 생성되는 메모리 공간(new 연산자를 이용)

      ② 객체는 개발자가 직접 생성해서 Heap에 메모리가 할당되는데, 다 사용하면 소멸을 시켜줘야함

      ③ GC(가비지 컬렉터)가 메모리를 관리함 -> 주기적으로 Heap에 접근해서 만약 어떤 메모리를 가리키는 포인터가 없다면 청소됨

   (3) Stack Area

      ① 메서드가 호출되면 기계어 코드를 할당받고 메서드가 실행되는 메모리 공간

      ② 스택처럼 위에 계속 쌓임(Last In First Out)

   (4) Runtime Constant Pool(Literal Pool)

      ① 상수값 할당이 되는 메모리 공간(ex. 123, "apple")

 

4. 객체 생성과 static과의 관계

   (1) 어떤 클래스의 모든 멤버가 static 멤버인 경우?

   (2) 객체를 생성해서 static을 사용하는 것이 아닌, 클래스이름.static멤버 로 사용하게끔 하는 것이 더 바람직함

   (3) 따라서, 생성자를 private로 만들어서 객체 생성을 막는다

 

5. Class, Object, Instance 구분하기

   (1) Class : 객체를 모델링하는 도구

   (2) Object : 클래스를 통해서 선언되는 변수

   (3) Instance : 실체, 객체 생성에 의해 Heap 메모리에 만들어진 객체


코테준비

1. 프로그래머스 - JadenCase 문자열 만들기

: 간단한 문자열 문제


해야할게 너무 많다...ㅜㅜ 급하게 생각하지 말고 천천히 하나씩 완성해나가자. 천천히, 꾸준히란 말을 꼭 기억하자

만다라트를 한번 작성해보는 것도 좋은 방법인 것 같다. 오늘도 고생했다!!!

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.18  (0) 2023.07.18
2023.07.17  (0) 2023.07.17
2023.07.13  (0) 2023.07.13
2023.07.12  (0) 2023.07.12
2023.07.11  (0) 2023.07.11
JAVA의 정석
1. 문제
   - ByteArrayInputStream input = new ByteArrayInputStream(inSrc)를 생성해서 사용할 때, 왜 input.read()는 exception을 잡을 필요가 없는데 input.read(temp)는 exception을 처리해야 할까?(temp는 byte[]임)

2. 시도
   - 코드를 보자. input.read() 메소드의 코드는 ByteArrayInputStream 클래스에 있고, input.read(temp)는 InputStream 클래스에 있다
   - 그런데, ByteArrayInputStream의 read()는 InputStream의 read()를 overriding한 것인데, InputStream의 read에는 abstract int read() throws IOException이 있고 ByteArrayInputStream에는 throws가 없다
   - 추상 메소드를 구현할 때, 이 메서드 또한 throws Exception을 하지 않아도 되는건가?
   - 직접 확인해보자. 추상클래스, 인터페이스 모두 그렇다. 추상 메서드에 throws Exception이 되어있다고 하더라도 구현체는 throws Exception을 안해도된다

3. 해법
   - 위 문제로 돌아가서,
   - input.read()는 왜 exception을 처리하지 않아도 될까?
      ① read() 메서드의 InputStream은 throws를 하지만 구현체는 throws 하지 않는다.
   - input.read(temp)는 왜 exception을 처리해야 할까?
      ① read(temp) 메서드는 ByteArrayInputStream에는 overriding이 안되어있으므로 InputStream 것을 사용한다. 그리고 여기에는 throws IOException이 되어있다

4. 알게된 점
   - 처음에 추상 메서드에 throws가 선언되어있으면, 구현체에도 throws가 선언되야한다고 생각했다
   - 하지만, 반대로 생각했다. 구현체에서 throws를 하려면 추상 메서드에 throws가 있어야한다가 정답이었다
   - 그렇다면 그냥 InputStream input = new ByteArrayInputStream(inSrc)를 하면 read()를 하더라도 exception을 처리해야한다. 왜냐하면 InputStream의 read메서드는 exception을 던지기 때문

부트캠프 온보딩 강의

★ 우리가 만들어보는 클래스의 종류

1. 모델이란 무엇인가

   (1) 현실에는 다양한 객체가 있고, 그 객체는 역할이 있다 -> 프로그래밍 세계에서는 크게 3개의 역할로 구분한다

   (2) 그 객체를 설계하는 것이 모델링

   (3) 모델이란 = 클래스를 역할에 따라 부르는 이름이다

   (4) 모델의 종류 : [시작 클래스], [DTO, VO], [DAO], [Utility]

      ① DTO, VO : 데이터를 담는 모델(저장하거나 이동에 편리), Data Transfer Object, Value Object의 줄임말

      ② DAO : 데이터를 처리하는 모델, DB에 Access해서 처리하는 모델, Data Access Object

      ③ Utility : 도움을 주는 모델

 

2. DTO, VO가 왜 필요한가?

   (1) 데이터를 하나로 묶어야될 경우 필요함(바구니가 필요, 데이터를 하나로 수집하는 역할임)

   (2) 만약 메서드에 인자가 100개라면? 100개를 다 보내줘야함 -> 넘기는 쪽, 받는 쪽 모두 불편

   (3) 이 때 DTO, VO를 사용하면 편리

 

3. DAO가 왜 필요한가?

   (1) DB에 데이터(DTO, VO)를 CRUD하기 위해서 만들어지는 클래스

   (2) 비즈니스 로직을 처리하는 클래스

 

4. Utility가 왜 필요한가?

   (1) 반복적으로 사용해야될 동작(기능)을 별도의 클래스로 만들어 놓고 필요할 때 사용하기 위해

 

★ 객체를 접근하는 권한 이해하기

1. 접근권한이란

   (1) 객체는 혼자 사용되지 않음 -> 객체는 다른 객체에 의해 사용되기 위해서 만들어짐

   (2) 접근을 허용하거나 허용하지 말아야 될 부분을 정해야함 -> 이것이 접근권한

   (3) 객체 상호간에 접근을 제어하기 위해서 접근제한자를 사용한다

   (4) 젭근제어가 필요한 이유? 객체의 상태정보는 중요해서 접근을 못하게 막야아하므로

   (5) 보통 상태 정보는 접근을 막고, 행위 정보는 상호작용을 위해 허용함

   (6) 접근을 제한하는 방법 : 클래스와 클래스 내부에 만들어지는 멤버(변수, 메서드)에 모두 사용 가능

      ① public : 모든 패키지에서 접근 가능

      ② private : 오로지 자기 자신에서 접근 가능

      ③ protected : 상속 관계에서 하위 클래스에서 상위 클래스로 접근 가능

      ④ default : 같은 패키지에서만 접근 가능

1. 문제
   - private이 자기 자신에서만 접근이 가능이니깐 상속 관계에서 하위 클래스도 접근을 못하는 것이 맞을까?

2. 시도
   - 직접 만들어보자

3. 해결
   - 하위클래스도 접근할 수 없었다

4. 알게된 점
   - private은 오로지 자기 자신에서만 사용 가능하다
   - 그렇다면 상속관계에서 자식 클래스가 부모의 멤버 변수에 접근하려면 어떻게 해야할까?
   - protected로 하거나 private을 사용하려면 자식 클래스에서 부모의 getter나 setter를 사용해야함

 

2. 패키지란 무엇인가

   (1) 서로 기능이 비슷한 클래스들끼리 모아서 관리를 쉽게 하기 위해서 사용(폴더 개념임)

   (2) 패키지 외부에서 클래스의 접근을 할 수 없도록 사용(보안을 위해, 그렇지만 잘 사용되지 않음)

   (3) 자바에서 제공해주는 API도 패키지의 형태로 제공함

 

3. 클래스를 접근하는 이름 이해하기

   (1) 클래스 이름은 크게 두 가지로 나눌 수 있음

      ① 패키지를 포함하지 않은 클래스 이름 : Scanner

      ② 패키지를 포함한 클래스 이름 : java.util.Scanner -> java 패키지 안의 util 패키지 안의 Scanner 클래스가 있다는 뜻

   (2) 매번 클래스 full name을 적을 수 없으므로 import를 통해 해결한다

   (3) import java.util.Scanner을 하면 full name을 쓰지 않고서도 클래스를 사용할 수 있음

   (4) import java.lang.*은 작성해주지 않아도 디폴트로 작동한다

1. 문제
   - IntelliJ에서 쉽게 도와주는 static import는 어떻게 작성하는 걸까?

2. 시도
   - 직접 사용해보자

3. 해결
   - import static java.lang.Math.abs 를 할 경우 int a = abs(3.5)처럼 사용할 수 있었음
   - import static java.lang.Math.PI 또한 System.out.println(PI)를 할 수 있었음

4. 알게된 점
   - static을 import할 때는 'import static'을 적어서 사용한다

 

★ 잘 설계된 VO 클래스

1. 정보 은닉이란?

   (1) 다른 객체에게 자신의 정보를 숨기고, 동작, 기능, 연산만을 통해 접근을 하게끔 하용하는 것

   (2) 클래스 외부에서 특정 정보의 접근을 막는 것을 뜻함

1. 문제
   - Person class에 private int age 필드를 두고, public void method() 함수에서 Person p = new Person()을 생성한 후 p.age는 사용이 가능할까?

2. 시도
   - 직접 해보자

3. 해결
   - 가능하다

4. 알게된 점
   - private멤버는 해당 클래스에서는 자유롭게 사용할 수 있다

 

2. setter, getter 메서드 만들기

   (1) 은닉된 정보에 접근하기 위해 getter와 setter를 만든다

 

3. 생성자를 이용한 초기화

   (1) 생성자를 이용해서 객체를 초기화할 수 있다

   (2) 생성자를 오버로딩해서 다양하게 초기화가 가능하다

1. 문제
   - 생성자에서 this.setName(name)을 할 수 있을까?

2. 시도
   - 직접 해보자

3. 해결
   - 가능하다

4. 알게된 점
   - this는 자기 자신을 가리키는 것이므로 멤버변수, 메서드 모두 사용할 수 있다
   - 그렇지만 굳이 저렇게 사용하는 것보다 생성자에서는 this.name = name을 사용할 것 같다
1. 문제
   - 멤버변수 초기화가 안됐다면, 사용할 수 있을까? 사용할 수 있다면 어떤 값이 들어가있을까?

2. 시도
   - 다양한 타입을 모두 시도해보자

3. 해결
   - int 멤버변수에는 0이, 객체에는 null이, boolean에는 false, char에는 'NUL'이 초기화가 되어있었음

4. 알게된 점
   - 멤버변수는 초기화를 하지 않아도 기본값이 할당이 된다
   - 그렇지만 지역변수는 초기화를 꼭 해주어야한다. 그렇지 않으면 컴파일 에러가 남

 

4. toString() 메서드로 객체값 출력하기

   (1) 객체가 갖고 있는 값은 매번 getter로 갖고와서 알아볼 경우 불편함(100개면?)

   (2) toString() 메서드를 만들어서 객체 멤버 변수 값을 String으로 받아보자

1. 문제
   - 기억상으로 System.out.println(person)을 하면 자동적으로 person.toString()의 결과가 나오는 것으로 알고있는데 어떻게 그럴 수 있을까?

2. 시도
   - 직접 해보고 코드를 보자

3. 해결
   - 객체의 toString()이 출력된다
   - System.out.println(object) 메서드를 보면 object.toString()을 출력하게끔 설계되어있다

4. 알게된 점
   - toString() 메서드는 Object 클래스로부터 상속되었으므로, System.out.println(object)를 구현할 수 있다는 것을 깜빡했다... 생각해보면 당연한 것을!!! 조금 더 차분히 생각해보자

 

5. 잘 설계된 VO 클래스

   (1) 설계 방법

      ① 모든 상태정보를 정보 은닉하기(private)

      ② 디폴트 생성자 만들기(사용하지 않더라도)

      ③ 생성자 오버로딩으로 객체 초기화

      ④ getter, setter

      ⑤ toString() 메서드 만들기(객체가 갖고 있는 전체값 출력 목표)


코테준비

1. 프로그래머스 - 뒤에 있는 큰 수 찾기

: N이 100만이므로 바로 떠오르는 방법인 이중 for문으로 해결할 수 없다. 이럴 경우 특별한 '자료구조'나 '알고리즘'을 사용해서 풀어야하는데, 정렬 알고리즘에만 꽂혀서 어떻게 풀지 고민하다가 다른 사람의 풀이를 보고 Stack 자료구조를 사용해야함을 알게되었다. '자료구조'를 이용해서 푸는 방법이 있다는 것을 명심하자

 

2. 프로그래머스 - 최솟값 만들기

: 두 배열을 정렬한 후 하나는 앞에서 하나는 뒤에서부터 탐색하며 서로를 곱해서 합을 구한다


Java책 필수적으로 완독하자. 오늘도 고생했다!

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.17  (0) 2023.07.17
2023.07.14  (0) 2023.07.14
2023.07.12  (0) 2023.07.12
2023.07.11  (0) 2023.07.11
2023.07.10  (0) 2023.07.10
야놀자 테크캠프 - JAVA

기본적으로 아는 내용 이므로 '문시해알' 방법으로 정리

1. 문제
   - 정수형 리터럴은 기본형이 int, 실수형 리터럴은 기본형이 double이다(int i = 123에서 123은 int형으로 저장된다)
   - 그래서 long l = 123에서 123은 int여서 더 큰 범위인 long에 할당될 수 있다
   - 그리고 만약 long l = 12345678900과 같이 int범위를 넘어선 리터럴에서는 '이 리터럴은 long형으로 저장해줘'를 의미하는 L을 숫자 뒤에 붙여줘야한다(long l = 12345678900L)
   - 마찬가지로 float f = 3.14는 에러가 나는데, 3.14의 기본형은 double이고 이 리터럴은 더 작은 범위인 3.14에 저장하려고 하니 에러가 난다. 그러므로 float f = 3.14F로 변경해줘야한다
   - 그렇다면 byte b = 100을 하면 100은 int이고 더 넓은 범위이므로 에러가 나야할 것 같은데, 에러가 나지 않았다

2. 시도
   - short s = 100도 에러가 나지 않았다. char c = 65도 에러가 나지 않았다
   - 하지만, byte b = 200을 했을 경우 에러가 났다
   - 아마도, byte의 범위를 넘어선 int 리터럴을 저장했을 때 에러가 난다고 생각

3. 해결방법
   - 'Java의 정석' 책을 찾아보았다
   - byte와 short타입의 리터럴이 별도로 존재하지 않아서 int 타입의 리터럴을 사용한다고 한다
   - 다만, 각 타입의 변수가 저장할 수 있는 범위에 속한 것이여야 함

4. 알게된 점
   - 이 후 더 검색해서 찾아보니
      ① 리터럴은 일시적으로 스택(operand stack)에 저장됨(문자열 제외)
      ② 그래서 스택에 byte, short, int형 리터럴은 모두 4byte로 저장이 됨. 만약 12345678900과 같이 int 범위를 넘어서는 리터럴일 경우 8byte를 알려주기 위해 L을 붙임. 그리고 실수형은 8byte로 저장되는데 4byte인 float에 저장하기 위해 F를 붙임
      ③ 스택에 저장된 리터럴을 나중에 변수에 저장할 때, 그 때 형변환이 일어나면서 변수에 저장됨
   - byte, short의 operand stack공간이 4byte이므로 int 리터럴을 저장할 수 있었던 것임. 그리고 그것이 나중에 형변환이 일어난다
1. 문제
   - 컴퓨터로 실수를 표현할 때 왜 오차가 생기는 걸까?
   - 컴퓨터가 실수를 표현하는 방식인 부동소수점 때문에 생긴걸까?

2. 시도

3. 해결방법
   - 이진 표현의 한계 : 예를 들어 1/10은 십진수로 0.1로 표현되지만, 이진 수로는 0.000110011...이렇게 무한소수로 표현됨. 이로 인해 근사치를 사용하게 되고 여기서 오차가 발생함
   - 반올림 오차 : 컴퓨터는 유한한 비트로 실수를 표현하기 때문에, 이 때 반올림이 일어나고 여기서 오차가 발생함

4. 알게된 점
   - 실수를 표현할 때 오차가 생기는 중요한 이유는 '십진수를 정확하게 이진수로 표현할 수 없기 때문'임
   - 그러므로 고정소수점 방식이나 부동소수점 방식 모두 실수를 표현하는데 오차가 생김
   - 고정소수점과 부동소수점
      ① 고정소수점 : 숫자를 정수부와 소수부로 나누고 그 숫자를 이진수로 변환한 후 그대로 저장하는 방법
      ② 부동소수점 : 숫자를 정규화를 거쳐 특정 숫자로 만들고 그 숫자를 저장하는 방법
   - 부동소수점을 더 많이 쓰는 이유 : 고정소수점은 비트 수 대비 표현가능한 숫자가 적어서 사용하지 않음

야놀자 테크캠프 - Git, Github

1. Branch 관리하기 -> 가장 중요

   (1) 버전의 분기를 나눌 수 있음. 브랜치를 왜 나누고 어떻게 나눌지 알아야 함

   (2) 버전을 여러개의 흐름으로 나눈다

   (3) 브랜치가 없을 경우

      ① 만약 A ... -> ... 흐름이 있고, B ... -> ... 이 있을 때, 합치는 과정에서 하나하나씩 모두 비교해야함

      ② 각 사용자마다 요청이 다를 경우 무수한 파일을 만들어야함

   (4) 브랜치로 해결해보자

   (5) 브랜치 순서

      ① 브랜치를 나눈다(별도의 작업환경으로 나눈다)

      ② 각자의 브랜치에서 작업한다

      ③ 나눈 브랜치를 합친다(필요하다면)

   (6) 브랜치를 활용했을 경우

      ① 서로가 다른 부분을 수정했을 경우 -> 합쳐줌

      ② 서로가 같은 부분을 수정했을 경우 -> 충돌이 일어나서, 개발자가 직접 지정 후 해결

   (7) 브랜치 이름 : feature/menu처럼 브랜치 이름을 보고 짐작할 수 있도록 짓

   (8) 브랜치 명령어

      ① git branch : branch목록들과 현재 내가 있는 branch를 보여줌

      ② git branch foo : foo 브랜치 생성

      ③ git checkout foo : foo 브랜치로 이동 후 가장 최신 commit으로 이동

 

2. 충돌 해결하기

   (1) stash, apply, revert, pull, merge ... 등등 충돌은 여러 상황에서 발생하지만, 해결하는 방법은 모두 동일함

   (2) 결국 같은 부분을 다르게 수정했을 때 나타나는 현상임

   (3) 충돌은 큰 코드베이스에서 일상이므로 충분히 연습해서 당황하지 말자

   (4) 해결 방법

      ① 어떤 브랜치의 내용을 반영할지 직접 선별한다. 남기고자 하는 내용물을 남김(어디가 충돌났는지 git이 표시해줌)

      ② add후 commit

 

3. Github

   (1) 깃허브는 파일을 업로드하는 곳이 아니라, 버전(커밋) 내역들을 업로드하는 곳임

   (2) clone을 한 경우에 버전들이 다운받아지는 것


git, github강의는 끝났지만, 아직 부족하고 모르는 부분이 많다고 생각한다. 이번주는 git 기초부터 스스로 공부해보자.

'TIL(Today I Learned)' 카테고리의 다른 글

2023.07.14  (0) 2023.07.14
2023.07.13  (0) 2023.07.13
2023.07.11  (0) 2023.07.11
2023.07.10  (0) 2023.07.10
2023.07.08  (0) 2023.07.10

+ Recent posts