Posts

901. Online Stock Span

이전에 비슷한 접근법을 요구하는 문제가 있었는데, 그 기억대로 접근해서 한번에 해결. 무식하게 매번 전체 array 를 search 할수도 있는데 그러면 Time limt exception 이 뜰거라고 생각했다. 그런데 그렇게 해서도 accept  가 된 솔루션이 있어보이긴 했지만 아무튼. 요지는 두  array 를 관리 하면서, 현재  price 와 span 을 기록하는데, 현재를 기준으로,  현재보다 이전 날짜의 span 은 그 날보다 가격이 같거나 작은날이 며칠인지를 이야기해주고 있으므로, 하루씩 back 할 필요 없이, 이 span 만큼 건너뛰어서 체크를 할수 있다. 물론 index outOfBound 는 피해야 한다. 처음 submit 할때는, 계산하는 함수를 따로 만들어서 뺐었는데, 그랬더니 32ms 가 나왔다. 가장 빠른 성능은 17ms 여서 뭔가 하고 봤는데 내 접근이랑 똑같은데 함수 호출만 없는거였다. 그래서 나도 private 함수로 뺀 부분을 그냥 합쳤더니 17ms 가 나왔다.  보통 이런 함수 호출이 성능에 그만큼 큰 영향을 주나 싶지만, 주어진 조건에 테스트케이스당 최대 만번의  호출을 하고, 전체 테스트케이스 합산시 15만번의 호출까지 한다고 하니. 함수스택 한번 들어갔다 나오는게 늘어나는만큼 유의미한 차이가 있긴 있었나보다. 그래봤자 15ms 가 일반적으로 쉽게 인식 가능한 범위는 아니지만. 아래의 calculateNewSpan 이 문제의 그 추가적인 함수 호출이었다. class StockSpanner { private int [] priceArray ; private int [] spanArray ; private int count ; public StockSpanner () { priceArray = new int [ 10000 ] ; spanArray = new int [ 10000 ] ; count = ...

547. Number of Provinces

한번에 풀지 못했고, intelliJ 를 통해 디버깅을 해야만 했다. 하지만 그렇게 해서라도 해결은 했다.  일단 첫번째 문제는,  정사각형 매트릭스에서 대각선은 전부 1 이기 때문에 대각선의 반쪽만 확인하면 될거라고 생각했는데, 맨 위 row 나 i맨 아래 row 같은 경우는, 맨 왼쪽 혹은 맨 오른쪽에서 시작해야만 자신의 connected node 를 가져올 수 있다.  그래서 0부터  iteration 을 도는데, visited 정보를 따로 관리 하지 않으면 이게 이미 빠진 건지 아닌지를 알 방법이 없다. 그래서 다시 무한루프에 걸렸었다.  visited 를 이용하니 해결. 성능은 좋지 않다.  4ms  였지만, 25% 일단 나의 접근은 set 에 전체 노드를 집어 넣어놓고 꺼내면서, 연관된 node 들을 다 꺼내는 priority queue 를 관리하는 것이었다. 그래서 기존의  set 이 empty 가 되면 종료. 일단 내 접근에서 문제점은, 쓸데없이 PQ 를 썼다는 것이다. 아무이유 없이. 그냥 Queue 를 썼어도 되었었다. 그리고 실제  node 들을 마치 당구공을 주머니에서 꺼내서 다른 주머니에 넣듯이 했는데. HashSet 으로 visit  을 관리할 필요가 전혀 없이, boolean[n] visited 만으로도 충분했다. 그래서 처음부터 각 node 를 Set 에 넣을 필요도, visited 를 set 에 넣을 필요도 없었다. DFS 로도 접근할 수 있는데, 이렇게 접근한 어떤이의 해결법은 다음과 같다. 아래 풀이를 보고 있자면 사실 그렇게 복잡할 필요도 없었겠다는 생각이 든다. public int findCircleNum ( int [][] isConnected) { boolean [] visited = new boolean [isConnected. length ] ; int provinces = 0 ; for ( int i = 0...

Join, FetchMode, FetchType, Fetch Join 에 대해

JPA를 사용할때, 테이블간 join 시 fetch 를 어떻게 하느냐에 따라 DB 에 실제로 hit 하는 query 가 달라지고, 성능에도 영향을 미친다.  아래와 같은,  고객 주문과 (CustomerOrderEntity, customer_orders) 주문history (CustomerOrderHistoryEntryEntity, customer_orders_status_history_entries) 를 담당하는 테이블이 있다고 할때 이런 query가 있다고 하자. @Query( "SELECT t FROM CustomerOrderEntity t JOIN t.orderHistory s WHERE NOT EXISTS (SELECT 1 FROM t.orderHistory intern_s WHERE intern_s.sequenceNumber > s.sequenceNumber) AND ((s.status IN ('DELIVERED', 'CANCELED') AND s.timestamp >= :finishedAfter) OR s.status IN ('CHECKEDOUT', 'DISPATCHED', 'CUSTOMER_NO_ANSWER'))" ) List<CustomerOrderEntity> findAllActiveOrFinishe...

아무도 기다려주지 않는다.

독일에 와서 정말 제대로 느낀게 하나 있다. 금요일 이후에, 스케쥴 표에 우리팀만 이름이 빠져있어서, 채워넣야하지 않냐고 물어봤는데 아무도 답이 없었다. 그러다 다음 월요일에, 다른 사람이 이야기를 다시 꺼내서, 채워넣야 하니 미팅을 하자고 했더니 다들 참여했다.  미팅에서 screenshare 할사람이 없어서 조금 기다리는 공백이 있었는데. 이때라도 나섰어야 했는데 머뭇거렸다. 아무일도 아니었음에도 말이다. 그러곤 빈 slot 에 각자 이름을 넣을 사람을 찾는데 저마다 자기 이름을 넣어달라고 했다. 나는 기회를 기다렸다가 말하려고 했는데. 내가 말할 틈을 주지 않았다. 진짜 모여서, 자기가 되는 시간은 주저없이 자기 이름을 넣어도 된다고 바로바로 말했다. 그렇게 약 5분만에 미팅이 끝났다. 공정한 분배나 이런건 말하지도 않았다.  아무도 기다려주지 않는다. 모두가 서로 돕고 돕는다. 그런데 도와달라고 말을 해야한다. 그러면 언제든 도와준다. 하지만 말을 해야한다. 적극적으로 의사표현을 해야한다. 내가 하겠다고 해야한다. 도움이 필요하다고 해야한다. 뭔지 잘 모르겠다고, 내가 할 수 있다고, 말을 해야한다.  쭈볏쭈볏 머뭇머뭇 하면 기회가 날라가는 것이다. 

자유도 100의 환경에서. 나는 아무것도 할 줄 모른다.

 주입식 교육의 단점이라기엔 스스로 잘하는 사람들이 너무 많다. 소극적인 성격이라기엔 소극적인거랑 일 하는거랑 무슨 상관인가. 양으로 치는거. 이거이거 이렇게 해. 라고 누가 정해주는거. 이런건 밤을 새고, 주말을 써서 한다. 그리고 혼자 뿌듯해한다. 해냈다. 이러면서.  하지만 빈 종이와 연필을 주고. 한번 해봐. 하면 못한다.  뭘 어떻게 해야할지 모르겠다.아무런 생각도 들지 않는다. 리서치를 해야한다고 해도 뭘 어떻게 서칭 해야하는지 감이 안잡힌다. 스펙 던져주고 구현해 라고 하면 마음이 편하다. 이런 방식은 남이 봤을때 비효율적이다. 시간을 많이 투자할줄만 알지, 그 시간 대비 효율성을 따졌을때 가치가 높지 않다. 다른 이유도 있지만, 경력에 비해 경험의 깊이가 별로 깊지 않은 이유이다. 논리적 전개를 해내지 못하면, 다양한 변수가 발생하는 상황에서 일단 문제 해결이 힘들다. 하더라도 효율적인 방안을 제시하지 못한다.  혼자서 생각해내는 힘이 없으면, 평생 남이 던져주는 스펙만 개발하고 살아야 한다. 극히 일부분만 보면서. 그러면 더 높은 곳으로 올라갈 수가 없다. 좋고 나쁘고가 아니라. 연차에 비해 지혜가 없으면 설 자리가 없게 된다.  그러면 시키는대로만 했기 때문에, 경험도 별로 쌓이지 않는다. 회고 할 것도 없고. 가치있는 경험을 했다고 말하기 어렵다.  지금이라도, 늦었더라도, 자유도 100이 주어지면. 나만의 전략을 세워야 한다. 그러기 위해선 목표가 무엇인지를 항상 기억하고. back tracking 이 될수도 있다. 전략을 세우고 싸워봐야. 지더라도 배우는게 있고 발전이 있다. 

peer review feedback 을 받았다.

처음으로 동료들로부터 feedback 을 받았다. 내가 지정한 동료들로부터 받으나, 나에게 돌아오는 결과는 익명이다.  예상했던 대로 self-initiative 는 낮았다. 그러나,quality of work, 나 efficiency  에서도 좋은 점수를 받지 못했다. 평균이란 소리는, 더 잘해야 한다는 소리다. 의외로 team effect 나 knowledge, work commitment 는 좋은 점수를 받았다. 열심히 하고 잘 아는데, 효율적이지 못하고, 스스로 나서지 않으며, 신경써서 일하지 않는다는 결과. 문제를 해결할 때 문제 해결뿐만 아니라, 그 주변의 코드들로 추가적으로 보는 습관들 들여야 한다. 문제를 해결할 때 이 해결된 방안이 다른 부분에 영향을 끼치지는 않는지도 생각해야 한다.  적극적 참여와 의견 개진은, 계속해서 들어오고 있는 피드백이다. 빠르고 바로바로 커뮤니케이션 하라는 주문도 들었다. 말도 못하고 영어는 더 못하는 나를 동료들도 답답해 한것이다.  미안함과 동시에, 답답하기도 했고. 발전의 여지를 인지했고, 발전했음을 나중에 볼 수 있다면 좋겠지만. 참 힘들것이라는것을 알기에. 마음이 좋지만은 않다.

design pattern #13 Behavioral pattern - Command

- 툴박스에 쓸 버튼을 하나 만들었다고 치자. 이 버튼을 상속시켜, 여러가지 저장하기, 복사하기, 붙여넣기 등의 버턴을 만든다고 치자. 뭐가 문젠가? - 문제가 충분히 될 수 있다. 일단, subclass 종류가 너무 많다. 그건 그렇다 치더라도, 복사하기가 버튼에만 있는게 아니고. 메뉴에도 있고, 단축기로도 가능하다. 단축기나 메뉴를 버튼에서 상속하자니 말이 안되고, 그렇지 않으려면 중복된 코드가 생기게 된다.  - command 패턴을 레스토랑에 비교했다. 손님이 테이블에서 주문을 하면, 웨이터는 이를 받아 적어 주방 어딘가에 stick note 를 붙여 놓는다. 요리사는 이 목록대로 음식을 만들어서 다시 내놓고. 웨이터는 목록과 음식을 최종 확인 한 뒤 손님에게 가져다준다. - 비즈니스로직과 GUI 분리의 관점에서, 위 상황의 버튼과 기능을 분리하는게 당연하지만, command 패턴이 말하는건 그냥 분리가 아니다. GUI 가 비즈리스 로직에 request 를 바로 보내는 것이 아니라, 따로 분리된 Command 라는 클래스에, 비즈니스 로직에 필요한 데이터들을 모아두고,  Command 라는 클래스에는 이 요청을 수행하는 method 하나가 존재한다. 그러면 GUI 가 비즈니스 로직에 대해 잘 몰라도, Command 만 트리거 하면 된다.  - Command 클래스는 보통 parameters 가 없는 execute method 하나만 가진다. - 그럼 명령 수행에 필요한 매개변수 같은건 어떻게 넘기는가? 아래 예제를 보면,  Command abstract class 에 생성자로  Editor 를 받는데, Editor 자체로 충분하다. 다른 경우에도, 생성자의 매개변수로 넘기고, execute() 함수에서 각 command 별 자세한 처리를 한다.  - Command  패턴은 이렇듯 객체와 할 행동을 같이 묶어 객체로 넘기는데 사용되고, 객체로 넘기기 때문에 serialize 가 가능하고, rev...