지난주에 마감한 카카오게임즈에서 기술직군 인턴에 지원했는데 코딩테스트 대신 사전과제가 있었다. 인턴십 지원 기간에 업로드 할 만한 내용은 아니라 시간이 좀 지난 오늘부터 포스팅을 시작하기로 했다.
아무래도 사전과제 1번 항목의 경우 업무 수행에 관한 서술과제이다 보니 조금 조사가 필요했다. 채용 정보 사이트에서 카카오게임즈 채용에 대해 검색해 보니 기술지원 PM에 대한 채용의 지원 조건, 우대 사항과 인터뷰 등을 검색으로 확인할 수 있었고 그림처럼 플랫폼과 서비스 인프라 두 가지로 요약할 수 있었다.
해당 항목에 대해선 구체적인 서술 내용은 올리지 않으려 한다. 기술직군 entity 내부의 resolve Technical Issue와 사업, 개발사, 기술직군, QA 사이의 Issue를 연관 관계로 기술직군을 중심으로 개발사와의 어떤 기술적인 이슈 해결을 위해 소통을 할지에 대해 기술했다.
import java.util.PriorityQueue;
class Solution {
public int solution(int[] scoville, int K) {
// 전처리 ,입력
PriorityQueue<Integer> pq = new PriorityQueue<>();
int answer = 0;
for ( int i : scoville ){
pq.add(i);
}
// 계산
int a, b;
try{
while (pq.peek() < K ){
a = pq.poll();
b = pq.poll();
pq.add(a + 2 * b);
answer++;
}
} catch(Exception e){
return -1;
}
return answer;
}
}
프로그래머스에서 기본 연습문제로 제공하는 Heap 문제
우선순위 큐를 사용해서 첫번째와 두번째 값을 가져오는데 특정 값 K가 만족 되지 않으면 계속 반복하는데 while(true)를 사용하면 불가능한 경우에도 출력하려다가 NullPointException을 발생시키게 된다. 그 에러 케이스를 이용해서 return -1을 사용하여 문제 해결
마리아디비 설치는 sudo apt-get install mariadb-server를 터미널에 입력하면 설치할 수 있고 mysql과 사용법이 똑같아서 sudo mysql -uroot -p로 쉽게 접속할 수 있지만 라즈베리에 설치하다 보니 온라인으로 접속할 필요를 느껴서 워크벤치랑 온라인으로 연결하기로 했다.
나는 mariadb-server를 사용하니까 /etc/mysql/mariadb.conf.d 디렉토리 안에 있는 50-server.cnf를 편집한다.
$ sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf
bind-address = 127.0.0.1 부분을 주석처리하거나 지워준다. 일부러 구분하기 편하게 ## 두개로 주석처리했다.
bind-address는 해당 IP 주소에서 접속만 허용한다는 의미다. 루프백 IP 혹은 localhost로 부르는 IP가 127.0.0.1이니까 컴퓨터 내부에서만 접속을 허용한다는 의미다.
$ sudo service mysql restart
service 대신에 systemctl을 써도 상관없다. 설정을 바꿨으니 재실행 시킨다.
[mysql]> grant all on <DB이름>.<테이블> to <'user'>@<'host'> identified by <'password'>; [mysql]> flush privileges;
host 부분에 '%'를 넣으면 모든 IP에서 접근이 가능해지고 'localhost' 혹은 '127.0.0.1'을 넣으면 라즈베리파이에서만 접근이 가능하다. 원격으로 조회가 안된다는 뜻.
모든 DB와 테이블에 권한을 부여하고싶으면 *.* 을 특정 DB만 부여하고싶으면 <특정 DB이름>.* 를 특정 DB의 특정 테이블만 권한을 부여하고싶으면 <DB 이름>.<해당 DB에 있는 테이블 이름>을 적는다.
This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.
해시코드 메서드는 따로 오버라이딩을 하지 않으면 객체의 내부 주소를 정수형으로 반환한다.
따로 객체를 만들고 오버라이딩 하지 않은 후 System.identityHashCode()를 사용해서 비교해봤다.
public class A{
priavte int a;
A(int a){
this.a = a;
}
}
public class Main(String[] args){
A a = new A(1);
A b = new A(1);
System.out.println("address of a\t: " + System.identityHashCode(a));
System.out.println("hashCode of a \t: " + a.hashCode());
System.out.println();
System.out.println("address of b\t: " + System.identityHashCode(b));
System.out.println("hashCode of b \t: " + b.hashCode());
System.out.println();
System.out.println("a.equals(b) : " + a.equals(b));
}
실행 결과
당연히 해시코드를 따로 선언해주면 잘 돌아간다.
public class A{
priavte int a;
A(int a){
this.a = a;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
return result;
}
}
hashCode() 오버라이드 결과
해시코드하면 떠오르는 게 있는데 HashMap, HashSet, HashTable들이다.
해시코드를 키로 사용하는 애들이니까 hashCode()만 오버라이드하면 같은 객체로 인식하지 않을까 테스트 해봤다.
import java.util.HashMap;
public class Main(String[] args){
HashMap<A, Integer> hm = new HashMap<>();
A a = new A(1);
A b = new A(1);
hm.put(a, 1);
hm.put(b, 1);
System.out.println("address of a\t: " + System.identityHashCode(a));
System.out.println("hashCode of a \t: " + a.hashCode());
System.out.println();
System.out.println("address of b\t: " + System.identityHashCode(b));
System.out.println("hashCode of b \t: " + b.hashCode());
System.out.println();
System.out.println("a.equals(b) : " + a.equals(b));
System.out.println("HashMap Size : " + hm.size());
}
HashMap
해시맵 사이즈를 보면 해시코드값만 같다고 키값이 같은건 아니란걸 알 수 있다.
자세히 알아본 결과 해시 구조를 사용한 자료구조에서는 HashCode를 먼저 비교한 후에 해시코드가 동일하면 equals()를 통해서 동치성을 확인한다는 내용이었다.
More formally, if this map contains a mapping from a keykto a valuevsuch that(key==null ? k==null : key.equals(k)), then this method returnsv; otherwise it returnsnull. (There can be at most one such mapping.)
여기서 K가 의미하는 자료형이 해시코드라는걸 생각한다면 해시구조에서 동치성을 확인 할 때 해시코드를 먼저 비교하고 해시코드가 같으면 equals()로 동치성을 확인한다는걸 알았다.
만약에 해시코드만 다르다? 동치성은 확인조차 못하고 넘어간다.
# Reference Type의 경우는 위에서 서술한 Object Class에서 상속받은 HashCode()와 equals()를 오버라이딩 하거나 시메모리 기본 메서드를 활용해서 동치성을 확인하지만 Primitive Type은 어떻게 동치성 ( == )을 확인할 수 있는 이유는 다음과 같다.
변수 선언부는 JVM의 Runtime Data Areadptj JVM Stack에 저장되고 기본형 타입의 데이터는 스택에 바로 저장하는 것이 아니라 Method Area 내부에 상수를 저장해둔 공간의 주소를 point 한다.
그래서 각 기본형 타입의 변수는 Method Area에 저장된 상수값을 불러오는 것이도 동치성을 확인하는 작업 ( == ) 에서는 상수의 주소를 비교해서 동치성을 체크하게 된다.