스타트업 병특 개발자의 삶 (3)

개발자: 67·2023년 5월 31일
19

Cimple Life

목록 보기
3/3
post-thumbnail

"3... 2... 1... Going Nuclear!"

위 문구는 우리 회사의 일부 제품들이 겪던 네트워크 연결성 문제를 해결하는데 톡톡한 역할을 한 펌웨어 기능인 "Nuclear Reboot"에서 출력되는 로그이다. 핵무기 폭격을 받은 땅에서는 모든 것이 다시 새로 시작되어야 하듯, 문제를 해결하는 가장 원시적이면서도 효과적인 방법인 "재부팅"을 적용한다는 것을 은유한 작명이다. 이 재치있는 개발자식 유머는 내가 훈련소를 다녀온 뒤 입사한 주니어 펌웨어 개발자 피터(가명)의 작품이다.

이것은 공교롭게도 앞으로 벌어지는 일에 대한 복선이 된다.

☄️폭격

2020년 3월 말.

내가 병특으로 회사를 들어오고, 일련의 사건을 거쳐 펌웨어 개발자로 일한지도 이제 1년 반이 넘어가고 있었다. 이제 펌웨어 팀은 주니어 개발자인 나와 피터, 그리고 시니어 개발자 한 명 팀쿡(가명)이 이끌어가고 있었다.

팀쿡은 어웨어가 창업한 지 3년째인 2016년에 조인해서, 현 서술 시점인 2020년까지 4년간 출시한 사실상 모든 제품 개발의 역사를 함께한 멤버였다. 즉, 말하자면 그는 펌웨어 팀의 역사책이었다.

근데 애석하게 팀쿡도 곧 짤렸다 😇

그의 마지막 한마디

사실 팀쿡에 대해 전편에서 분량상 특이한 설계를 했다는 것 외에는 자세히 다루지 못했지만, 팀쿡은 사실 회사에 있어 필요악 같은 존재였다. 뭐 예를 들면 회사 근처에서 페미니즘 시위가 있었는데, 개발하라고 사준 전문 소음 측정 장비를 들고나가서 보란 듯이 행위 예술을 하다가 한 여성인권 운동가에게 포착되어 트위터에 박제됐다고 한다. 이런 것 말고도 회사 내에서도 그의 악동같은 면모로 이런 저런 업보를 많이 쌓아와서 그에 대해 부정적 시선을 가진 윗사람들이 조금 있었다는 것 같다. 이런 점들이 전편에서 언급된 '그가 공식적인 팀 매니저로 인정받지 못한 이유' 중 하나이다.

이런 정황을 어느정도 알고있었기에, 회사가 결국 그의 해고를 결정한 까닭이 이해가 안가는 것도 아니었다. 근데 나한테는 "that sucks bruh!"같은 동년배들 다 쓰는 표현이나 "avocado is testicle fruit"이라는 유익한 사실을 알려줄 정도로 잘해줬기 때문에 딱히 악감정은 없었다.

"그럼 과카몰리는 🔥🥚소스인가?"

"헐, 팀쿡 없는데 우리 어떡해!"

역시나 회사는 다시 한번 혼란에 빠졌다. 이제 펌웨어 팀엔 주니어 개발자 둘 뿐인데, 회사에 앞으로 해야할 일은 산더미였으니까. 또 "그를 해고한 이 회사가 미웠다ㅠㅠ"라고 말할 법도 하지만, 이미 몇차례 구조조정으로 좋은 동료 분들을 떠나보내는 일을 경험한 나는 이제 더는 이런 사건에 감정이 오르락 내리락 하지 않았다. 그냥 '뭐, 스타트업이 이런갑다~'하고 일하면 되는 일이라고 생각했다. 무엇보다 난 병역 문제를 해결하려 이곳에 왔으니까. 그냥 내가 안짤리면 그만, 2년 채우면 도비 이즈 프리였다. 시니어 펌웨어 개발자가 절멸된게 솔직히 약간은 불안하긴 했지만, 내겐 매니저 주혁님이 있으니까 이정도 어려움은 헤쳐나갈 수 있을 거라는 믿음이 있었다.

🔌재시작

2020년 4월 1일.

거짓말처럼 펌웨어 팀은 이제 다시 백지장부터 시작해야 했다. 사실 이건 좀 과장이고, 적어도 나와 피터 두 주니어 개발자들이 겪게되는 일은 이전과 사뭇 달랐다.

다음 날 아침, 이젠 펌웨어 팀의 매니저인 주혁님이 내게 다가와 앞으로의 계획을 이야기 해주시기 시작했다.

"이제부터 회사의 가장 큰 우선순위는 BACnet이에요."

그가 말한 BACnet은 "Building Automation and Control" Network의 약자로, 백넷이라 읽으며, 미국 건물 자동화 시스템의 세계관 최강자 프로토콜이라고 한다. 건물 환기 및 냉난방, 조명 제어, 각종 센싱 등을 처리하기 위한 표준 오브젝트들이 정의되어있고, 이를 중앙에서 연동해주는 워크스테이션을 두는 방식으로 구성된다.

대충 이런 거라고 함!

IoT 공기질 모니터를 만드는 우리 회사는 미국 엔터프라이즈 시장에 본격적으로 진입하기 위해 이 기능을 넣는 것이 필수적이라고 판단했고, 팀쿡이 나가기 전 몇 달 동안 ASHRAE로부터 표준 문서를 구매하고, 공식 백넷 벤더로 등록하고, 이 분야 전문 인도인 외주 개발자를 섭외하는 등의 사전 작업을 해놓았다. 그러니까, 이제 나의 역할은 인도인 외주 개발자가 만든 백넷 PoC 코드를 기반으로 MVP를 만드는 것이라고 한다.

PoC?? MVP??

주니어 개발자였던 내게 그런 용어가 생소했을 뿐더러, 듣기만 해도 뭔가 이 거대해보이는 프로토콜 기능을 개발하라니. 두려움부터 앞서 '응애 나 애기 개발자 그런거 못함!'이라는 생각이 머리 속에 가득했지만, 뭐 어찌저찌 하다보면 주혁님이 또 도와주시겠지라는 마음으로 이 작업에 임해보기로 했다. 😏

시작은 PoC 개발을 돕는 것이었다. 인도인 외주 개발자를 위한 타겟 하드웨어 및 JTAG 디버거를 준비하고 개발환경 셋업을 위한 가이드 등을 작성했다. 임베디드 개발이 으레 그렇듯, 모든게 마법처럼 순조롭게 이루어지진 않았다. 보드를 켜고 펌웨어를 굽는 것부터 시작해서, 디버깅이 되게 만드는데도 시간이 조금 걸렸다. 인도가 미국보다는 한국과 시차가 덜 났기 때문에, 미국에서 근무하는 피터보다 한국의 내가 인도인 외주개발자를 대응해야하는 일이 많았다. 그와 여러차례 슬랙 메시지를 주고 받고, 때론 음성 통화도 해야했다. 영화 세얼간이에서나 듣던 인도 억양을 직접 이해하며 일해야하는 것도 꽤나 신선한 경험이었다.

...

2020년 5월 초.

외주 개발자로부터 드디어 첫 번째 작업물인 MS/TP 드라이버 코드를 전달받았다. 여기서 MS/TP는 BACnet이 지원하는 데이터 링크 계층 옵션 중 하나인데, 일반적으로 쓰는 인터넷 프로토콜로 치면 대략 이더넷의 포지션이다. MS/TP 하위의 물리 계층은 RS-485인데, 전선들을 아래 사진과 같이 데이지 체인 방식으로 연결하여 기기 간의 통신을 달성한다.

그러니까 미국의 흔한 빌딩은 벽 속에 이런 전선들이 가득한가 보다.

외주 개발자가 안내해준 대로 받은 펌웨어를 오픈소스 백넷 탐색기 프로그램과 Wireshark 등으로 테스트해 보았고, 역시 백넷 전문가 닉값대로 잘 동작 했다. 아직 그가 PoC를 완성하려면 MS/TP 드라이버 외에도 네트워크와 응용 계층 구현이 추가되어야 했지만, 어차피 자사 MVP를 만들려면 이게 어떻게 동작하는지 이해해야 했기에 미리부터 코드 분석을 시작했다.

그런데 웬걸, 돈과 가독성의 행방불명이다. 드라이버의 핵심 로직은 수많은 중첩 if-else문으로 1000줄가량의 함수 하나에 다 담겨있었고, 무엇보다 드라이버 구현에서 흔히 볼 수 있는 그 구조체를 단 하나도 찾아볼 수 없었다. 그럼 패킷 헤더 같은걸 어떻게 구현했냐고? 전부 배열이었다.

// Format1: <1 uint8_t Command> + <1 uint8_t Baud-Rate> + <1 uint8_t This-Station-ID> + <1 uint8_t Max-Master> +
//          <1 uint8_t Max-Info-Frames> + <Not-Used> + <Not-Used> + <Not-Used> +
//          <8 bytes MS/TP-Header place-holder> + <NPDU-Data (max 501 bytes) place-holder> + <2 bytes Data-CRC place-holder>.
// Format2: <Send-NPDU-Request> + <Use-My-Src-MAC-Addr> + <Src-MAC-Addr> + <Not-Used> + <Not-Used> +
//          <1 uint8_t Request-ExpectingReply> + <1 uint8_t Destination-MAC-Address> + <2 uint8_t Data-Length (LSB first)> +
//          <8 bytes MS/TP-Header place-holder> + <NPDU-Data (max 501 bytes)> + <2 bytes Data-CRC>.
static uint8_t bacnetNwkAppStackReqMessage[520];

더 심한 건, 배열의 인덱스를 매크로나 enum 상수로 선언이라도 해놨다면 모를까, 위처럼 주석으로 패킷 구조를 설명해놓고 실제로 배열 원소를 사용할 땐 그냥 숫자로 인덱싱했다.

허허 이걸 어떻게 써...ㅋㅋ

이 인도인 개발자는 진짜 그 숫자들을 다 기억하면서 코드를 짜는 🐕천재거나, 아니면 학부 시절에 구조체와 사이가 좀 안 좋으셨다거나 한 것 같다. 아무튼 확실한 건, 우리의 MVP에서 이 코드를 그대로 재활용하는 것은 우리 후세를 위해 도저히 못 할 짓이었다. 뭔가 대책이 필요했다.

백엔드 개발자인 주혁님은 이 사태를 파악하시고는, 백넷 표준 문서를 참고하여 Go 언어로 MS/TP 상태머신 코드를 빠르게 작성해서 내게 예시로 보여주셨다. 그의 코드는 바이트 하나가 들어올 때마다 상태가 전환되면서 올바른 프레임이 수신되었는지를 체크해주는 로직이 읽기 쉽고 우아하게 잘 짜여져 있었다. 주혁님의 의도는 내가 이 Go 코드를 참고해서 C 언어로 외주 개발자 코드를 리팩터하는 것이었다. 이 기능은 명확한 입력(바이트)과 출력(상태값)이 있는 주제이기 때문에 주혁님이 최근에 내게 알려주신 TDD를 적용하기 너무나 좋은 예시였다. 나는 바로 리팩터 작업에 착수했다.

MS/TP 상태머신은 대충 이렇게 생겼다 😵‍💫출처: https://koreascience.kr/article/JAKO200714539097148.pdf

이틀 정도를 내리 쏟아 상태머신의 뼈대 구조를 단위 테스트로 검증하며 완성하고 그 안에 CRC 체크와 같은 실질적인 기능을 외주 개발자의 코드를 참고해 채워나가던 도중, 문득 의문이 들었다.

잠깐, 이게 진짜 내가 해야하는 일이 맞나?

하다 보니 왠지, 뭔가 이런 구조화조차 내가 처음 하는 일이라는 건 말이 되지 않는 것 같았다. 백넷이 무려 1987년부터 개발된 프로토콜이고, 이미 시장에 수많은 백넷 제품들이 있는데, 그 회사들이 전부 프로토콜 문서를 분석하며 바닥부터 코드를 짜진 않았을 테니까. 표준 문서를 대충 훑어보니 이 상태머신 말고도 구현해야 할게 더 있는데, 나 같은 주니어 개발자가 이런 식으로 코드를 더 짠다 한들 과연 이것의 안정성은 누가 보장할까 싶었다. 이런 귀차니즘이 발동해서 코드 짜기를 멈추고 구글링을 시작했고, 얼마 되지 않아 완전한 오픈소스 백넷 스택이 있음을 뒤늦게 깨달았다.

백넷 위원회 소속의 Steve Karg 씨가 15여년에 걸쳐 정성스럽게 작성한 백넷 스택은, 임베디드 시스템에서 빠르게 백넷 응용 프로그램을 작성할 수 있도록 만들어진 로열티 프리, 소스코드 공개 의무가 없는 천사 같은 라이브러리였다. 나는 라이브러리 코드를 분석하기 시작했고, 내가 리팩터를 하며 고민했던 MS/TP 드라이버의 CRC 체크 기능은 물론, 최종 MVP에 포함해야 하는 네트워크와 응용 계층 구현이 전부 구현되어 있음을 확인했다. 우리가 해야 하는 일은 오로지 자사의 비즈니스 로직에 맞게 오브젝트를 정의하는 API를 적절히 호출하는 것과, 당연히도 하드웨어 플랫폼마다 달라지는 물리 계층 구현을 만들고 MS/TP 드라이버에 붙이는 것뿐이었다. 이 발견을 주혁님에게 알렸고, 그 즉시 우리는 전략을 바꾸었다. 외주 개발자가 최종 PoC를 전달하기 전에 이 백넷 스택을 활용하여 우리 나름의 구현을 시작하기로.

...
2020년 6월 초.

회사 내부적으로 정한 데드라인이 며칠 앞으로 다가왔다. 팀원들은 모두 내가 제시한 해결책을 믿고 백넷 스택을 사용하여 MVP 펌웨어를 거의 완성한 시점이었다. 모든 피쳐 브랜치를 임시로 머지해서 테스트를 해보았는데, 아뿔싸. MS/TP 패킷을 주고받다가 특정 시점에 시스템 충돌이 난다.

망했다.

머리 속이 복잡해지고 초조해졌다. 며칠 안 남았는데 어떻게 고치지? 분명 꼼꼼히 라이브러리를 분석했다고 생각했다. 라이브러리의 의도대로 코드만 작성하면 아무 문제 없을 줄 알았지. 막판에 이런 버그가 나올 줄 알았더라면 진작에 중간중간 테스트하며 개발했었어야 했는데. 이런 마음으로 디버깅을 시작하니, 잘 될 리가 없다. 내가 예측한 원인 중 단 하나도 맞는 것이 없었다. 밤 10시가 넘는 시간까지 야근을 하며 분석해보았지만, 결국 별다른 성과를 얻지 못했다. 반면, 외주 개발자가 전달한 최종 PoC 코드는 같은 상황에서 매우 잘 동작하는 것 하나는 확실했다.

다음 날 아침, 주혁님께 조심스럽게 이 사실을 전달했고 약간 패닉에 빠진 상태에서 '아무래도 시간 제약상 MVP에 외주 개발자의 코드를 쓰는 것이 좋을 것 같다'라는 의견을 드렸다. 그는 그날, 그가 해야 하는 모든 백엔드 업무를 제쳐두고 나와 함께 펌웨어를 디버깅했다. JTAG, Wireshark 등 우리가 아는 방법을 모두 동원해 침착하게 패킷과 코드 한줄 한줄 분석해 나간 결과, 문제의 근본 원인이 내가 임의로 블로킹 I/O 방식으로 바꿔 구현한 읽기 함수에 있다는 것을 알아낼 수 있었다. 백넷 스택의 예제 코드들은 읽기 함수에 논블록 방식으로 적절한 타임아웃을 함께 제공하고 있었지만, 내 의심병이 또 도져서 "굳이 이걸 넣어서 코드를 복잡하게 해야해?"라 생각하며 과감히 타임아웃 없이 입력이 들어오는 것을 영원히 기다리도록 만들었더랬다. 하지만, 백넷 스택은 유저가 정의한 코드에서 읽기를 특정 시간만큼만 시도하고 리턴해야만 다음 처리가 정상적으로 이루어지도록 구현되어 있었던 것이었다.

그날 나는 논블록과 비동기 처리의 중요성에 대해 절실히 깨닫게 되었다. 코드의 단순함을 위해서 특정 구현 방식만을 편식하다 보면, 언젠가는 이렇게 해결하기 까다로운 문제에 봉착하게 될지 모른다. 적어도 혹시 무언가를 바꾸었다면, 잘 기억해 두었다가 꼼꼼히 검증해야겠다고 다짐했다. 그리고 라이브러리 코드는 보통 그렇게 짜여진 이유가 있을지 모르니 되도록이면 임의로 바꾸지 않는 것도 잠재적인 버그를 피하는 방법이다.

개발도 때로는 다른 작업을 하며 기분 전환을 할 필요가 있다 😉출처: https://wildeveloperetrain.tistory.com/104

아무튼, 이렇게 주혁님 덕분에 다시 한번 내 스타트업 라이프 최대의 위기를 잘 넘길 수 있었다 😮‍💨

♻️애자일하게

이런저런 노력 끝에, 우리는 어웨어의 첫 백넷 MVP를 성공적으로 출시했다. 백넷 전문 외주 개발자는 마지막으로 우리가 직접 만든 펌웨어를 QA까지 해주고 계약이 종료되었고, 프로덕트 매니저 토니(가명)가 수소문한 몇몇 베타 테스터들에게 제품이 전달됐다. 빌딩 관리 시스템 시장에 첫 발을 내딛는 우리 회사에게는 실제 백넷을 사용하는 유저들로부터 받는 피드백이 절실했다. 실제로 몇 달간 고객을 통해 받은 피드백을 통해 점진적으로 기능을 개선할 수 있었고, 더 나은 사용성을 위해 일부 백넷 오브젝트를 조정하거나, 백넷과 기존 클라우드 연결을 동시에 가능하게 하는 하이브리드 모드, 사용자 입맛에 맞는 다양한 설정 방식을 고려한 기기 구성 페이지 등의 많은 긍정적인 변화를 이룩해 낼 수 있었다.

나중에 깨달았지만, 내가 이 회사에서 자연스레 접한 이러한 개발 프로세스는 사실 애자일 방법론의 일부이다. 내가 개발에 참여한 MVP는 애자일한 제품 개발에서 흔히 사용되는 개념으로, 최소의 기능으로 제품을 시장에 선보이고 빠르고 반복적으로 고객 반응을 살피는 방식이다. 백넷이 처음이라 잘 몰랐던 우리는 "정말 고객이 원하는게 무엇인지" 기민하게 대응하며 천천히 제품을 진화시켜 나갔다. 마치 아래의 그림처럼!

처음부터 완벽한 계획 말고, 당장 할 수 있는 것부터 차근차근!출처: https://blog.crisp.se/2016/01/25/henrikkniberg/making-sense-of-mvp

누군가에게는 이상 속의 얘기처럼 들리거나, 조금 대책 없이 보일 수 있을 것이다. 하지만 적어도 나는 이 회사에서 그 이상을 현실로 만들려 노력하는 개개인들을 보았고, 그것이 만들어낸 가치를 분명히 느꼈다. 시작은 조금 엉성했을지 모르지만, 이런 과정을 통해 만들어진 어웨어의 B2B 기능들 덕분에 지금은 수많은 기업과의 딜을 따내고 시장에서도 어느 정도 인정받게 되었다.

이것이 가능했던 이유는 아마 구성원들의 애자일에 대한 이해가 합치했기 때문일 것이다. 프로덕트 매니저 토니는 개발 전반에 걸쳐서 고객의 피드백을 꾸준히 개발 팀에게 전달하여 중요성을 인지시켰고, 스크럼을 통해 매 단계마다 달성해야할 범위를 적절히 설정해주었다. 팀 매니저 주혁님은 익스트림 프로그래밍의 모범 사례를 전파하며, 테스트를 통한 점진적 개선과 충분한 커뮤니케이션이 개발 조직에서 실천될 수 있도록 꾸준히 도왔다. 또한 UX 디자이너 지용님(가명)은 고객의 피드백에 대한 진지한 고찰을 통해 기술적인 복잡성을 이해하고 사용자 친화적인 UX로 승화시켰다. 내가 경험한 것을 전부 구구절절 설명하기는 어렵지만, 나는 '협업이란 이런 거구나'를 이 프로젝트를 통해 제대로 느낄 수 있었다.

...
2020년 7월 초.

이렇게 나도 모르게 일에 빠져 지내는 동안, 시간은 벌써 곧 2년이 다 되어가고 있었다. 결정의 시간이 온 것이다. 1편에서 말했듯, 나를 제외한 모든 병특 개발자들은 복무만료 이후엔 퇴사를 다짐했다. 하지만, 나는 뭔가 말로 형용할 수 없는 아쉬움이 남았다.

'나 설마 남고 싶은건가?ㅋㅋㅋ'

그냥 내 본성이 귀차니즘 그 자체라 변화가 두려웠을 가능성이 크긴 하다. 그리고 연봉도 조금 올려준다니까. 그래도 이곳에 남을 이유를 찾자면... 끝나면 학교로 복학해야 하는데, 코로나 때문에 비대면 수업을 한다더라. 나는 비대면이면 성격상 도저히 공부가 안될 것 같았다. '뭐, 1년 정도 더하면 코로나 끝나고 산뜻하고 집중도 잘 되는 캠퍼스 라이프를 할 수 있지 않을까?'라고 생각했다. (근데 결국 2023년까지 안 끝났다^^)

근데 사실 마음을 굳힌 더 큰 동기는 따로 있었는데, 바로 앞서 언급한 UX 디자이너 지용님이 회식 자리에서 지나가듯이 했던 말이었다. 아마 누군가가 병특들도 곧 나가고 회사 분위기가 싱숭생숭 하니, 대략 "지용님도 오래 다녔는데 언제나가지용?"처럼 장난스럽게 질문을 던졌는데, 그에 대한 답변이 나에겐 엄청 감명깊었다.

"여기 아직 제가 할 수 있는게 남아있는 것 같아요."

어쩌면 내가 느낀 아쉬움이 바로 이런 게 아니었을까? 내가 만들어낸 것과 앞으로 만들어야 하는 것들, 아마도 내가 가장 잘 할 수 있을 것이기 때문에, 그것을 책임져보고 싶다는 마음. 그의 말을 듣고 보니, 그 제품에 대한 오너십이 내가 이 회사에서 2년간 주변 동료들을 통해 보고 느낀 것들로 갖게 된 무언가가 아닐까 싶었다.

얼마나 감명 받았으면 오글거리게 이런 메모도 썼더랬다.

2020년 8월 26일자로 나는 소집해제가 되었고, 드디어 국방(?)의 의무에서 벗어날 수 있게 되었다. 이젠 진짜 평범한 정직원으로서 펌웨어 개발자 일을 하게되었다. 병특이 아니라고 특별히 달라진 건 없었다. 주혁님 그리고 피터와 데일리 스탠드업을 하고 토니와 스프린트 계획을 하고, CS팀으로 들어온 버그를 고치고, 로드맵에 따라 백넷만큼 복잡한 기능들을 만들어가며 때로는 밤새 고생도 하고, 고객의 반응에 보람도 느끼며 나날을 보냈다.

사실 이 흥미로운 스타트업에서 겪은 에피소드들을 더 늘어놓자면 아직 할 말이 많지만, 이제 병특이라는 제목으로 다루기에는 이야기가 꽤 많이 진행된 것 같다. 그래서 이쯤에서 잠깐 마침표를 하나 찍고, 또 다른 페이지에서 내 이야기를 마저 이어가 볼까 한다.

— <스타트업 병특 개발자의 삶> 끝 —

profile
어쩌다 보니 임베디드 개발자

12개의 댓글

comment-user-thumbnail
2023년 5월 31일

폼 미쳤다...

1개의 답글
comment-user-thumbnail
2023년 6월 4일

멋있으십니다... 잘읽었습니다!

1개의 답글
comment-user-thumbnail
2023년 6월 7일

진짜 글 잘 읽었습니다!
저도 이번 년도 12월이면 병특을 마치고 회사를 나올 수 있게 되었는데 어딘가 찜찜한 이 느낌.. 무언가 모를 회사에 남고 싶은 이 감정이 무엇인지 고민했었는데 이 글에서 언급해주신 친구분의 말씀을 읽고 확신이 서게 되었습니다.

저에겐 이런 글솜씨가 없지만, 만약 글을 쓴다면 제 글은 범죄의 기록이라 할 만한 글이 될 것 같네요;; 아마 저 또한 이러한 범죄의 기록들을 면죄하기 위해 병 특이 끝나고도 회사를 좀 더 다니게 될 것 같습니다. 값진 경험 공유해주셔서 감사합니다!

1개의 답글
comment-user-thumbnail
2023년 6월 9일

또 다른 페이지에서 내 이야기를 마저 이어가 볼까 한다.

기대가 되네요!

1개의 답글
comment-user-thumbnail
2023년 7월 8일

홀린듯 읽었습니다. 좋은 경험 공유해주셔서 감사합니다.

1개의 답글
comment-user-thumbnail
2024년 2월 16일

mac 앱 실행 단축키 만들기 로 유입되어 어쩌다보니 3편을 다 읽고 병특 동지애라는것을 느끼고 갑니다. 성취욕과 학구열도 대단하지만 글 솜씨가 무지 좋으십니다. 뜸하지만 구독할만한 가치가 있는 글인 것 같습니다. 앞으로도 화이팅 입니다!

1개의 답글