21년 2월 25일

한 일

  • 코드 스쿼드 수업을 통해 자바의 기본 쓰레드 사용법을 배웠다.

    • java의 sleep, interrupt, run, start, wait, notify, notifyAll 등을 실습하고 각각 차이점을 알게되었다.

    • Thread.interrupted() 전역 메소드는 현재 쓰레드의 interrupted상태가 true인지 false인지 반환하고 interrupted상태를 false로 변경한다.

    • isInterrupted() 메소드는 현재 쓰레드의 interrupted상태만 반환한다.

    • java는 일반 스레드(데몬 스레드가 아닌 스레드) 가 모두 종료되야 프로세스가 종료된다.

    • 데몬 스레드는 일반 스레드가 모두 종료되면 자신의 코드가 안 끝나도 종료된다.

    • synchronized를 사용하여 동기화를 할 수 있으며, synchronized method는 this에 lock을 걸게 된다.

    • syncrhonized(Object object) {} 이 블럭은 object에 대한 lock을 걸게 된다.

    • 멀티 코어 환경에서 멀티 쓰레드를 구현해도, synchronized 블럭을 잘못쓰면 단일 쓰레드보다 성능 효율이 낮아진다. (자원 하나를 여러 쓰레드가 다투게 되므로)

    • 잘못된 사용의 예 (synchronized 위치를 확인해보자)

      package honux;
          
      class Result {
          public long sum;
      }
          
      public class Task extends Thread{
          private long start;
          private long end;
          public Result result;
          public Task(long start, long end, Result r) {
              this.start = start;
              this.end = end;
              this.result = r;
          }
          private void sum() {
              for(long i = start; i <= end; i++) {
                  synchronized(result){
                      result.sum++;
                  }
              }
              System.out.println("thread ended: " + getName());
          }
          public void run() {
              sum();
          }
          public static void main(String[] args) {
              final long n = 20000000;
              final int numThread = 5;
              final long size = n / numThread;
              Thread[] t = new Thread[numThread];
              Result r = new Result();
              r.sum = 0;
              for(int i = 0; i < numThread; i++) {
                  t[i] = new Task(i * size + 1, (i + 1) * size, r);
              }
              long start = System.currentTimeMillis();
              for(int i = 0; i < numThread; i++) {
                  t[i].start();
              }
              for(int i = 0; i < numThread; i++) {
                  try {
                      t[i].join();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              long end = System.currentTimeMillis();
              System.out.println("Elapsed time: " + (end - start));
              System.out.printf("sum of 1 to %d is %d\n", n, r.sum);
          }
      }
      
    • 올바른 사용의 예 (synchronized 위치를 확인해보자)

      package honux;
          
      class Result {
          public long sum;
          public synchronized void add(int i){
              this.sum += i;
          }
      }
          
      public class Task extends Thread{
          private long start;
          private long end;
          public Result result;
          public Task(long start, long end, Result r) {
              this.start = start;
              this.end = end;
              this.result = r;
          }
          private void sum() {
              int localSum = 0;
              for(long i = start; i <= end; i++) {
                  localSum++;
              }
              result.add(localSum);
              System.out.println("thread ended: " + getName());
          }
          public void run() {
              sum();
          }
          public static void main(String[] args) {
              final long n = 2000000000;
              final int numThread = 5;
              final long size = n / numThread;
              Thread[] t = new Thread[numThread];
              Result r = new Result();
              r.sum = 0;
              for(int i = 0; i < numThread; i++) {
                  t[i] = new Task(i * size + 1, (i + 1) * size, r);
              }
              long start = System.currentTimeMillis();
              for(int i = 0; i < numThread; i++) {
                  t[i].start();
              }
              for(int i = 0; i < numThread; i++) {
                  try {
                      t[i].join();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              long end = System.currentTimeMillis();
              System.out.println("Elapsed time: " + (end - start));
              System.out.printf("sum of 1 to %d is %d\n", n, r.sum);
          }
      }
      


  • 프로그래머스 순위검색 문제를 풀었다.

    1. 순위검색:

      이 문제는 구간 합을 어떻게 구하냐가 관건인 문제였다.

      사용언어,지원직군,경력,소울푸드 에 따라서 나눠 저장하고 (나는 [리스트 또는 배열]의 다차원 배열을 사용했다.)

      query를 읽어서 query에 해당하는 점수 리스트로부터 score 이상의 사람 수를 저장하여 반환한다.

      리스트로부터 사람 수를 가져오는 두 가지 방법이 있는데, 1번은 segment tree를 사용했고 2번은 binary search를 사용했다.

      segment tree를 사용할 경우 index가 점수값이고 value가 사람 수가 되고,

      binary search를 사용할 경우 value가 점수값이고 원소 개수가 사람 수인 차이가 있다.

      이해가 잘 되지 않는 다면 코드 를 읽어서 확인해보자


  • 자바로 조합을 구하는 새로운 방법을 알게 되었다 (비트 연산자를 이용하기)

        public List<int[]> getCombination(int n, int r) {
            List<int[]> list = new ArrayList<>();
            for (int i = 0; i < (1 << n); i++) {
                if (Integer.bitCount(i) == r) {
                    int[] add = new int[n];
                    for (int j = 0; j < n; j++) {
                        if ((i & (1 << j)) > 0) {
                            add[j] = 1;
                        }
                    }
                    list.add(add);
                }
            }
            return list;
        }
    

잘못한 것

잘한 것

  • 꾸준히 앞으로 나아가기

느낌

  • 요즘 또 너무 놀아서 죄책감이 크다.
  • 네이버 파이낸셜 지원했다는 설렘 때문에 더욱 공부를 소홀히 한거 같다.
  • 합격 여/부랑 관계없이 내 속도로 나아가자 마음을 다잡자
  • 욕심부리지말자, 붙으면 좋지만 못붙으면 아직 준비가 안된 것일 뿐, 다시 시작하면 된다.

할 일

  • 코드스쿼드 미션하기
  • 자바의 정석 읽기
  • 프로그래머스 문제 풀기