Posts

Showing posts from June, 2020

IDENTITY_INSERT가 OFF로 설정되면 테이블 'products'의 ID 열에 명시적 값을 삽입할 수 없습니다.

Springframework JPA 를 사용해왔는데,  PostgreSQL, MySQL 에선 본적이 없던 에러가 나왔다. 테이블 ID 컬럼 속성에 auto increment 옵션을 달아놨는데 JPA에서 create 를 할때 id   값을 지정하려고 하니 이런 에러가 발생했다.  영어로는 Cannot insert explicit value for identity column in table 'products' when IDENTITY_INSERT is set to OFF 이런 식이다. 그냥 이 에러로 검색하면 해결법이 테이블 속성을 바꾸거나, 아래와 같이 쿼리를 수행 할 때 이전과 이 후에 처리를 해주는 것으로 나왔다. SET IDENTITY_INSERT (table) ON INSERT  SET IDENTITY_INSERT (table) OFF 하지만 JPA 를 사용할때는 이런 쿼리를 수행하기가 까다로워서 더 찾아봤다. 해결 방법은 간단했는데, @GeneratedValue (strategy=GenerationType. IDENTITY ) 를 Entity 클래스의 column  선언에 추가해 주면 된다.  public class ProductEntity { @Id @GeneratedValue (strategy=GenerationType. IDENTITY ) @Column (name = "id" , nullable = false ) public int id ; } 이런 식으로 수정을 해주고 나니 에러 없이 데이터 추가가 잘 되었다.  

Only Black Lives Matter?

충격적이고 슬픈 사건이 미국에서 발생한지 한달. 이 사건이 계기가 되어 미국은 물론 전 세계적으로 black lives matter 라는 운동이 일어났다.  폭력 사태가 발생하기도 했으며, 한인 타운의 가게를 포함 백화점들이 약탈 당했다는 소식도 들었다.  분명 일어나선 안되는 일이고 슬픈 일이지만. 이 운동에는 반문이 생긴다. 프리미어리그가 다시 시작하면서,  모든 선수들이 유니폼의 이름 자리에 black lives matter   라는 문구가 적힌 유니폼을 입고 뛰었다. 취지는 좋다. 그런데 좀 이상했다. 손흥민도, 미나미도도 그 유니폼을 입고 뛰었다. 아시안이 black lives matter  를 외치는 것 같았다.  맨유와 토트넘의 언젠가의 경기에서. 손흥민이 넘어졌을때, 포그바는 박수치는 듯한 제스쳐를 취했다. 비꼬는 듯한 표현으로읽혔다. 손흥민이 아시안이 아니었으면, 포그바는 그런 제스쳐를 취했을까? 박지성 입단 때부터 맨유를 응원하게 되었지만, 박지성 응원가에 그들은 인종차별적인 요소를 담은 응원가를 붙였다.  중남미 어느 국가와 우리나라가 국가 대표팀 경기를 했을때도. 눈을 양 옆으로 찢는듯한 제스쳐는 물론이고, 심지어는 부상선수의 치료를 위해 들고 들어간 구급상자를 밖으로 내팽개치는 선수도 있었다. 유럽의 국가와 대항전이었다면, 아무리 지고 있는 상황이라도 그런 행동을 했을까.  백인은 그들이 흑인보다 위라고 생각한다. 흑인은 백인과 동등한 대우를 해달라고 요구한다. 그런데 그 둘에겐 공통점이 있는 느낌이다.  아시안은 둘다 i don't care 라고 생각하는 듯 보인다.  인간이라고 생각을 안하는건가.  그들이 길거리에 나와 시위를 하는 이유는 정말로 모든 인종차별에 대한 증오라기 보단, 그렇게 하면 깨어 있는 행동을 하는것 같기 때문이라고 생각한다. 결국은 힘의 논리이고, 본인에게 유리한 대로 행동하는 기저가 깔려 있겠지만. 유럽에서...

refactoring #1 composing method

composing method  refactoring 의 제일 기본. 코드가 길면 이해하기 어려워지고, 이해하기 어려우면 변경하기도 어렵다. 변경하기 어려워지면 방치될 수 있고, 잠재적인 결함의 원인이 되거나, 비즈니스 로직의 변경에 대처하는 비용이 증가하게 된다.  독일에 와서 일하기 시작하면서,  code review 엄격하게 하는 환경이 되었는데. 가장 먼저 내가 받았던 review 들은 너무 길어서 이해하기 힘들다는 것이다. 별로 안길다고 생각했는데, 다시 생각해보니 "모르는 사람, 혹은 처음보는 사람 입장에서 코드를 봤을 때 이해하기 쉬운지" 의 관점에서 생각해본적은 한번도 없는 것 같다. 여러차례 review 에서 지적을 받은 끝에, 지금은  commit 할 때마다 길이를 다시한번 확인하는 습관이 생겼다. 제일 기본적인 내용이지만 생각해봐야 할 점들이 있다. 1. refactoring 혹은 review 를 하다보면 주석으로 적혀있는 것이 그대로 함수명이나 변수명이 되는 경우, 혹은 assert 의 문구가 되는 경우가 있다. 그런 경우 함수명이나 변수명이 그 뜻을 제대로 내포하지 못했다는 뜻이거나, 주석이 더 잘 표시했다는 경우이다.  우리회사에서의 주석의 정체는, what 보다는 why 에 대해 남기자는 정책인데,  why 에 대한 입장에서 naming 하는것이 더 깔끔한 경우가 있는것 같다. Exception 을 던지는 경우에도, Exception 옆에 주석을 다는 것보다, Assert(condition, "comment"); 로 표시하는 것이 더 깔끔해보였다. 2. 쪼개는 것의 단점 if(a() || b()) 의 경우,  a() 가 true 이면 b 는 실행하지 않는다. 어차피 true 이기때문이다. 하지만 이걸 extract 해서 위로 빼면  aa= a() bb = b() if (aa || bb) 같은 식이 되므로, 이때는 항상 a(), b() 를 모두 실행한다. 따라서 re...

독일 추천 수분크림 올리브놀 (Olivenöl) 제품 비교 / 후기 - 약국에 팔아요!

Image
독일에 올때 가져왔던 Dr.Jart  크림이 다 떨어져서 새로 사려고 수분 크림을 찾아봤다. 아마존을 통해 쓰던 크림을 다시 살수도 있었지만, 독일에 왔으니 독일 추천 수분 크림으로 바꿔봐야겠다고 생각했다.  많은 독일 추천 혹은 독일 선물 필수 아이템 등으로 수분 크림이 여러개가 나왔지만, 뭔가 자연 친화적일 것 같은 디자인에 향이 강하지 않고 은은한 향 일것 같아서 올리브놀 수분크림을 선택했다.  내가 찾아봤을때는 DM  에서 판다고 해서 시내  DM 들을 여기저기 가봤는데, 모두 없다고 했다. 스크린 샷을 보여주며 직원에게 물어봐도 없다고만 했다. 그래서 안파나 싶어 약국을 가봤는데, 약국에 진열되어 있는게 아닌가. 올리브놀 수분 크림은 약국에 있다.  다른 도시에는 DM 에 있을수도, 하지만 DM 에 없다면  약국에 한번 가보라고 말하고 싶다. 나는 수분크림을 찾고 있었는데, 올리브놀 제품에도 여러가지 타입이 있는것 같았다.  이건 50ml 작은 타입이고, 큰 타입도 따로 판다. 아마 100ml 였던것 같다. 일단 50ml 두개를 한번씩 써본 뒤 맞는 제품으로 큰 용량을 다음번에 사려고 한다. Feuchtigkeitspflege [Moisturizing] 수분 크림 Gesichtspflege [Facial care] 페이셜 케어  둘다 향은 강하지 않고, 은은한 기분 좋은 향이다. 향은 비슷한 것같다. 둘다 요거트 같기도하고. 두 타입의 차이가 조금 있는데, 수분 크림은 좀 촉촉한 느낌이고, 페이셜 케어는 좀더 고체감이 있는 느낌이다. 엄청 큰 차이가 있다기보단, 두개를 비교했을때 상대적인 차이라고 보면된다.  번들거림을 피하고 싶다면 페이셜 케어가 좋을것 같고 액체감을 선호한다면 수분 크림이 좋을것 같다. 아, 가격은 똑같았던것 같고,  각각 10-11 유로 사이였던것 같다. 

개발자 커리어로 해외 취업, 독일 이직 프로세스

요즘은 국내 IT 기업도 이런 프로세스를 많이 따라가고 있는것 같다. 아래는 내가 해외 이직을 목표로 준비하면서 밟았던 몇몇 프로세스 경험을 종합했다. 0.  최초 컨택 크게 두가지 경로가 있는데, 링크드인에 프로필을 업로드하고 관리를 하다보면 연락이 오는경우. 그리고 내가 직접 링크드인에서 지원을 하거나 회사 홈페이지의 오픈 포지션에서 지원을 하는 경우이다.  링크드인에 프로필을 업로드하고 관리를 하다보면, 메세지를 받게 된다. 두가지의 경우가 있는데, 하나는 헤드헌터로부터 받는 경우, 그리고 하나는 채용하는 회사의 HR 로부터 받는 경우이다.   헤드헌터의 경우 채용하는 회사의 이름이나 구체적인 정보를 오픈하지는 않는다. 자신의 고객이 인재를 구하고 있는데 너의 프로필이 매칭되는것 같다, 괜찮다면 짧게 소개하고 이야기를 하고싶다, 라는 식이다. 회사의 리크루터가 직접 컨택하는 경우도 있는데, 이때는 보통 팀 소개도 간략히 해주기도 한다. 우리회사의 이런 팀에서 어떤인재를 찾고 있는데 너의 프로필이 잘 어울리는것 같다. 전화를 통해 자세한 이야기를 하고싶다, 라고 온다.  처음엔 몰랐지만, 몇번 메세지를 받다보니 내용은 복붙하고 이름만 바꿔서 뿌리는것 같은 느낌이다. 내가 조건을 필터링해서 구인공고를 검색할 수 있듯이, 리쿠르터들도 키워드를 검색해서 매칭되는 프로필들에게 뿌릴 수 있는것 같다. 운좋게 가고싶었던 회사 인사팀으로부터 연락이와서 정성스레 답장을 보냈는데, 그 뒤로 아무런 응답이 없는 경우도 있었다. 직접 지원을 하는 경우에도,  끝끝내 답장이 오지 않는 경우가 더 많았던것 같다.  1. 첫번째 인터뷰 첫번째 인터뷰는 주로 전화 혹은 스카이프로 짧게 진행되었다. 헤드헌터나 인사팀과 서로 소개하는 식이었다. 주로 받는 질문은 이런것이었다. - 왜 한국을 떠나려고 하는지 - 왜 삼성을 떠나려고 하는지 - 여기서 일하는데 비자를 갖추고 있는지 - 일을 한다면 언제부터 일할 수 있는지 그러면서 ...

삼성전자 무선사업부 퇴사 후기

"잠깐 드릴 말씀이 있는데요."  8월 어느날. 갑작스런 내 메신저에, 이미 예상을 하셨는지도 모르겠다. 몇주간 보인 내 근무 태도와, 먼저 메신저로 이런말을 하는 적이 한번도 없는 내가 면담을 요청한거나 마찬가지니. 갑자기 죄송스럽지만, 퇴사를 하겠다고 말씀을 드렸다. 신입사원으로 입사한지 6년 반만이었다.  삼성전자. 글로벌 기업이지만. 그래서일까. 우리나라에서 사기업,대기업 하면 가장 많이 사람들의 입에 오르며, 연일 다양한 언론의 주목을 다각도로 받는 기업. 명절에 가족 친지들을 만나면, 어르신들은 항상 요즘 삼성 어떠냐, 라고 물으셨었다. 내가 어떤지보다는. 무선사업부. 사람들 일상에 제일 가까운 핸드폰을 만들기도 하고, 내가 다니던 동안은 성과급 이야기에 무선 이야기가 늘 빠지지 않았다. 많은 사업부들이 있지만, 적어도 내가 입사 할때는 많은 개발직군은 무선이 최우선 지망이었다. 사내 댓상에서 조차, 삼성에는 전자와 후자가 있고, 전자에는 무선만 있습니다 라는 이야기를. 무선이 아닐때 들었었다. 그땐. 부럽기도 하고 어이가 없기도 했는데. 네임밸류  주위에선 잘다니는 회사를 왜 나오려고 하냐고. 그 안이 전쟁이라면 바깥은 지옥이라고. 이런 말들을 해줬었다. 누구나 아는 회사를 다니면 편하다. 아무도 뭐하는 곳이냐고 묻지않는다. 어렵게 설명하지 않아도 된다. 부모님도, 아들 어디 취직했어? 라고 물어오는 질문들에 대답이 편하셨을테다. 모르는 사람에게 소개할때도 편하다. 이직을 준비하는 과정에서도 그랬다. 이런점이 편했고, 알게 모르게 사람들의 이미지에 적어도 밥벌이는 하겠구나 하는 이미지였으리라. 하는 생각이 든다.  인지도 언론의 기사 제목 뽑는 능력 덕분에, 바깥의 사람들은 삼성 직원이 엄청난 연봉을 받는줄 안다. 그러나 안에서는 어떻게 하면 돈을 더벌까, 더 모을까 이런 이야기들을 한다. 집을 사지 못해 전세를얻고, 회사 앞 수많은 오피스텔에서 다니는 사원들중 본인 소유인 사람은 얼마나 되려나. 임직원중에 부자들...

Largest Rectangle in Histogram with Divide and Conquer, Dynamic Programming, Stack

Image
 이 문제는 stack 으로 푸는게 먼저 있었는데, 답을 보다 보니 divide conquer 가 더 이해가 잘되고 직관적이다. 아래와 같이, 우선 가장 높이가 작은 인덱스 i를 찾는다. 그 다음,  그것을 기준으로 왼쪽과 오른쪽으로 쪼갠다. 그리고 쪼개진 왼쪽 파트에서 나올 수 있는 가장 큰 값, 오른쪽 파트에서 나올 수 있는 가장 큰 값, i 를 포함한 넓이, 이렇게 3가지중 max 값을 구한다. 각각의 왼쪽 파트와 오른쪽 파트는 또 다시 재귀적으로 들어가서 가장 높이가 낮은 인덱스를 각각 구하고.. 또 쪼개고..       public int largestRectangleArea(int[] heights) { return calculateArea(heights, 0, heights.length - 1); } public int calculateArea(int[] heights, int start, int end) { if (start > end) return 0; int minindex = start; for (int i = start; i <= end; i++) if (heights[minindex] > heights[i]) minindex = i; return Math.max( heights[minindex] * (end - start + 1), Math.max( calculateArea(heights, start, minindex - 1), calculateArea(heights, minindex + 1, end) ) ); } 구현상 포인트는 divid...