https://cocodataset.org/#home

 

COCO - Common Objects in Context

 

cocodataset.org

로고

 

COCO 데이터셋은 다양한 컴퓨터비전 타스크의 연구에서 널리 사용되는 벤치마크로, 특정 알고리즘의 성능을 측정할 때 표준으로 활용된다. 최근 이 데이터셋을 이용해 YOLO 알고리즘을 학습시켜 평가해본 결과, 오탐지가 상당히 많다는 사실을 확인하였다. 

 

이런 오탐지 문제가 데이터셋 라벨링 모호함에 기인하는 것이 아닌지 생각하였고 데이터셋의 라벨링 상태를 확인했다.
(물론 데이터 augmentation이나, 모델에 따른 오탐지 가능성도 있지만..)

 

예를 들어, '사람(person)'이라는 객체에 대해 생각해보자.

  • 사람의 기준은 무엇인가?
    • 단순히 손 또는 다리가 보이면 사람으로 판단하는 것인가?
    • 거울에 비친 모습도 사람으로 인식하는가? 
    • 사람인 것 같은데 육안으로 사람으로 식별되지 않아도 사람인가?

라벨링에 대한 엄밀한 기준이 있는가? 그 기준이 일관되게 라벨링 했는가? 에 대해서도 의심을 해볼 수 있다. 

 

다음은 yolo11s 모델의 coco2017 validation 데이터셋에 대한 Evalulation 코드의 결과이다. 

Class                       Images  Instances         P        R    mAP50  mAP50-95
               (metric thread): 100% 1/1 [00:00<00:00,  0.00it/s]
all                           5000      36781     0.615    0.814    0.615     0.452
person (0)                    2693      11004     0.785    0.911    0.785     0.565
bicycle (1)                    149        316     0.583    0.813    0.583     0.347
car (2)                        535       1932     0.651    0.851    0.651     0.440
motorcycle (3)                 159        371     0.726    0.871    0.726     0.490
airplane (4)                    97        143     0.918    0.993    0.918     0.755
bus (5)                        189        285     0.823    0.888    0.823     0.698
train (6)                      157        190     0.913    0.974    0.913     0.744
truck (7)                      250        415     0.498    0.711    0.498     0.351
boat (8)                       121        430     0.508    0.788    0.508     0.291
traffic light (9)              191        637     0.497    0.777    0.497     0.268
fire hydrant (10)               86        101     0.842    0.871    0.842     0.702
stop sign (11)                  69         75     0.715    0.840    0.715     0.648
parking meter (12)              37         60     0.678    0.767    0.678     0.530
bench (13)                     235        413     0.398    0.692    0.398     0.273
bird (14)                      125        440     0.500    0.664    0.500     0.341
cat (15)                       184        202     0.886    0.936    0.886     0.726
dog (16)                       177        218     0.792    0.858    0.792     0.687
horse (17)                     128        273     0.809    0.894    0.809     0.626
sheep (18)                      65        361     0.757    0.895    0.757     0.545
cow (19)                        87        380     0.743    0.842    0.743     0.553
elephant (20)                   89        255     0.876    0.976    0.876     0.693
bear (21)                       49         71     0.921    0.958    0.921     0.763
zebra (22)                      85        268     0.907    0.974    0.907     0.706
giraffe (23)                   101        232     0.915    0.970    0.915     0.741
backpack (24)                  228        371     0.271    0.596    0.271     0.150
umbrella (25)                  174        413     0.646    0.818    0.646     0.451
handbag (26)                   292        540     0.278    0.672    0.278     0.158
tie (27)                       145        254     0.524    0.720    0.524     0.350
suitcase (28)                  105        303     0.664    0.868    0.664     0.464
frisbee (29)                    84        115     0.870    0.939    0.870     0.682
skis (30)                      120        241     0.478    0.784    0.478     0.284
snowboard (31)                  49         69     0.531    0.652    0.531     0.391
sports ball (32)               169        263     0.626    0.719    0.626     0.435
kite (33)                       91        336     0.607    0.812    0.607     0.433
baseball bat (34)               97        146     0.566    0.733    0.566     0.379
baseball glove (35)            100        148     0.628    0.791    0.628     0.381
skateboard (36)                127        179     0.773    0.866    0.773     0.589
surfboard (37)                 149        269     0.610    0.747    0.610     0.394
tennis racket (38)             167        225     0.781    0.893    0.781     0.520
bottle (39)                    379       1025     0.554    0.822    0.554     0.378
wine glass (40)                110        343     0.531    0.703    0.531     0.358
cup (41)                       390        899     0.572    0.802    0.572     0.428
fork (42)                      155        215     0.538    0.781    0.538     0.393
knife (43)                     181        326     0.313    0.623    0.313     0.201
spoon (44)                     153        253     0.289    0.656    0.289     0.195
bowl (45)                      314        626     0.578    0.829    0.578     0.439
banana (46)                    103        379     0.417    0.818    0.417     0.278
apple (47)                      76        239     0.295    0.669    0.295     0.208
sandwich (48)                   98        177     0.519    0.734    0.519     0.394
orange (49)                     85        287     0.396    0.739    0.396     0.305
broccoli (50)                   71        316     0.416    0.899    0.416     0.238
carrot (51)                     81        371     0.364    0.790    0.364     0.235
hot dog (52)                    51        127     0.510    0.669    0.510     0.375
pizza (53)                     153        285     0.736    0.891    0.736     0.568
donut (54)                      62        338     0.587    0.855    0.587     0.465
cake (55)                      124        316     0.587    0.804    0.587     0.405
chair (56)                     580       1791     0.511    0.830    0.511     0.338
couch (57)                     195        261     0.627    0.847    0.627     0.485
potted plant (58)              172        343     0.501    0.843    0.501     0.304
bed (59)                       149        163     0.683    0.859    0.683     0.500
dining table (60)              501        697     0.500    0.834    0.500     0.354
toilet (61)                    149        179     0.843    0.950    0.843     0.693
tv (62)                        207        288     0.810    0.920    0.810     0.620
laptop (63)                    183        231     0.772    0.861    0.772     0.652
mouse (64)                      88        106     0.788    0.896    0.788     0.613
remote (65)                    145        283     0.500    0.820    0.500     0.319
keyboard (66)                  106        153     0.717    0.908    0.717     0.546
cell phone (67)                214        262     0.559    0.779    0.559     0.365
microwave (68)                  54         55     0.735    0.891    0.735     0.590
oven (69)                      115        143     0.622    0.888    0.622     0.448
toaster (70)                     8          9     0.689    0.778    0.689     0.466
sink (71)                      187        225     0.627    0.884    0.627     0.424
refrigerator (72)              101        126     0.807    0.921    0.807     0.671
book (73)                      230       1161     0.233    0.707    0.233     0.126
clock (74)                     204        267     0.721    0.846    0.721     0.524
vase (75)                      137        277     0.553    0.798    0.553     0.406
scissors (76)                   28         36     0.489    0.583    0.489     0.420
teddy bear (77)                 94        191     0.680    0.843    0.680     0.521
hair drier (78)                  9         11     0.156    0.545    0.156     0.068
toothbrush (79)                 34         57     0.377    0.667    0.377     0.271

 

위 결과를 보며 여러 가지 생각이 들었다. 

 

COCO 데이터셋에서 사람 객체를 탐지하는 것이 왜 고양이나 비행기와 같은 객체보다는 상대적으로 어려운지에 대해 고민해봤다. 

 

그 이유를 몇 가지로 정리해보았다.

  • 라벨링의 모호성
  • 부분 가려짐 및 복잡한 배경
  • 다양한 포즈와 변형 

그래서 위의 경우를 cvat이라는 툴로 coco 2017 val 데이터셋에서 찾아보았다.

 

일단 coco 데이터셋의 class가 80개 이므로 person이라는 클래스만 추려서 툴에다가 넣었다. 

 

이걸 사람이라고?

첫 프레임부터 놀라운 것은 창에 비친 것도 사람으로 취급하는 것이었다. 예를 들어서 CCTV Task에 적용했을 때 반사된 모습을 사람으로 처리하면 이건... 말이 안되는 경우이다. 

 

우측의 이미지 역시도 사람의 형체가 분명하게 인지되지 않음에도 person이라는 라벨이 쳐졌음을 확인할 수 있다. 너무 모호하다.... 

 

그리고 또한 Box의 Localization을 어떻게 처리할 것인가도 이슈이다. 

 

어디까지 사람이야?

 

왼쪽의 경우는 사람들이 겹쳐있는 경우이다. 앉아 있으니 앉아있는 영역까지 box를 친다. 문제는 가려짐에 의해 맨 앞의 사람은 머리부분만 bound box가 쳐졌지만 그 우측에 있는 아이는 localization의 기준이 매우 모호하다. 어떤 건 더 넓고 어떤 것은 더 길다..

 

그러면 만약에 다리만 있으면? 손만 보여지면 사람인가? 

 

 

 

위의 결과로 사람임을 인지할 수 있다면 사람으로 라벨링 한다. 손만 보여도, 머리만 보여도, 다리만 보여도 사람이다. localization은 보여지는 부분만 쳐진다. 

 

하지만 사람임을 인지할 수 없음에도 뭔가 사람으로 표기된 경우도 있고 사람으로 인지되는 경우에도 라벨링이 되지 않은 경우도 있다. 

 

왼쪽 이미지에서 점을 어떻게 사람으로 신뢰할 수 있는가? 혹은 우측 이미지에선 crowded data 샘플인데 왜 박스를 치다 말았나? 

 

이러한 사례로 비추어 봤을 때 coco dataset이 computer vision task 데이터셋으로 믿을만한지 의문이다. 아니면 의도적으로 Noise를 넣은 것인가? 

 

실무 적용에서의 문제점과 고민

모호한 라벨링 기준과 부실한 라벨링은 오탐지를 유발할 수 있으며, 오히려 높은 mAP를 취득하는 데 방해요소가 될 수 있다고 생각했다.


실제로, YOLO 모델 평가 결과를 통해 사람 객체에 대한 mAP가 예상보단 낮게 나오는 것을 확인할 수 있었으며, 이는 단순히 알고리즘의 한계가 아니라 데이터셋 자체의 라벨링 문제와도 깊은 관련이 있다.

 

COCO 데이터셋은 방대한 양의 데이터를 통해 일반화(generalization)를 확보할 수 있는 장점이 있지만, 모두가 납득할 만한 라벨링 정책을 가지고 있지는 않을 수 있다. 라벨링 기준은 팀이나 프로젝트마다 달라질 수 있으므로, 실무에 적용하기 위해서는 별도의 데이터셋을 구축하거나 기존 데이터셋을 재검토하여 명확한 기준 하에 재어노테이션을 진행할 필요가 있다.

 

따라서, 단순히 성능 벤치마크용으로 쓰이는 COCO 데이터셋을 맹신하기보다는, 자체적으로 명확한 라벨링 기준 하에 구축된 데이터셋과 함께 보완적으로 활용하는 것이 바람직하다고 생각된다.

 

 

 이전에 개발한 소프트웨어를 문서화하였다. 프로토콜에 대한 정리를 다른 회사와 공유하고 팀내에서 협업을 위해 사용하고자 함이다. 대외적으로 공개 할 수도 있는 문서니이 양식은 좀 신경쓴거같다. 용어 정리, 통신 흐름도, 아키텍처 구성 ..

 

 공유하고자 하는 문서에는 어느 내용이 들어갈지도 되게 중요하다. 우리 회사 소프트웨어 자체적으로 쓰이는 로직도 넣을지 외부 통신하는 로직만 넣을지... 팀 내에서는 어떤방식으로 프로토콜을 만들지 논의한다.

 

음 ... 여러 방식이 있는데 무조건 내주장을 내세우진 않았고 일부러 이런 방식을 생각한다고 떠 보았다.. 조금은 RestFul한 방식으로 설계하고자 미리 생각했는데 팀원분 코드를 보니까 원하는 방향으로 되진 않아서 떠 본 것이기도 했다. 

 

"난 항상 이런식으로 개발했어~" 라는 말에 바로 상대가 원하는 방식으로 바꿨다. 이왕이면 서로가 알고 있는 방식으로 개발하면 좋다고 생각했다. 

 

 문서를 만들 때는 귀찮았는데 만들고 나니까 오히려 업무 소통도 명확해지고 상대가 크로스 체크 해주면서 문서 오탈자도 잡아주고 좋았다. 또한 업무 의존성 분리가 가능했다. 한 쪽이 기능개발 + 문서화 해놓으면 다른쪽에서 이후에 그대로만 따라하니까 업무 진행이 편했다. 

 

 이전에 문서화를 대충 해놓았더니 그 문서가 버려지고 오히려 코드로만 업무 소통이 된 적이 있었는데... 

 

이번에는 뭔가 달랐다. 문서화의 필요성....!

 

 

 

 

 

 

 

 

 

 

'회고록' 카테고리의 다른 글

일관성  (0) 2024.05.25
프로젝트 회고1  (0) 2024.05.12
OS가 발목을 잡는다.  (0) 2023.12.02
10월 ~ 11월 회고  (1) 2023.11.20
회사생활  (1) 2023.10.02

 개발할 때 일관성을 유지하는 것은 매우 중요하다. 

 

 어디서 일관성을 지녀야 하냐면  DB테이블, 컬럼명 작명 스타일, 함수 작명 스타일, 프론트쪽에서 attribute 작명 스타일, 예외처리 방식, 스프링 서버코드 작성 방식 등 이런 모든 것들은 일관성을 지녀야하는 부분들이다. 어떨 때 어떤 방식으로 코드를 짤지 다 패턴화되어 있어야 한다. 현재 진행하는 프로젝트에선 이게 제대로 안되어 있으니 매번 코드가 바뀔 때마다 고치고 고민하느라 고생좀 했다. 애초에 일관성을 가져야 겠다는 생각을 하지 않으니 그때 그때마다 할 수 있는 생각이 다르고 나도 모르게 일관성이 많이 흐트러지게 되었었다.

 

 고민할 시간을 줄여서 일관성을 갖추게 되면 개발 시간도 줄어들고 협업을 하거나 또는 내 코드를 인수인계 받는 사람에게도 좋다. 입사 초에 전임자가 해놓고 간 코드에서 고통을 받았던 적이 있다. 여러 사람의 코드가 섞여 있지만 일관성이라고는 전혀 없는 코드, 따로 노는 느낌의 코드였다. 하지만 그때는 그것을 내 스타일 대로 고치려하지 않았다. 코드의 당위성이나 효율성은 그다지 없던 코드.. 그리고 뭔가 구현하다 말은 코드... 업무를 모르고 구현한 코드 등 ..

 

 최근 그 전임자의 스타일이 묻은 프로젝트에서 나와서 내 프로젝트로 다시 만들었다. 내가 처음부터 다시 만들면 뭔가 다르겠지라고 생각했는데 일관성이라는 것을 갖추는게 좀처럼 쉽지가 않았다. 

 

 

 

 

 

 

 

'회고록' 카테고리의 다른 글

문서화  (0) 2024.08.06
프로젝트 회고1  (0) 2024.05.12
OS가 발목을 잡는다.  (0) 2023.12.02
10월 ~ 11월 회고  (1) 2023.11.20
회사생활  (1) 2023.10.02

 여태까지 많은 일들이 있었다. 올초에 했던 프로젝트는 기능동작의 프로토타입을 만들고 한 사이클의 시연을 하고 

 

 해당 기능이 개발이 가능하다는 것을 보였다. 그 후 부터는 사람들이 같이 붙어서 이것 저것의 기획 또는 디자인이 추가가 되었다. 

 

 다른 사람들과 함께 일하는 순간부터는 문서작업이 많이 추가 되었다. 일정관리는 정말 중요했고 그 과정에서 많은 커뮤니케이션이 필요했다. 서로의 업무 우선순위를 체크하고 언제 그것이 가능한지 조율하면서 목표일정을 맞추는 것이 중요한 과정이었다. 

 

사실상 개발 자체는 빨리 끝나도 이런 문서작업이 정말 많은 시간을 잡아먹었다는 아쉬움이 있었다. 근데 이것도 익숙해지면 엄청 빨라지겠지.. 

 

OS 및 연동

작년에도 많은 고민을 했었지만 개발상에는 여러 문제점과 제약사항들이 많았다... 개발서버가 따로 없었고 개발환경 구축의 어려움 등이 있었으나 Docker 컨테이너 안에서의 빌드환경 구축으로 개발이 가능했고 연동에 있어서의 문제는 굳이 JNA나 JNI로 무거운 알고리즘 로직을 직접 돌리는 방법보단 해당 프레임워크에서 제공하는 연동 로직을 사용하였다. 실제로 자바 서버로직에서 무거운 dll 알고리즘을 돌리는 것은 엄청난 부하를 가져와서 절대 하면 안되는 것이라는 것을 느꼈다. 그래서 dll 알고리즘 단의 로직은 서버와 별도로 분리된 서버로직에서 돌아가게 해야한다. 이를 자바스프링 서버에서 interface를 만들어서 웹소켓 통신을 하고 c++ 서버로직에서 그것을 처리한다.

 

 알고리즘 개발자분이 윈도우 개발자이셨고 만든 알고리즘이 dll로 만든 것이기에  리눅스 서버 운용환경에 맞추기 위해서 so파일로 뽑아지게 변경하였다. 이 과정에서 해당 객체에서 메모리 누수가 나지 않도록 객체 동작 라이프사이클을 자바서버쪽에서 컨트롤 할 수 있게 맞추었다. 타이머, 유저 인터렉션 등의 이벤트가 있어서 스레드를 써야 하는 부분 등이 있었고 만일 해당 객체가 도중에 죽게 되면 스레드 또한 잘못하면 자원회수가 안될 수 있는 이슈도 있었다. 그래서 메인 동작 객체의 소멸자 부분에 스레드 자원회수하는 코드도 넣어서 자바쪽에서 혹시나 통신이 끊기면 해당 객체를 제거해서 밑에 딸려있는 메모리도 해제한다. ( 이 당시 스레드의 개념은 얼핏 알고 있었으나 뭔가의 필요성에 의해서 실무에는 처음 적용해보았고 다음 프로젝트에서 리뷰하던 코드에서 스레드를 사용하는 상황이 나의 상황과 비슷한 점을 확인함... )

 

 아키텍처 구성도 많은 고민이 있었다. 알고리즘 개발자분이 하는 말로는 해당 기능을 처리하기 위해서 반드시 어플리케이션 자체가 분리 되어야 한다는 얘기를 해주셔서 또 다른 기능은 다른 서버에서 돌게하였다. 웹서버 로직에서 A서버(C++), B서버(Python)를 사용하는 MSA 구성인데 이 작은 기능을 구현하기 위해서 이렇게까지 하다니 현타가 오기도 했다.... 업무의 범위가 매우 넓기도 하였다. 언어만해도 java, javascript, c++, python에 프레임워크도 이것저것... 

 

 처음 계획했던 것은 고도화 느낌의 작업도 할 생각이었다. 그런데 도중에 다른 프로젝트로 붙게 되어서 고도화쪽은 나중에 할것같다.. 그 때 되면 엄청 힘들어지겠지? 

'회고록' 카테고리의 다른 글

문서화  (0) 2024.08.06
일관성  (0) 2024.05.25
OS가 발목을 잡는다.  (0) 2023.12.02
10월 ~ 11월 회고  (1) 2023.11.20
회사생활  (1) 2023.10.02

java라는 언어는 jvm 기반으로 동작하기 때문에 OS가 다르더라도 돌아간다. 하지만 java라는 언어만 사용해서 개발하면 좋겠지만 현실은 그렇지 않다. 연산량 많은 알고리즘이나 자바가 아닌 특정 언어에 특화되어서 어떤 기능을 제공하는 경우 다른 언어를 자바에서 써야 한다. 예를 들면 영상처리 알고리즘이나 누군가 구현한 암호화 알고리즘을 자바에서 쓰는 경우가 많다. 그런 경우에는 자바에서 다른 언어의 동적 라이브러리를 load해서 사용할 수가 있는데 이 경우에 자바 언어 자체의 단점을 보완하게 된다. 

 

가장 큰 문제는 OS를 고려하여 빌드된 파일을 따로 가져야 한다는 것이다. 즉 빌드된 동적 라이브러리 형태가 OS마다 다르기에 배포 환경에 따라 라이브러리를 맞춰서 빌드해야 한다는 것이다. 요즘은 이런 번거로움에 대한 해결책이 나와서 윈도우도 wsl을 지원하지만 그것이 없던 시절에는 aws ec2에 리눅스 환경을 따로 마련하거나 듀얼 부팅으로 개발을 하던 시절이 있었을 것이다. 물론 wsl도 온전한 리눅스 환경을 그대로 제공할지는 의문이다. 

 

단순히 윈도우 개발자들 기준에서는 별도의 리눅스용 빌드된 파일이 필요가 없겠지만 웹개발자들 기준에서는 대부분 리눅스에서 배포하기 때문에 리눅스용 빌드된 파일이 필요하고 빌드 방법을 알아야 한다. (아니면 그것을 아는 개발자가 따로 있거나..) cmake를 사용해서 딥러닝이나 opencv 소스 빌드를 하는것이 블로그에서 보면 명령어 몇 줄 입력하는 걸로 보여서 간단해 보이지만 사실 그거 하느라 하루 꼬박 날리는 경우도 있으니 돌아버릴 노릇이다.

 

그렇지만 배워두면 좋은 기술인데 뭔가 현재로선 압박감이 있다. docker라는 기술은 이에 대해서 좋은 제안을 하지만 이러한 것들을 잘 다루는 사람들만 보던 시니어들은 왜 이걸 바로 못하는지에 대해 눈치를 준다는 느낌을 받는다. 환경셋팅하는데만 왠종일 걸릴 것으로 예상되는데 왜 아직도 개발의 윤곽이 안나오는지는 많은 고민이 있는 것이다.. 

 

'회고록' 카테고리의 다른 글

일관성  (0) 2024.05.25
프로젝트 회고1  (0) 2024.05.12
10월 ~ 11월 회고  (1) 2023.11.20
회사생활  (1) 2023.10.02
면접후기2  (0) 2023.07.29

 C++ 구현된 어떠한 알고리즘을 사용하는 경우에 자바에서 C++ dll을 참조하는 인터페이스를 정의해서 동작시킬 수 있다. 이것은 다른 언어에서 돌리는 경우 최적화 방법이라 한다. C#에서도 c++ dll을 동작시키는 방법이 있었듯이 Java에서도 있었다.

 

 JNI(Java Native Interface)를 사용하면 그것이 가능해진다. 본 포스트는 윈도우 환경, Java17로 진행하며 간단한 방법에 대해서 다룰것이다. 스프링 부트리눅스 환경에서 동작시키는 것은 추후에 해봐야하는 일이다. (so파일 생성, gradle , boot 설정 고려)

 

 먼저 C++의 코드를 실행시킬 수 있는 인터페이스가 필요하다. header 파일 형태로 작성되며 그것이 만들어지면 cpp 파일에 구현부 부분을 추가로 작성해주면 된다. 이를 위해서는 자바에서 먼저 어떠한 방식으로 사용할지 정의해야 한다. 

 

1. Java Native Interface 코드 작성

 다음과 같이 작성하는데 Path 환경 변수에 Java 17 jdk 패스를 추가된 상태이다. 아래의 코드는 내가 자바에서 "C++ 코드를 쓸건데 이런 파라미터를 사용할거야~" 라고 명세한 인터페이스 코드라고 보면 된다. 

 

2. C++ dll 생성을 위한 header 파일 생성 

위의 인터페이스 코드는 C++ dll과 연동이 될수 있도록 c++ 형태의 인터페이스 헤더코드 또한 작성되어야 한다. 다르게 말하자면 "내가 c++ dll을 만드는데 이걸 자바에서 쓴다네? 그러면 어떤 형태로 자바에서 쓴대?" 라고 명세한 c++의 header이다. 위의 코드형태를 c++ header 형식으로 자동으로 뽑아낼 수 있다. javac.exe로 가능하다. 

 

java 11버전까지는 javah.exe 라는 파일이 있었으나 java12 버전부터는 사라지고 javac의 -h 옵션으로 가능하게 된다. 해당 코드를 작성한 위치로 가서 javac -h . Main.java 이렇게 입력하면 된다. 

실행결과로 com_test_jni_Main.h라는 파일이 생성된다. 잘보면 자바 패키지 경로와 클래스까지 맞춰져서 생성이 된다. (이 패키지 경로랑 클래스 못맞추면 동작 안되는 경우가 있어요.) 

 

생성된 파일은 다음과 같다. 

 

3. visual studio에서 dll 파일 생성

이제 이 파일을 들고 visual studio에서 작업을 한다. 빈 프로젝트 하나를 만들고 프로젝트 속성에 동적 라이브러리 설정을 한다. 

다음엔 포함 디렉터리 설정에 jdk의 include 위치를 추가한다. 

 

위에서 만든  com_test_jni_Main.h 파일을 visual studio 프로젝트 파일로 넣어주고 해당 파일을 include하여 함수 내부를 정의한다. 

빌드를 해주면 dll 파일이 생성된다. 프로젝트는 반드시 64bit로 빌드해준다. 

 

이제 아까 그 자바코드를 eclipse에서 실행시키면 결과는 다음과 같다. 이 때 주의할 점은 CppJNIProject.dll을 load 해줘야하는데 해당 폴더의 위치를 환경변수에 추가해줘도 되고 파일이 잡히는 위치에다가 놓아서 System.loadLibrary 함수가 참조할 수 있으면 된다. 

 

 

참고

https://velog.io/@oksk4753/JAVA-C-JNI%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%97%B0%EB%8F%99CentOS7-x8664

https://m.blog.naver.com/senshig/221756026727

https://m.blog.naver.com/sssang97/221737572369

'잡지식' 카테고리의 다른 글

IT 직군 관련 포지션, 용어 정리  (0) 2023.07.25
코딩테스트  (0) 2023.07.24

회고

회사에 들어온지는 좀 됬는데 입사하고 나서 제일 중요했던 일정 하나가 저번달에 마무리 되었다.

 

정부과제 평가였는데 평가 하루 전날까지 애매한 기능을 손 보느라 재배포 하는 과정을 수없이 반복했다. (Jenkins를  써보고 싶었으나 그 때는 t2.micro 계정이라 Jenkins 쓸 여건이 나진 않았다. 근데 지금 클라우드 리소스는 넉넉함) 해당 업무는 처음 써보는 라이브러리와 처음 해보는 업무 도메인이다.

 

Back 단에는 그렇게 많은 코드가 필요하진 않았고 Front단 기능 동작 부분에서 많은 시간을 할애하였다. 클라이언트 단에서 UI 디자인 쪽은 딱히 내가 관여한 것은 없으나 화면단 인터페이스 정의와 기능 동작이 굉장히 중요했다. 

 

프로젝트 자체는 전임자에게 받아서 진행하는 상태이고 같이 하는 분도 계시고 기획도 이미 정해져 있어서 그렇게 업무 강도는 빡쌔진 않았다. 빡새게 하려고 작정했으면 더 많은 기능을 넣을 순 있었겠지만 굳이 그렇게 하지 않아도 됬다.

 

기능을 구현하는 것도 고통이지만 어떻게 구현할지 계획하고 무슨 라이브러리나 어떤 기술을 쓸 것인지 상급자와 협의하는 것도 중요했다. 구현없이 뜬구름 잡는 계획으로만 구성된 ppt 보다는 기능 구현을 해보고 어느정도 윤곽을 보여주는 것을 좋아했다.

 

단순히 기능만 돌아가는 것만 중요한 것이 아니었다. 이 기능을 논리적으로 어떻게 동작시킬지 정의하는 것도 굉장히 골치아픈 문제였다. 회사에 기획자 분이 계시긴 하는데 그 당시에는 없었다. 

 

그래서 테스트 시나리오 라는 것을 만들었다. 해당 업무 도메인에서 이 소프트웨어 사용시에 어떠한 방식으로 사용할 것인가를 다룬 UseCase 문서 느낌인데 나름 기능에 대한 정리가 잘되고 그걸 보면서 내 기능이나 UI도 수정하고 또한 남들에게 제시할만한 좋은 문서가 된다. 

 

평가는 잘끝났다. 좋은 평을 받긴 했는데 많이 그래도 부족하다고는 생각한다. 

 

새로 구상하는 것을 위해 이제 또 다른 일정을 시작했다. 가능성을 일단 계속 구상하고 길을 만들어 가야 하는데 업무 영역이 매우 넓어서 쉽게 트라이가 되진 않는다. 또한 기술적으로 "이제 왜 안되? 그냥 하면 되나?"하고 로직을 만들려고 하면 또 다른게 걸리는게 많다. 그래서 요즘 대부분의 시간을 공부하면서 어떻게 하면 되게 할지의 방향을 잡는데 많은 시간을 보낸다. 

 

잡생각들

 

기록

Notion에다가 다시 기록을 시작했다. 원래 강의 들었던 것을 word에 기록했는데 365 기한이 끝나버려서 Notion에다가 땜빵으로 쓰고 있었는데 계속 쓰다보니 워드보다 좋았다.. 특히 Backup 기능이 있어서 삭제한 파일 복구가 가능한게 인상 깊었다. 지금은 물론 회사 ms365 계정을 받았지만 ppt 만드는거 아니라면 거의 Notion에서 주로 공부했던 것을 기록한다. 

 

InteliJ

무겁고 불편한 sts에서 벗어나서 InteliJ ultimate 버전을 사용하기 시작했다. 다양한 플러그 인과 툴 자체도 덜 무거워서 갑자기 sts처럼 팅기는 일이 없어졌다. 작업하는 것에 있어서 많이 쾌적해졌다. 최대한 다양한 기능을 써서 기록해서 정리할 예정이다.

 

S/W 아키텍처

최근 프로젝트 하나를 새로 만들 일이 생겨서 이전에 패키지 구조를 고민하다가 스프링 코드에 관련해서 아키텍처에 대한 유튜브 강의를 많이 보게 되었다. 일반적으로 우리가 많이 사용하는 레이어 아키택처와 도메인 별로 나누는 도메인 아키텍처, 그리고 요즘 유행하는 클린 아키텍처 등에 대해서 공부하였다. 사실 이걸 공부하게 된 이유도 어떤 시니어 개발자분이 프로젝트를 클린 아키텍처로 새로 만드는 것을 유튜브로 보고 난 후 였는데 공부를 하고나니 이것을 굳이 쓸 이유가 없다는 것으로 결론이 내려졌다. 내 프로젝트와는 맞지 않았다.

 

TDD/Rest Docs

남들과 협업을 한다거나 문서로 기능 명세서를 남겨야 하는 상황이 많다. 기존에 몇몇 프로젝트는 그러한 명세를 엑셀에다가 일일히 수작업으로 했었다. 하지만 이러한 수작업으로 기록하는 것도 만약에 코드가 변경되면 그것에 맞추어 문서도 수작업으로 따라서 변경해야하는 단점이 있다. 그러한 상황을 위해 실무에서는 Rest Docs나 Swagger를 많이 쓴다고 한다. API 문서 자동화 라이브러리인데 API 명세를 코드가 자동으로 만들어주는 것으로 웹페이지가 자동으로 만들어지고 그것을 보면서 협업을 한다는 그림이었다. Swagger와 Rest docs 이 두개가 많이 알려졌지만 동작 난이도는 Swagger가 낮으나 배포코드가 지저분해진다는 단점으로 Rest docs를 많이 쓴다고 한다. Rest docs의 단점이 있다면 테스트 코드 강제하는 형태로 되어 있어 나름 귀찮을 수도 있다는 것이다. 하지만 이 기회에 앞으로 TDD로 코드 짜는 습관을 익혀두면 좋을 수 있다. 그 전까지는 왜 TDD로 짜야 하는지에 대한 뚜렷한 명분이 없었으나 Rest Docs 를 위해서라면 나름 훌륭한 명분이 될 것이다. 

 

Docker/Kubernetes/Kafka/Redis 

나중가서는 꼭 알아야 하는 부분이다. 개발한 프로젝트에 dockerfile을 작성해서 환경울 구성해야 하고 docker Compose로 db와 다른 어플리케이션 단을 연결해야 한다. 쿠버네티스 쪽은 사내 프로젝트에 관련된 것을 하고 있어서 어떻게 돌리는지에 관한 것은 꼭 알아야 한다. Kafka도 주변에서 알아야 한다고 말은 해준다. 요즘 github에서 남들 프로젝트 하는거보면 죄다 Redis쓰는데 Kafka 비슷한거라고 검색하면 나오긴 하는데 왜 쓰는지는 나도 좀 알고 싶다. 

 

강의를 열심히 듣자

8, 9, 10 월 달에는 강의를 많이 못들었는데 최근에는 과거에 등록해놓았던 인프런 강의를 하나씩 격파하려 하고 있다. 정말 배울 게 많다. 클라우드, 프론트, 백엔드, 인프라, CI/CD 등 .. 

'회고록' 카테고리의 다른 글

프로젝트 회고1  (0) 2024.05.12
OS가 발목을 잡는다.  (0) 2023.12.02
회사생활  (1) 2023.10.02
면접후기2  (0) 2023.07.29
강의부자  (0) 2023.07.24

 어느덧 회사에 들어온지 두 달 가까이 되었다. 전혀 생각지도 못했던 회사로부터 입사 제의를 받고 1차 면접에서 2차 면접까지 속전속결로 진행되어 바로 그 다음주에 입사하게 된다. 입사 후에는 그동안 블로그를 하지 않았다. 약간 게을러진 것도 있었고 내가 생각했던 방향과 개발자로서 가져야할 마인드 셋이 달랐었기 때문이다. 

 

 입사 초반에 사무실에 들어오자마자 새 PC 하나를 받았다. 환경 셋팅하는거 좀 오래 걸리고 번거로운 일이라는 것을 그 때 또 다시 깨닫는다. 이클립스 sts는 뭐이리 불편한건지, 자바는 무슨 버전을 설치해야 하는지 DB는 뭘 설치해야 하는지 등의 이슈가 있고 워드나 오피스 등을 설치하는 것도 나름 시간이 걸렸으니 말이다. 받은 pc가 속도도 너무 느려서 이것저것 문제를 검토해보니 HDD에 OS를 설치해놔서 그랬다. 그래서 SSD에 OS를 재설치 하는 과정도 거치니까 하루가 갑자기 끝나 있었다..

 

 우리회사는 딱히 맞사수가 있는 그런 회사는 아니다. 각자 자기할 일 잘 맡아서 하는 방향으로 업무는 진행된다. 동료 한분이 많은 조언을 해주었다. 내가 신입이라고 하니까 개발자가 가져야할 마인드셋부터 시작해서 본인이 어떠한 회사들을 거쳐왔는지 등 이야기 해주시고 먼저 말씀해주시진 않았지만 내가 귀찮게 캐물어서 어떤 코딩 스타일을 선호하는지, 어떤식으로 코드를 짜야 하는지에 대해서도 대답을 들었다. 

 

 사수가 없다보니 초반에 나름 방황할 수가 있는데 신입 때는 뭘하더라도 크게 터치를 받지 않는다는 것을 이용하여 새로운 디비 공부나 신버전의 스프링 배치, 시큐리티 등을 공부하면서 신입한테 주는 숙제를 했다. 다행히도 업무 자체가 내가 기존의 알던 것들과 크게 다르지 않아서 새롭게 공부할 것이 많지는 않다. 그것도 오래하는 것을 원치 않아하는 분위기여서 일주일 정도하고 pass 하였다. 그 과정에서 대표님의 많은 가르침이 있었다. <- 생략 ->  그러고 실무에 들어가게 되었다....

 

 그러면서 회사생활을 하다보니 문득 어떤 개발자가 좋은 인재인가라는 생각도 하게 된다. 지금은 아래와 같은 생각을 하고 있다. 

 

 회사에서는 어느 정도 단순히 어떤 지식에만 매달려서 공부하고 카피하는 것이 아니라 본인의 생각으로 구성하고 방향성을 의논할 개발자를 원한다. 세상이 많이 좋아져서 요즘 개발할 때 chatgpt를 많이 쓰게 된다. 단지 "코드를 구현해줘"의 차원이 아니라 이 코드가 좋은 코드인지, 어떤 구성으로 코드를 짰는지, 그리고 라이브러리의 사용법을 익히는 차원에서도 많이 쓰게 된다. 과거보다 학습속도와 개발속도가 매우 빨라진 셈이다. 물론 백그라운드도 많이 아는 것을 좋지만 단지 그것만이 주가 되면 안되고 그것을 이용해 어떻게 활용하고 문제를 다루고 그림을 그릴지가 주가 되어야 한다. 

 

그래서 예를 들자면 단지 "나 리액트, 뷰, 스프링 잘해요." 라고 어필해서 세부 사용법에 대해 논하는 사람들보단 사내 프로젝트에서 어떤 문제를 접하고 그 과정에서 어떠한 생각을 가지면서 그 문제를 해결했는지에 대한 주관이 있는 개발자가 빛을 볼 수 있다는 것이다. 

 

 개발자라는 직업이 아이러니 한게 주말에도 공부를 하지 않으면 현재 업무에 매몰되어서 트랜드에 뒤쳐지는 일이 쉽게 일어난다. 공부라는 것이 개발자에겐 숙명이다. 하지만 취준 때 처럼 목적성 없이 단순히 해당 도메인을 익히려는 공부보단 이제는 응용의 측면에서 학습을 해야 한다고 생각한다. 

 

'회고록' 카테고리의 다른 글

OS가 발목을 잡는다.  (0) 2023.12.02
10월 ~ 11월 회고  (1) 2023.11.20
면접후기2  (0) 2023.07.29
강의부자  (0) 2023.07.24
마무리  (0) 2023.07.14

+ Recent posts