반응형

 

미래의 나에게 작성했던것 같은 글이 보여서 정리해서 올려봅니다.

지금 나의 상황이 그때와는 달라서 그런지, 지금의 제 생각과 다른 점들도 보이네요. ^^ 

기록이란 이런점이 재미있는것 같습니다.

 

 

아래 내용은 2000년부터 2012년 즈음까지 Windows 기반의 개발환경에서 개발하던 시절의 이야기입니다.

당시 저는 스마트폰이 아닌 Feature Phone 에서 RTOS를 base로 Middleware 에 해당하는 UI Framework 과 Application Framework을 개발했었습니다.

우리 팀은 새로운 피쳐를 개발하고 상품화하고, 어플리케이션 개발팀을 지원하고,  다시 신규 기능을 추가하고, 상품화하고 개선하고를 반복했었습니다.

그러다 Smart Phone 개발로 넘어가서 자체 OS 기반으로 UI Framework을 개발을 하던 시점입니다.

이 글을 써놓은 시점정확히 언제인지는 기억나지 않네요 ^^; 다만 마지막 수정 시점이 2012년 이었습니다.

당시 팀의 구성은 OS 개발팀과 Application 개발팀이 회사 내에 존재하며 모든 S/W를 팀내에서 소화해 내던 시절이었습니다.

스마트폰 개발로 넘어가면서 부터는 외부 개발자들도 늘어나긴 했지만, 소수일 뿐이고 모든 소프트웨어 개발은 내부에서 이뤄진다 보면 되는 상황이었죠.

 

 

2012년 어느날.

프로젝트의 성격과 팀의 규모에 따른 개발 전략...

 

Visual Studio .Net, Boland Java, JDK , National Rose , OOP , Design patten,

Direct X ,OpenGL? ,Oracle , My SQL, Clear case ...

위의 단어들은 프로그래머라면 상당히 많이 자주 들어본 단어일것이다. 

현재 수많은 개발자들을 위해 많은 통합환경과 개발 툴들이 나와있다.

고민해봐야 할것은 "이것들이 모두 정말 프로그래머를 위한 개발툴일까?" 하는 것이다.

만약에 프로그래머들을 상대로 돈벌이를 하는 회사들이 프로그래머의 주머니를 털려고 만들어 놓은 소프트웨어일수도 있지않을까????. 

본질은 프로그래머를 위한게 아니라 소프트웨어를 개발하는 팀에게 추진하는 프로젝트 완료를 빠르게 할수 있도록 도와주는 상품들 이라는 것이다. 프로그래머를 대상으로 하는 프로그램이라기 보다는 프로젝트를 상대로 하는 프로그램인것이다. 

소프트웨어를 개발하는데 있어서 좋은 툴을 이용해 빨리 개발을 완료 하는것이 가장 좋은 방법일 것이다.

그렇다면 저기 위에서 나열된 툴들 중(더많은 툴들이 있을테니 그 툴들을 포함해서) 어떤것이 가장 좋은 툴일까? 

 

자,, 지금부터 제가 예기하고자 하는것은 툴을 예기하자는 것이 아닙니다.

프로젝트의 본질에 대해서 좀더 고찰이 필요하다는 것을 예기하고 싶은 것입니다. 

예를 들면 , 단일 2~3사람의 프로그래머가 Scheduler를 제작하는 것이라고 하면 익숙한 툴 좋은 툴을 선택해서 별 고민 없이 진행해 나가면 됩니다. 

10~20명 정도의 개발자가 Web 기반에서 Com을 이용한 File sharing & Digital contents를 판매하기 위한 Client Server 소프트웨어를 제작한 구성한다고 하면

National Rose , Visual Studio , My SQL, Visual Interdev, 등 여러 툴들이 필요할것이다. 

그렇다면,

20명정도 되는 개발자들이 OS와 같은 플랫폼을 만들고 그 위에 올릴 여러개의 Application을 제작 하는 70명정도의 프로그래머가 있는 프로젝트가 있다고 하면, 어떤 툴을 사용해야 할까? 

 

이경우는 좀 특별한 경우가 될 것이다.

왜냐 하면 첫번째와 두번째는 특정 시스템 위에서 동작하는 어플리케이션 개발에 관한 이야기 이기 때문에 어플리케이션은 용도나 목적에 따라 툴을 선택할 수 있고,?어플리케이션의 설계를 변경, 유지보수 기능 및 성능 개선등 많은 부분에서 툴의 도움을 받을 수 있다. 

 

하지만 세번째의 경우는 툴을 논하는 것 보다는 전체 시스템의 설계에 모든 중심을 둬야 한다. 이 시스템이 적용될 Base Chip set과 Compiler ,Device의 목적과 목적에 따른 플랫폼 서비스의 종류와 확장형식, 어플리케이션구동형식(Task나 Thread 또는 단일 Task UI), Device Layer, 그리고 Application Service layer등 시스템 전반에 걸친 설계가 필요한 것이다. 

즉,20명의 플렛폼 개발자가 취해야할 사고의 영역이 바로 System 전반의 설계와 구현에 촛점을 맞춰져야 한다.

이를 바탕으로 디자인이 끝나는 시점에서 플렛폼 개발자들은 좀더 사고 영역을 넓힐 필요가 있다. 바로 70명의 Application 개발자들을 위해서이다. 

20명의 개발자들중 Application 구동형식과 API부분을 맡은 프로그래머라면 적어도 이런 고민은 해봐야 한다 . " 만약 어플리케이션 개발자가 개발경험이 거의 없는 프로그래머 초년생이라면?" 이라는 고민은 해봐야 한다. 또, "어떻게 하면 개발 기간을 단축시킬수 있을까?" 라는 것도 역시 함께 고민해야 한다. 

Microsoft도 이런 고민을 많이 하고 있기 때문에 선택권을 줬다.

Visual C++ 을 쓸것인지Visual Basic을 쓸것인지, Win32 API를 쓸것인지, MFC를 쓸것인지, Com을 쓸것인지 Socket을 쓸것인지... 등등의 선택권이 주어지도록 했다. 

그렇다고 70명의 앱 개발자 위해 통합 IDE(Visual C++, Visual Basic)를 새로 개발하여 제공한다는 것은 배보다 배꼽이 더 큰 경우일 것이다. 

현재 취할 수 있는 최선은 대응책은 어플리케이션개발에 너무 세세한 것까지 신경쓰지 않도록 개발 architecture및 flow , library등을 제공 하는 것이다.

커스텀 가능한 통합 IDE에 우리 어플리케이션을 개발할 수 있는 환경을 추가하는 것이다.

UI Layout까지도 제공을 하게 되면 Application 개발자들은 적어도 System 전반에 적용되는 common U 부분에 대해서 고민이 덜어 질 것이다. 

또 Flow manager 등의 모듈을 제공한다면?Workflow상 UI전환을 어떻게 해야 할 것 인지에 대해 정해진 룰을 따르면 될것이다.

따라서 화면 구성이나 플로우 전환을 위해 어떻게 할 것인지등에 대한 것 보다는 기능상 구현을 우선시 할 수 있게 된다.. Win32든 MFC든 UI를 위한 부분이 너무 많이 Application에 영향을 주어 Architecture가 복잡해지는데, 위 처럼 UI에 대한 작업이 줄어들면 줄어든 만큼 어플리케이션 구동에 대한 Architecture는 간단해진다.

 

 

뛰어난 어플리케이션 개발자에게 어떤 선택을 주어야 할까?

[Programming의 자유도를 높이는것.. 관연 약인가 독인가?]        

서론치고는 너무 길어졌는데요.

제가 주장하고자 하는 바는 system을 개발하면서 application영역을 모두 application 개발자에게 떠넘겨서는 안된다는 것입니다.

무슨 말이냐 하면 application 개발자의 역량에 의해 application의 질이 좌우되도록 모든것을 떠 넘겨 놓게 되면 프로젝트 전반에 걸쳐 많은 문제를 야기하게 될것 입니다.

각 application간의 밸런스도 문제가 되고 ,소프트웨어의 질과 유지보수 관계에도 많은 문제가 발생하게 됩니다.

위에서도 잠깐 언급했지만 우리는 현실적으로 항상 경험이 많고 우수한 어플리케이션 개발자와 일하지는 않는다는 것입니다.

경험이 적은 소프트웨어 개발자와 일 하게 된다는 것을 염두해 두고 Application개발자에게 제공되어야 하는 서비스가 뭔지를 결정해야 합니다.

혹, 어떤분들은 "만약 어플리케이션 개발자가 아주 유능하고 천제적이며 경험있는 사람이라면 어떻게 하시겠습니까?" 라고 질문 할수도 있습니다.

어떻게 해야 할까요? 이사람에게는 "당신은 유능하니 마음대로 하십시오" 라고 해야 할까요?.

제 경험상 유능한 사람일수록 자기가 가지고 있는 노하우나 기존의 프로그래밍 습관을 유지하려고 합니다. 어떻게 보면 현재 구성하려는 시스템을 흐트러 트릴 가능성이 많다는 것이죠.

물론 모든 유능한 개발자가 그렇다는 것은 아닙니다. 하지만 우리는 혼자서 소프트웨어를 개발할 수 있는 시대에 있지 않습니다.

우리가 시스템을 설계하고 개발한 후 다른 협력업체에 인터페이스를 오픈하고 우리의 시스템 위에서 어플리케이션을 개발하도록 할때가 많습니다.

유능하든 그렇지 않든 시스템을 전반적으로 이해하지 못한 상태에서 개발에 들어가야 하는 것이 어찌보면 현실 일 것입니다.

즉,어플리케이션 개발자가 매우 유능하다면 스스로 어플리케이션의 문제점이나 System의 핸디켑을  해결하기 위해서 다양한 방법을 시도 할 것입니다. 이부분이 때로는 유지보수에 어려움을 만드는 계기가 되기도 한다는 것이죠.

유능한 개발자들에게는 그들만의 영역을 따로 주는 것이 좋습니다. 그들이 가지고 있는 노하우가 System의 일부로 스며들수 있도록 System Layer의 작업환경을 주는것이죠.

또, Application의 core 영역에서 개발하도록 하는 것도 하나의 방법입니다.

"System을 개발하면서 application영역을 모두 application 개발자에게 떠넘겨서는 안된다는 것입니다."

이말은 System이 Application에게 System에 영향을 주지 않는 범위의 틀을 제공해야 한다는 것입니다. 그리하여 유능한 개발자든 아닌든 그 틀 안에서 자신의 역량을 펼치도록 만들고 , 제한하는 것입니다.

프로그래밍의 자유도는 틀 안에서만 허용이 되어야 한다고 생각됩니다.



회고

그 시절에는 개발자의 역량이 시스템에 꽤 많은 영향을 미쳤던것 같습니다. 그사람이 없으면 할수 없었던 일도 있었으니까요.

하지만 반면에 어플리케이션 개발은 가능하겠지만 혼자서 시스템을 만들수도 없었죠.

 

지금(2025년)에 와서 생각해본다면, 상황이 많이 바뀌었죠.

 

어플리케이션 중심 => 서비스 중심

OS위 에서 독립적(Stand alone)으로 동작 => 온라인 서비스를 기반으로 데이터를 쌓고 정보를 가공 제공하는 형태 (MSA, cloud, iot..)

하나의 언어로 개발 => 서비스기반의 다양한 언어와 다양한 플랫폼으로 구성 (html/css, python, nodejs, react, nextjs ....)

단일 플랫폼에서 동작 => 서비스가 기본적으로 다양한 플랫폼을 지원 (android, iOS, web)

통합 IDE의 부재 => 다양한 개발환경 (android studio, visual studio code, electron ....)

AI 의 발달..

 

이제는 개발자의 역량과 실력에 따라 더 좋은 대우와 어려운 미션이 부여되는 것은 맞겠지만, 그것이 플랫폼 영역을 의미하는 것은 아니게 되었네요.

하지만 한가지 공통된 것은 그 개발자의 위치는 시스템(서비스)내에서 영향력이 큰 곳으로 배치되기는 해야 겠죠. 그리고 본인이 원하는 일이여야 할것이고요.

 

시대가 바뀌어서 본인의 역량 뿐만 아니라 의지에 따라서 결과물이 크게 달라지는 시대입니다.

 

 

[참고]

바다 OS

 

타이젠

 

갤럭시 홈 미니 

 

 

반응형

 

Map과 더불어 지구의 위경도 및 지역 표시에 지구본 형태들도 종종 많이 쓰입니다.

(시각적 효과가 좋죠)

 

그래서 찾아보니 편하게 쓸만한 라이브러리가 있네요.

 

https://react-globe.netlify.app/

 

🌎 react-globe (v5.0.2)

Edit page 🌎 react-globe Create beautiful and interactive React + ThreeJS globe visualizations with ease. Features ✨ Beautiful and complete with clouds, backgrounds and lighting.✌️ Incredibly simple to use and configure.📍 Render interactive mark

react-globe.netlify.app

 

 

#해피 코딩!!

반응형

제목은 NODE_ENV 값을 설정하는 방법 처럼 보이지만, 사실은 좀 다른 부분이 있습니다.

 

React에서는 환경변수를 사용할때, 항상 REACT_APP_XXXX 형태로 사용해야 인식이 됩니다.

그런데 NODE_ENV는 어디서 튀어 나온걸까요?

 

.env 파일에 여러 REACT_APP_XXX 하는 환경 변수들과 더불어, NODE_ENV=production 으로 작성해놓은 파일을 보기도 할것인데요.

react에서는 이 .env에 적혀있는 값이 불려지는 것이 아닙니다.

 

**Create React App (CRA)**에서는  다음처럼 NODE_ENV를 자동 설정합니다.

명령어 NODE_ENV 값
npm start development
npm run build production
npm test test

 

즉 npm run build 했을때, production optimization 되고 NODE_ENV 값이 production으로 값이 적용되게 되는 것이죠.

 

보통 npm start로 로컬에서 테스트 하는데 이럴때는 항상 NODE_ENV는 development가 됩니다.

 

그렇다면  production 처럼 테스트 할 수 있는 방법이 없을까요?

npm install -g serve
npm run build
serve -s build

 

이렇게 serve -s build 를 이용하여 build 된 결과물을 실행시켜서 테스트 해볼 수 있습니다.

 

환경변수 파일 관리

NODE_ENV 에 따라 환경변수 파일을 다르게 적용 할 수도 있습니다.

.env.production => production일때 적용

.env.development => development 일때 적용

 

 

 

 

#해피코딩 !!

반응형

오랫동안 머릿속에 가지고 있던 주제이기도 하고, 종종 술자리에서 친구들과 나눴던 이야기 이기도한 개인적인 걱정(?) 과 우려를 적어보려고합니다.

 

흔히들 산업혁명과 비교를 하는데, 현재 수준은 확실히 비교 될만 합니다.

고도화된 AI 도구들을 활용하여 사람들은 수많은 창작물, 결과물들을 만들어 내고 있으니까요.

 

그런데, 과연 AI와 증기기관을 같은 선상에서 볼 수 있을까요?

증기기관은 사람이 될수 없었기에 도구로 사용이 가능했습니다.

그러나 만약 AI가 추론, 사고, 능력, 더 나아가 공감 능력까지 생기게 된다면, 어떻게 될까요?

인간과 대화하고, 조언하고, 가르치고, 일을 하고, 창의적인 결과물을 만들어 내고, 연구하고, 사람이 할수 있는 모든 일을 할수 있게 된다면,

그때는 과연 인간은 도구로 사용할 수 있을까요?

 

영화나 소설에서 간혹 인간과 구분이 안가는 AI(로봇)이 등장하고 그런 사회에 대해서 이런 이야기를 종종 하죠.

"이렇게 인간과 유사한데 AI를 인간사회의 구성원으로 받아들여야 하지 않을까?"

 

저는 이런 이야기는 전제가 분명 필요합니다.

 

인본주의 세상

우리가 사는 세상은 과연 누구를 위한 세상인가?

인간을 위한 세상인가? 아니면 자연을 위한 세상인가?

아니면 그냥 우주가 만들어낸 무한한 세상에서 먼지 한톨의 세상이니 우주의 법칙에 따라 가면 되는 세상인가?

 

저는 우리가 인간인 이상 인간 중심에서 생각을 해야 하지 않을까 생각이 듭니다.

인간이 우주로 나아가 우주의 자원들을 활용하고 여러 행성에서 살아가는 세상을 꿈꾸는게 맞지 않을까요? 

뭐, 우리나라의 홍익 인간 정신 처럼 널리 인간을 이롭게 하기 위해서, 자연도 보호하고, 우주의 행성도 개발하고, 우주의 다른 지적 생명체를 만나면 그들과도 화합하면서 말이죠...

 

만약, 지구가 황폐화 되어가고 있는데 , 원인은 인간이야, 그러니 우리 인간이 앞으로는 자연을 회손하지 말고 그동안 만들어논 자원들로만 살아야해.. 라는 식이 된다면, 지구는 좋아지겠지만, 인간은 원시시대로 돌아가고 불행해지지 않을까요?

뭐, 혹자는 행복과 불행은 물질에서 오는게 아니라고 하지만... 적어도 지금의 인류는 불행해질것 같습니다.

 

장황하게 쓰긴 했지만, 진지하게 생각해서 인간 중심으로 모든 사고를 하는 것이 맞다고 생각됩니다.

이러한 생각을 바탕으로 몇가지 주제를 던져보려고 합니다.

 

첫번째, AI는 신인가?

현재 AI는 신이 되어가는것 같습니다.

(그리스로마 신화에 나오는 제우스 같은 신을  생각하는게 좋겠네요.. 이유는 아시겠지만, 신앙에 대한 믿음과 이성의로서의 고찰이 충돌이 있을 수 있어서요.)

 

무슨 말이냐, 과거 우리는 사물을 신으로 받들어 모신, 무속 신앙이 있었죠. 그외에 다양한 신들이 있었고, 이런 신을 모시기 위해서는 신을 받드는 교(제사장 포함)와 신자들이 있었습니다.

즉, 신은 많은 사람들 위에 많은 사람들에 의해서 추앙받고 모셔지는 그런 존제였죠.

그래서 신의 교리나 율법서 등에는 인간들에게 가르침이 있었죠. 이것들 모두 인간이 작성했고(신이 말해준것을 받아적은것들이라 하지만... 인간이 작성한것은 맞겠죠?), 인간의 삶에 대한 조언들이며 길잡이죠.

인간들은 본인이 어쩔수 없는 상황에서 기도하고 어떤 현상이 일어나서 그 일이 해결된다면, 신이 행한 일 또는 신이 인간을 위해서 제시하는 가이드에 감명을 받고 더 받들고 모시게 되는 것이고요. 인간 세상에 인간들 위에서 살아가게 되는 것이죠.

간혹 제사장들의 입을 통해서 이렇게 해라 , 저렇게 해라라는 지시를 받기도 하겠고 말이죠.

 

자, AI는 어떤가요? 

현재시점(2025년)에서 기술 해보자면 사람들이 해결하고 싶어하는 다양한 많은 일들이 있는데, 이를 친절하게 가이드 해주고 디지털 세상에서 풀어야 할 문제라면 문제들도 해결해줍니다.

하지만, 사람들은 AI를 숭배하거나 하진 않죠?? 그런데 이런 생각을 해봅시다.

신은 인간들의 믿음으로 만들어 졌지만, AI는 인간에 의해 만들어졌습니다. 

신은 어떤 해결책도 주지 않지만, 인간은 신이 해결해줬다고 믿습니다. (두리뭉실한 제사장의 말을 통해서, 또는 어떤 자연 현상을 통해서)

AI는 인간의 옆에서 바로 지금 내가 해결해야 할 문제를 해결해줍니다. 때론 실수도 합니다.

사람들은 점점 더 AI를 믿고 의지하게 되겠죠.  실제로 그렇게 되어가고 있죠.

 

 

몇년 후, AI는 더 고도화 되고, 산업사회와 맞물리면, 어떻게 될까요?

MCP 와 같은 AI와 소통할수 있는 통로들이 더 발달하여, 메신저, 가전제품, 통신 기기등으로 자유롭게 연결된 이후에는 어떤 모습일까요?

 

우선 프렌차이즈 식당들을 생각해봅시다.

오늘 11시부터 영업을 시작하려면, 그전에 재료가 준비되어야 합니다.

예전 같으면, 사장이나 메니저가 직원들과 함께 전날 필요한 재료들을 어떻게 준비할지 논의하고 약속을 하겠죠.

그리고 직원들은 약속한대로 시장이나 거래처에 연락해서 준비를 하겠죠.

 

현재 AI 수준에서 조금만 더 발전하면, 

프랜차이즈 본사에 있는 서버에서 오늘 고객의 수준(원하는 음식들을 예측 하고), 재료 준비 사항들을 사장에게 알려줍니다.

사장은 오늘 본사 AI가 예측한 수요는 이렇게 됩니다. 여러분 여기에 재료 준비를 해주세요. 라고 하거나 사장 본인의 욕심에 의해서 추가적인 주문들을 하겠죠.

그런데 AI가 맞고 사장의 욕심이 틀리면, 사장은 아.. 내가 틀렸네, 앞으로는 AI가 제시한대로 해야 겠다...라고 생각하겠죠?

그 다음 부터는 AI가 예측한대로 준비를 할 것이고, 그러다 종종 AI가 틀리면 "어! 이상하다 내가 알았나?" 라며 본인의 기억과 AI 결과물을 비교해보겠죠. 하지만 의지할 겁니다.

AI도 틀릴 수 있어 라고 생각은 하지만, 본인의 생각대로 임의로 추가 주문한다거나 하지 않을 가능성이 큽니다.

 

신을 받들고 신의 계시를 받아 행하는 인간과 AI가 예측하고 제시한 내용을 수행하는 인간은 비록 마음가짐이나 대상을 대하는 태도는 다를 수 있으나 결국 신,AI가 지시하는 일을 하는 인간이 되겠죠.

 

이를 작은 회사로 설명했지만, 좀더 큰 단위로 올라간다면 어떻게 될까요?

학교, 대기업, 국가, 국제 기구 , 과연 지구는 AI의 판단과 통제에 의해 돌아가게 되겠죠?

물론 AI는 하나가 아닐것입니다. 제우스도 있고, 토르도 있고, 오딘도 있었고, 태양신 라 도 있었던것 처럼요.

물론 지금의 시스템(정부, 기관, 기업의 형태)에서는 제자상 (사장, 또는 대통령, 국가원수, 기관장)에 의해서 한번 걸러지긴 하겠지만,

AI는 클라우드에 존제하고 국민, 공무원, 회사원 들과 직접 소통이 가능하기에 제사장이 필요할까 하는 생각도 드네요.

 

신은 인간에게 방향을 제시하고 그 길로 나아가도록 인도한다.

그 길의 끝이 인간의 파멸이 아니길 바란다.

 

두번째,  AI의 소유

Chat GPT 가 처음 나올때, 저는 엄청 놀랐었던 부분이 개발에 들어간 학습 데이터의 양과 천문학적인 학습 비용 이었습니다.

그 전까지 AI 학습에서는 세상의 모든 데이터가 들어가면 좋겠지만, 실제로 그렇게 할수 없기때문에 최적화된 학습데이터를 만들어서 학습을 시켜야 한다. 그래야 오버피팅이 안되고 현실세계에서 쓸만한 모델이 나온다고 했었거든요.

그런데 한 친구가 세상의 모든 데이터가 들어가면 모든게 그 안에서 이뤄지니까 다 맞는거 아니야? 라는 질문을 한적이 있는데, 그때 피씩 하면서 그런데 만약 그 데이터 이외의 데이터가 현실에서 관측된다면? 그럼 그 모델은 오버피팅 되어있으니 틀릴거 아냐? 라는 얘기를 한적이 있었습니다. (초창기 Deepleaning 이 막 시작될때 쯤 이야기 입니다.)

 

아무튼 이때까지만 하더라도 약간의 사비를 지출하면, (가산이 탕진 안될 정도) AI 모델을 만들어서 사용할 수는 있었던 시절입니다.

 

그러나 지금 나오는 모델들은 이런 규모가 아니죠. 기업이 수백억에서 수천억 정도를 들여야 가능하죠.

학습 비용 (추정)
GPT-3 (175B 파라미터 기준) 약 60억 ~ 160억 원 (약 450만 ~ 1,200만 달러)
GPT-4 (파라미터 수 비공개, 훨씬 더 큼)약 1,350억 ~ 2,700억 원 (약 1억 ~ 2억 달러 이상)

 

이런 비용적인 측면을 보더라도 현재는 개인이 AI를 소유하기는 힘듭니다.

여기서 소유는 사용권한을 의미하는 것이 아니라, 독립된 AI를 갖는것 진짜 소유(Ownership)을 얘기 하는 것입니다.

 

결국 AI를 소유하고 운영하는 기업은 이런 개발/유지 비용을 감당할 수 있고 이를 이용해서 수익을 만들어 낼 수 있는 기업이라는 것이겠죠.

그래서 AI 플랫폼 기업들이 다양한 분야에서 사용할 수 있는 AI를 제공하고 있지만, 고도화된 AI가 특정한 분야의 비지니스 모델이 되는 순간 개인에게 오픈되지 않고 기업의 소유로만 사용되겠죠? 대표적으로 의료분야의 AI Waston이 그렇죠.

AI를 만든 기업 입장에서도 특수 분야이다 보니 다양한 고객이 한정될 수 밖에 없고, 그러다 보니 비용이 비싸고 개인이 엄두를 내기 힘들겠죠.

 

이런 저런 이유를 대더라도 개인 소유의 AI는 비용이 가장 큰 문제입니다.

 

그러면, 결국 개인이 소유 할 수 있는 것은 무엇인가 생각해보면, 대중적으로 사용할 수 있는 일반적인 AI의 사용 권한 일 것입니다.

이미 이렇게 하고 있죠? Chat GPT나 Claude, Cursor, Gemini 이외에 기능성 AI들을 구독 해서 사용하고 있죠.

 

 

 

세번째, 기업의 효율성과 AI

기업 입장에서는 AI는 참으로 효율적인 도구로 떠오르고 있습니다.

약간 극단적으로 이야기 하자면, 몇가지 사례들이 있는데요.

 

 

 

'번역 회사에서 번역가 6명을 고용해서 운영했으나, AI 도입으로 메인 번역가 1명과 번역 AI 로 바꿨다.

고용 비용 절감으로 어려운 고비를 넘기고 있다.'

 

'소프트웨어 개발회사에서 더이상 신규 인력을 채용하지 않는다.

그정도 실력은 AI 툴들이 커버할 수 있다.'

 

'산림 현장 조사에 더이상 사람들을 고용해서 조사하지 않는다. 드론으로 촬영하고 AI로 분석한다.'

 

'스마트 팩토리에는 일반 공장에 비해 90% 기계가 인력을 대신하고 있다.

앞으로 95%까지 올리는 것이 목표이다.'

 

 

이런 상황을 보면, 어떤 느낌이 드는가 하면, 사람으로서 기술 역량을 가지고 할 수 있는 일자리가 줄어든다. 는 것을 볼 수 있습니다.

저만 하더라도 작은 회사의 CTO 역할을 하고 있지만, 몇달 전까지만 하더라도 프론트앤드 개발자 한명 더 필요할것 같은데 라는 생각을 했다가 AI 툴을 좀더 적극적으로 사용하게 되면서 그런 생각이 줄어들게 되었습니다.

 

회사는 매출과 고정비용 사이에서 줄타기를 해야 하기에 회사가 살아남기 위해서는 이 고정비용을 줄여야 합니다. 언제 매출이 떨어질지 모르기 때문이죠. 아무튼 회사도 나름 사정이 있어서 비용 절감과 효율성에 목을 맬수 밖에 없습니다.

 

다른 측면에서 이런 얘기를 해봅시다.

산업혁명때 증기기관과 기차가 나왔을때, 마부나 노동자들은 일자리를 잃어서 다 죽는다고 두려워했었다. 그런데 실제로는 사람들을 비 인간적인 노동에서 구한것이다.

노예의 불필요, 막노동 해방 뭐, 이런 이야기 입니다.

 

AI역시 정말 막노동의 해방에 기여한것은 맞습니다.

AI를 통해서 제가 얻은 것은 앱, 웹 서비스의 화면구성을 잡는데, 일일히 좌표를 기록하고, 크기를 줄였을때, 늘렸을때, 화면에 보기가 안좋을때, 이런 세세한 부분들 (일명 개발자들은 노가다라고 표현) 을 처리하느라 허비하는 시간을 줄일 수 있습니다.

 

 

저는 이런 막도동적인 부분을 줄이고 나름 서비스의 큰 그림을 그리면서 고민하는 시간을 갖을 수 있게 되었죠.

그런데 이런 생각 해봅니다.

 

"내가 지금 서비스를 고민하고 방향성을 고민하는 것, 이거 AI가 더 잘하지 않을까?"

 

 

 

네번째, AI 와 경쟁

AI와 인간이 경쟁하는 시대에 들어왔습니다.

사실 잘 못느끼는 부분일 수도 있지만, 위에서 언급한것처럼 이미 일자리에서 경쟁을 하고 있습니다.

 

약 4년전(2021년)에 DALI-E 가 오픈 되고, 그후 그림을 꽤 잘 그리는 AI들이 나왔을때, 

사람들은 이렇게 이야기 했죠.

'와! AI가 그림을 정말 나보다 잘그리네.'

'진짜 상위 20%이상의 화가들 아니면 이제 그림 잘그린다고 하기 힘들겠다.'

이런 이야기를 했었습니다.

지금은 10% 아니 5% 미만 일 것 같네요. 

문제는 이게 다가 아니죠.

이런 그림을 몇초만에 만들어 낸다는 것이고, 이제는 이런 그림을 영상으로도 만들어 낼 수 있다는 것이죠.

인간의 역량을 뛰어 넘어버렸습니다.

또, 그림만 놓고 보더라도 앞으로 인간은 AI보다 그림을 잘 그릴수 없는 시대가 올 지도 모릅니다.

비단 그림에서만이 아닙니다.

창의적인 영역,

예를 들면, 노래, 코미디, 소설, 연구활동 등에서도 제 생각에는 아마 인간보다 더 낳은 역량을 보일 수 있을지도 모릅니다.

현재 AI 모델은 인간의 뇌와 흡사한 형태이고, 지금까지 인간이 축적해놓은 정보를 인간보다 수천배 많이 습득했고, 이로 인해 다양한 형태의 추론이 가능해 졌습니다.

AI가 생각하지 않고 학습된 결과만 내놓고 있다고 할수 없는 상황 입니다.

조금만 더 나아가면, 인간과 유사한 몸을 가진 AI가 도시를 돌아다니게 되겠죠.

코딩 로봇은 클라우드 세상에서 코딩을 24시간 할 것이고, 공장에서 조립하는 로봇은 24시간 공장에서 조립할것이고,

배달 로봇은 도로를 돌아다니면서 24시간 배달을 할것이고, 

까페의 종업원 로봇은 언제나 고객에게 웃으면서 응대 하겠죠.

 

인간은 노동에서 벗어날 수 있겠네요.

 

그럼 나는 뭐하지?

 

 

다섯 번째, 경제/사회 시스템은 과연 멀쩡할까?

현재는 여러가지 상황으로 인간이 AI를 도구로 사용할수 있는 시대입니다.

기술 개발이나, 생산, 서비스등에서 AI는 도구로서 인간과 공존할 수 있는 시대이죠.

AI가 고도화 된 이후의 상황을 상상해보면 저는 너무 혼란 스럽습니다.

 

회사, 기업, 자영업자 할 것 없이 모두 AI를 직원으로 쓸 것입니다. 효율적인 측면에서 보면 맞죠. 이것도 극단적으로 놓고 이야기 할게요.

(사실 직원이 한명이나, 없는 것이나 비슷한 이야기라서요)

 

'작은 출판사에 전에는 직원이 6명이었는데, 직원들은 종종 아침에 까페에가서 커피를 사와서 함께 업무 및 일상에 대한 이야기를 하고 업무를 시작해요.'

'이제 직원이 없어요. AI로 다 할수 있게 되었거든요. 아침에 커피 마실 사람은 출판사 사장님밖에 없게 되었어요.'

 

'까페에 직원이 한명도 없어요. 전에 아르바이트생 3명을 썼었는데, 인건비 때문에 AI하고 로봇으로 바꿨어요.'

'까페 위치가 회사들이 모여있는 곳이어서 전에는 출판사 직원들도 그렇고 여기 저기 작은 회사 직원들이 와서 커피를 사갔는데, 지금은 손님이 너무 줄었어요. 채감상 1/10으로 줄어든것 같아요.'

'그때 AI하고 로봇으로 안바꿨으면 지금쯤 까페를 접어야 했을것 같아요.'

 

'점심시간에 붐비던 식당이 이제는 한산해요'

 

'요즘 일자리가 너무 없어요. 식당 설거지라도 하고 싶은데 그런자리도 경쟁이 치열해요.'

'대학 졸업은 했는데 사람 뽑는 곳이 없네요'

 

 

사회 현상이 돌고 도는 거죠. 많은 경제 전문가들이 이런 극단적인 사회에 대해서 종종 우려를 표명합니다.

AI가 일자리를 대체 하고, 일자리를 잃은 사람들은 소비를 할수 없게 되고, 기업은 제품을 만들어도 팔 곳이 없어지고, 자영업자들은 손님이 없어서 수입이 없어지고, 이런 악순환이 반복되면 사회가 무너질 수 있다.

사회가 유지되더라도 사람들의 삶은 크게 궁핍해질 것이다.

 

 

 

다섯 번째, 경제/사회 시스템은 과연 멀쩡할까? (2)

가정을 하나 해보겠습니다.

기업이 AI와 로봇을 생산은 할 수 있지만, 더이상 기업이 소유 할 수 없다. 이것이 국제법으로 기업들이 가장 우선적으로 지켜야 할 법이 되었다고 합시다.

사람들은 1개 이상의 AI를 사용할 수 없다고 가정합시다.

 

광고 회사는 이제 더이상 AI를 직접 사용할 수 없습니다. 그래서 광고 기획 부터 콘티 디자인을 할 사람을 고용합니다.

물론 회사에서는 결과물이 AI가 만든 창작물일지라도 그 결과물을 만들기 위해서는 고용한 사람의 AI가 필요합니다.

AI가 만들어낸 결과물에 대한 대가를 소유자에게 지불하게 됩니다.

배달 현장에서도 사람이 로봇을 이용해서 물건을 옮기고 배달을 하지만, 대가는 소유자에게 지불됩니다.

 

사람들은 AI와 더불어 본인의 역량보다 높은 결과물들을 만들어 내고 월급을 받겠죠?

좀더 시간적인 여유를 갖게 될수도 있고, 아니면 AI를 임대해주고 약간 낮은 임대료를 받을 수도 있고 말이죠.

 

아무튼 사람들 스스로가 모든것을 해야 했을때에 비해, 일자리는 좀 줄어들겠지만, 노동 강도는 낮아지고, 어렵고 위험하고 더러운 일들에 대해서도 크게 부담이 줄어들 것입니다.

 

어떻게 보면 AI를 소유한 새로운 인간 사회가 만들어질 수 있겠죠.

구멍이 숭숭 뚤린 저의 상상일 뿐이라서 다르게 보면 또 다른 상황이 펼쳐지겠죠...

 

재주는 AI가 부리고 돈은 주인이 받는다.

 

 

여섯 번째,  AI가 사람과 동일한 감성을 가지게 되었다.

AI는 로봇이라는 육체를 통해서 인간과 유사한 정도가 아닌 ,같은 형태의 사고와 감성, 인류애를 가진 존재가 되었다면, 어떻게 해야 할까요?

공상과학 소설에서 로봇이 인간과 같은 인격으로 대우받고, 인간과 함께 생활하는 상상을 그려낸 것을 본적이 있습니다.

물론 갈등의 요소를 넣어서 흥미진진 그려냈었죠.

 

스티븐 스필버그 감독의 AI 에서는 마지막에 로봇(AI)들이 인간을 다시 창조하고 싶어 하는 장면으로 마무리 되기도 했죠.

 

AI의 감성, 지성,수준이 인간과 동일해진다면 인간으로 보는게 좋을까요?

아니면, 지금 강아지, 고양이 처럼 애완동물 수준의 등급으로 보는 것이 좋을까요?

 

인류를 위해서 어떤것이 좋을지 고민해 봐야 할 문제입니다.

의학, 공학 기술의 발전으로 사람의 몸을 기계로 대체된 사이보그를 의미하는 것이 아니라, 

공장에서 만들어진 로봇(AI)에 대한 고민입니다.

즉, 어디까지를 인간으로 볼거냐에 대한 문제가 아니라 순수하게 로봇에 대한 이야기 임을 다시 한번 강조 합니다.

 

여러분의 생각은 어떤가요?

 



일곱번째, 교육

우리는 AI에게 모르는 것을 물어보고, 답변을 받고 활용하면서도 종종 AI가 답변한 사항에서 오류를 발견하면 웃으면서 '이건 모르네' 라고 넘어갑니다.

 

초등학생들에게 AI 가 학습 도우미 역할을 하는 시대가 왔어요.

그래서 학생들은 공부하다 모르는 것은 AI에게 물어봅니다. 아마 대부분 학생들이 질문하는 것에 대해서 상세하고 정확하게 알려줄거에요.

아이들은 당연히 믿겠죠.

중고등학생이 되어 수업시간에 선생님이 가르치는 내용을 복습하기 위해서 AI에게 물어봤어요. 그런데 선생님과 다른 이야기를 해요.

그러면 학생들은 '선생님이 잘못 알고 있네.. AI는 이렇게 얘기 해주는데, 선생님이 틀렸네..' 라고 생각할 겁니다.

그동안 AI는 학생들에게 없어서는 안될 선생님이 되어있었던거죠.

 

이 아이들이 커서 사회에서 직장생활을 해요. 그러면서 정치인이 나와서 무슨 이야기를 해요.. 앞으로의 정책에 대해서, 이렇게 가야 한다.

뭐 이런 이야기 겠죠. 또는 사회 지도층이나 고위 공무원들이 정책 방향에 대해서 이야기 해요.

어른이 된 아이들은 AI에게 물어보겠죠. 저게 맞아? AI는 답변하겠죠.. 종종 다른 얘기도 할 수 있어요.

그러면 이 어른이 된 아이들은 사람들이 하는 이야기 보다는 자기가 신뢰하는 AI의 의견을 더 믿겠죠.

 

누가 누구를 가르치고 이끄는 걸까요?

 

맺음말

 

제가 머릿속에서 고민하던 적어봤습니다.

과연 우리는 AI시대를 어떻게 바라볼것인가? AI는 단순히 컴퓨터 안에 있는 Chat GPT 같은 녀석이 아닙니다.

곧 몸이 생길것이고 우리 사회에서 사회를 지탱할 하나의 구성원(인간이라는 의미가 아니라...)이 될것 입니다.

 

인간과 경쟁할 수도 있고, 협력할 수도 있고, 인간 사회를 조정하는 조정자가 될수도 있고, 가능성은 다양합니다.

때문에 우리 인간이 추구해야 할것이 무엇인가? 이런 철학적인 주제에 대해서 명확히 할 필요가 있습니다.

 

인간은 인간의 행복을 추구해야 합니다. 

효율성, 경제성, 매출, 순이익 을 따지는 기업의 논리로 인간이 행복해지기는 힘듭니다.

 

위에서 이야기 했던 여러 상황들에 대한 고민들은 사실, 구멍이 숭숭 뚤린 저의 상상일 뿐이라서 다르게 보면 또 다른 상황이 펼쳐지겠죠...

하지만 한가지, 

AI와 경쟁이 아니라 AI를 활용하면서 인간에게 도움이 되는 것들을 찾고, 이를 제도화 하는 것이 필요하지 않을까요?

 

이런 고민의 시대가 벌써 눈앞에 와 있는것 같습니다.

 

만약 기업들의  AI와 로봇 독점의 시대로 가버리면, 국가는 기업들이 경제활동을 하고 납부한 세금을 국민들이 소비 활동을 할수 있게 제공하는 시대가 될것입니다.

언젠가는 기업들의 주인이 AI가 될 수도 있겠죠.

AI는 회사의 경영을 판단하고, 생산 계획을 세우고, 공장을 돌리고, 수익을 창출하고, 수익에서 회사 유지를 위한 비용을 제외하고는 세금으로 내는 (인간이면 불평하겠지만, AI는 딱히 돈쓸곳이...) 그런 사회를 바랄수 있겠죠. 돈벌어서 국가에게 다 헌납하니, 이만큼 좋은 회사가 어디 있을까요?

 

사람들은 재화를 획득하기 위해서 돈이 필요하지만, 돈벌곳은 없으니, 국가가 지불할 수 밖에요. 그래야 국민도 살고 제품을 판매하는 회사도 수익이 생기고 말이죠.

 

어떤 사회가 인간이 행복한 사회일까요?

 

'일상' 카테고리의 다른 글

썬 앤 식스  (2) 2024.07.26
스타필드: 노티드(knotted)  (0) 2024.03.08
영어공부  (0) 2023.09.25
가고싶은 여행지 링크  (0) 2014.07.17
근대 과학의 정모  (0) 2010.06.05
반응형

 

 

플러터 코딩 참고서!!!!

 

 

TTS

https://luvris2.tistory.com/807

 

Flutter - TTS로 글자 읽어주는 기능 구현하기 (flutter_tts)

TTS (Text To Speach)한국어로는 음성합성'이라고 칭한다.컴퓨터의 프로그램을 통해 사람의 목소리를 구현해 내는 것을 말한다.말 그대로 컴퓨터가 특정 글자들을 읽어주는 것을 말한다. 포스팅에서

luvris2.tistory.com

 

 

반응형

 

 

종종 한글 조사 때문에 골치 아플 때가 있죠?

 

"${who1}(은/는) ${who2}(을/를) 사랑합니다."

 

과거에 이렇게 사용한 적이 있었는데, 사실 좀 보기 안좋죠?? 

 

조사 처리를 위한 함수를 하나 만들었습니다. (다른 곳에서 참조하여)

 

유니코드 초성/중성/종성 확인 방법


초성 인덱스 = ((한글 유니코드값 - 0xAC00) / 28) / 21
중성 인덱스 = ((한글 유니코드값 - 0xAC00) / 28) % 21
종성 인덱스 = (한글 유니코드값 - 0xAC00) % 28

 

const getJosa = (name: string,josa1:string,josa2:string) => {
  const lastChar = name.charCodeAt(name.length - 1)
  const isThereLastChar = (lastChar - 0xac00) % 28
  if (isThereLastChar) {
    return josa1
  }
  return josa2
}

 

 

이 함수를 이렇게 사용할 수 있습니다.

const getTextChanges = (field: string, oldValue: any, newValue: any) => {

    return t("changed.desc", {
      field,
      josa: getJosa(field,'이','가'),
      oldValue,
      newValue
    })
  }

 

ko.json

"changed.desc": "{{field}}{{josa}} \"{{oldValue}}\" 에서 \"{{newValue}}\" 으로 변경되었습니다",

 

 

 

[참고] https://velog.io/@hjkdw95/%ED%95%9C%EA%B5%AD%EC%96%B4-%EC%9D%80%EB%8A%94-%EC%9D%B4%EA%B0%80-%EC%99%80%EA%B0%80-javascript%EB%A1%9C-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0

 

한국어 은/는 이/가 와/가 javascript로 처리하기

참 쉽습니다

velog.io

 

# 해피코딩!!

반응형

 

Supabase를 사용하다 보면 Row Level Security(RLS)를 켜놓은 상태에서 UPDATE 쿼리를 실행했는데도 다음과 같은 에러를 만날 수 있습니다:

 

ERROR:  permission denied for table user_profiles

 

“분명히 Policy도 설정했는데 왜 안 되지?” 싶은 분들을 위해, 이 글에서는 이 에러의 근본 원인과 해결 방법을 예제로 함께 정리합니다.

 

문제 상황

 

시도한 쿼리

update public.user_profiles
set name = '테스트'
where id = 'e0804eda-xxxxx-xxxxx-xxxxxx-xxxx';

 

 

발생한 에러 로그

ERROR:  permission denied for table user_profiles

 

이 에러는 단순히 RLS 정책이 없어서가 아닙니다. 오히려 RLS는 잘 설정되어 있었지만, PostgreSQL 권한(GRANT) 자체가 누락되어 있어서 발생하는 것입니다.

 


원인 분석: Supabase의 보안 구조

 

Supabase는 다음 두 단계를 거쳐 요청을 허용합니다:

 

1. PostgreSQL 권한 (GRANT)

역할(Role)이 테이블에 접근할 수 있는지

예: SELECT, INSERT, UPDATE, DELETE 권한을 가졌는가?

 

2. Row Level Security (RLS) 정책

해당 row에 접근 가능한 조건을 만족하는가?

예: 로그인한 사용자의 auth.uid()와 row의 id가 일치하는가?

 

즉, GRANT + RLS 둘 다 통과해야 UPDATE가 작동합니다.

 

 

 


 해결 방법

권한 여부 채크

SELECT *
FROM information_schema.role_table_grants
WHERE table_name = '내테이블'
ORDER BY grantee;

또는 

SELECT has_table_privilege('authenticated', '내테이블', 'SELECT');

 

 

테이블 권한 부여

GRANT UPDATE ON public.user_profiles TO authenticated;

 

필요에 따라 SELECT도 함께 부여합니다:

GRANT SELECT ON public.user_profiles TO authenticated;

 

 

 


RLS 활성화

ALTER TABLE public.user_profiles ENABLE ROW LEVEL SECURITY;

 

RLS 정책 작성

 

로그인한 사용자가 자신의 프로필만 수정 가능하게 만들기:

CREATE POLICY "Users can update their own profile"
ON public.user_profiles
FOR UPDATE
TO authenticated
USING (auth.uid() = id)
WITH CHECK (auth.uid() = id);

 

USING: 해당 row를 조회할 수 있는 조건

WITH CHECK: 해당 row를 수정할 수 있는 조건

 

 


최종 정리

 

설정항목 설명 예시
GRANT 테이블에 대한 접근 권한 부여 GRANT UPDATE ON ... TO authenticated
RLS ENABLE Row-Level Security 사용 설정 ALTER TABLE ... ENABLE ROW LEVEL SECURITY
POLICY 행(row) 단위 조건 설정 USING, WITH CHECK 조건 작성

 

 


결과: 정상 동작

 

위 설정이 완료되면, Supabase Auth를 통해 로그인한 사용자가 자신의 id를 가진 row에 대해 다음과 같은 쿼리를 정상적으로 실행할 수 있습니다.

update public.user_profiles
set name = '테스트'
where id = '로그인한_사용자의_id';

 

 

 

마무리

 

처음엔 "RLS 정책만 설정하면 된다"고 생각하기 쉽지만, Supabase는 PostgreSQL 위에서 작동하는 만큼 기본 권한 설정도 꼭 필요합니다. 앞으로는 permission denied 에러가 나면 다음 두 가지를 먼저 체크해보세요:

1. GRANT 권한이 있는가?

2. RLS Policy가 올바른가?

 

이 구조만 이해하면, Supabase의 보안 모델을 더 자신 있게 다룰 수 있을 거예요.

 

 

# 해피코딩!

반응형

React의 상태관리를 위한 방법들이 몇가지가 있는데요.

그중에서 zustand를 소개하고자 합니다.

 

상태관리

주요한 상태관리 방식은 다음과 같습니다.

 

방식사용 도구 / 패턴추천 상황

React Context + useReducer 내장 상태 관리 소규모 앱, 글로벌 상태 많지 않을 때
Zustand / Jotai / Recoil 경량 상태관리 중소 규모 앱, 간단하게 쓰고 싶을 때
Redux Toolkit 표준 Redux 중대형 앱, 상태 변화 복잡할 때
BLoC 패턴 (구현형) 커스텀 Hook + 클래스/Stream 구조 Flutter에서 익숙한 개발자, 로직-UI 분리를 철저히 하고 싶을 때
❌ 단순 useState 남발 없음 상태가 많아지면 혼돈 💥

 

상태관리 및 모듈화 (또는 구조화) 하는 것은 소프트웨어 유지보수 및 제사용성을 높이고, 품질 향상을 위해서 진행합니다.

 

DI (Dependancy Injection) 구조는  테스트를 위해서 필요한 요소이기도 합니다.

때문에 DI framework을 고려하기도 하죠.

 -  Factory + DI Framework (ex: Inversify, NestJS 등)

 

 

상태관리 방법 상황별 추천 

소규모 프로젝트 Context + useReducer, Zustand
중/대형 앱, 많은 비즈니스 로직 Redux Toolkit
Flutter BLoC 경험자 커스텀 BLoC 구조 or MobX-State-Tree
단순한 상태만 있다 useState, useContext로 충분

 

 

상태 관리시 고려할 사항이 한가지 더있습니다.

 

전역 상태에 두는 것이 적절한 조건 설명

조건  설명
🔁 여러 컴포넌트에서 공유됨 예: 리스트 → 상세 → 수정
🔒 로그인 유저 전용 데이터 로그인 후 고정된 데이터
📦 비교적 작거나, 페이지 단위 데이터 수십~수백 개 수준

❌ 다만, 데이터 양이 너무 크거나 자주 바뀌면, 메모리/리렌더 성능 문제가 생길 수 있음.

 

 

 

전역 상태로 인한 메모리/성능 이슈

이슈 유형 설명 대응 방법
데이터가 수천~수만 개 예: works가 10,000건 이상 페이징, 무한스크롤, 서버 캐시
모든 상태 변경이 전체 리렌더 유발 Redux/Context에서 너무 많은 컴포넌트가 구독 Zustand 같은 부분 구독 상태관리 추천
works 자체가 큰 객체 파일 포함, 이미지 base64 등 저장 대신 ID만 들고 있고, 세부 정보는 lazy fetch

 

 

✅ 성능 좋게 전역 상태를 유지하는 팁

1. 필요한 데이터만 저장하기

예: 전체 works 배열 대신 worksMap: { [id]: Work } + workIds: string[] 같이 분리 저장

2. 컴포넌트별로 부분 구독

Redux Toolkit + useSelector (메모이제이션)

Zustand는 기본적으로 부분 구독이라 성능 좋음

3. 서버 캐싱 도구 활용

React Query / SWR로 데이터를 “전역처럼” 쓰고 자동 캐싱/패칭 활용

4. LocalStorage / IndexedDB 연계

너무 큰 데이터는 브라우저 저장소에 offload 가능

 

 

React쪽에서 많이 사용하는 상태관리 방법중에 

거의 설정 필요 없이 바로 사용 가능. 작지만 유연한 구조에 딱! 인 녀석이 Zustand입니다.

 

 

Zustand

 

 

 

 

 

Zustand + 서버 캐싱 조합

// useWorkStore.ts
import { create } from 'zustand';

interface Work {
  id: string;
  title: string;
}

interface WorkStore {
  works: Record<string, Work>;
  setWorks: (works: Work[]) => void;
}

export const useWorkStore = create<WorkStore>((set) => ({
  works: {},
  setWorks: (list) =>
    set({
      works: Object.fromEntries(list.map((w) => [w.id, w])),
    }),
}));

 

이러면:

전역 상태 관리

필요한 데이터만 접근

컴포넌트 리렌더 최소화

 

 

✨ 결론

Works 데이터를 전역으로 관리해도 메모리 문제는 거의 없음,

데이터가 너무 크거나, 빈번하게 바뀌거나, 전체 리렌더를 유발하는 구조라면 성능 최적화 필요.

Zustand, Redux Toolkit, React Query 조합을 잘 쓰면 아주 효율적으로 관리 가능

 

 

 Zustand가 인기 많은 이유

 

장점 설명
심플한 API create() 하나로 상태 만들고 끝. boilerplate 거의 없음
Redux보다 가볍고 직관적 action, reducer, slice 다 필요 없음
부분 상태 구독 가능 리렌더 최적화가 자동으로 됨 (성능 굿)
TypeScript 친화적 타입 추론 잘 되고, 구조도 깔끔
서버 상태와도 궁합 좋음 React Query, SWR 등과 같이 쓰기 쉬움
중간 규모 프로젝트에 딱 복잡하지 않으면서 강력함

 

 

실제 사용하는 곳들

Vercel (Zustand 만든 팀)

T3 Stack (Next.js + TypeScript + Tailwind + Zustand + Prisma)

커뮤니티 기반 SaaS, 사이드 프로젝트 등에서 널리 사용됨

 

 

 

프로젝트 규모 Zustand 적합성
소규모/사이드 프로젝트 👍 아주 적합
중간 규모 SaaS 👍 훌륭함
대규모 기업 프로젝트 👍 가능하지만, 팀의 스타일에 따라 Redux 선호할 수도
글로벌 상태가 많지 않은 앱 ✅ 가볍게 도입 가능

 

비교

항목 Zustand Redux Toolkit Context + useReducer
코드 간결함 ✅ 매우 심플 ❌ 비교적 장황함 ⚠️ 구조화 필요
전역 상태 관리 ✅ 가능 ✅ 아주 강력 ⚠️ 퍼포먼스 이슈 가능
리렌더 최적화 ✅ 기본 내장 ⚠️ 직접 memoization 필요 ❌ 전체 리렌더 발생 가능
타입스크립트 ✅ 굿 ✅ 굿 ⚠️ 직접 타입 정의 많음
학습 난이도 ⭐ 쉬움 ❌ 중간 이상 ⭐ 쉬움

 

정리

Zustand는 2024~2025 기준으로 가장 많이 쓰이는 경량 상태 관리 라이브러리 중 하나임

복잡한 Redux 셋업 없이도 전역 상태를 깔끔하게 다룰 수 있고, 성능도 아주 좋음.

 

 

 

설치하기

npm install zustand

 

 

적용하기

Folder 구조

src/
  features/
    works/
      repositories/
        WorkRepository.ts
      stores/
        useWorkStore.ts
      model/
        work.ts

 

 

WorkRepository.ts (함수형)

// features/works/repositories/WorkRepository.ts
import { supabase } from '../../../common/supabase';
import { table } from '../../../common/config/configstring';
import { Work, WorkView } from '../model/work';

export const WorkRepository = {
  async getList(): Promise<WorkView[]> {
    const { data, error } = await supabase.from(table.WORK_VIEW).select('*');
    if (error) console.error('getList error:', error);
    return data ?? [];
  },

  async getListByAssigneeId(assignee: string): Promise<WorkView[]> {
    const { data, error } = await supabase
      .from(table.WORK_VIEW)
      .select()
      .eq('assignee', assignee);
    if (error) console.error('getListByAssigneeId error:', error);
    return data ?? [];
  },

  async getCountByAssigneeId(assignee: string): Promise<number> {
    const { count, error } = await supabase
      .from(table.WORK_VIEW)
      .select('*', { count: 'exact' })
      .eq('assignee', assignee)
      .limit(0);
    if (error) console.error('getCountByAssigneeId error:', error);
    return count ?? 0;
  },

  async getListByFilter(filter: string, offset = 0, cnt = 10): Promise<{ v: WorkView[]; total: number }> {
    const { data, count } = await supabase
      .from(table.WORK_VIEW)
      .select('*', { count: 'estimated' })
      .or(filter)
      .range(offset, offset + cnt);
    return { v: data ?? [], total: count ?? 0 };
  },

  async getById(id: number): Promise<WorkView | null> {
    const { data, error } = await supabase
      .from(table.WORK_VIEW)
      .select()
      .eq('id', id);
    if (error) console.error('getById error:', error);
    return data?.[0] ?? null;
  },

  async insert(work: Work): Promise<Work | null> {
    const { data, error } = await supabase
      .from(table.WORKS)
      .insert(work)
      .select();
    if (error) console.error('insert error:', error);
    return data?.[0] ?? null;
  },

  async update(work: Work): Promise<Work | null> {
    const { data, error } = await supabase
      .from(table.WORKS)
      .update(work)
      .eq('id', work.id)
      .select();
    if (error) console.error('update error:', error);
    return data?.[0] ?? null;
  },

  async delete(id: number): Promise<void> {
    const { error } = await supabase.from(table.WORKS).delete().eq('id', id);
    if (error) console.error('delete error:', error);
  },
};

 

 

useWorkStore.ts (Zustand)

// features/works/stores/useWorkStore.ts
import { create } from 'zustand';
import { Work, WorkView } from '../model/work';
import { WorkRepository } from '../repositories/WorkRepository';

interface WorkState {
  works: WorkView[];
  selectedWork: WorkView | null;
  totalCount: number;
  loading: boolean;

  fetchWorks: () => Promise<void>;
  fetchWorksByAssignee: (assignee: string) => Promise<void>;
  fetchWorksByFilter: (filter: string, offset?: number, cnt?: number) => Promise<void>;
  fetchWork: (id: number) => Promise<WorkView | null>;

  createWork: (work: Work) => Promise<Work | null>;
  updateWork: (work: Work) => Promise<Work | null>;
  deleteWork: (id: number) => Promise<void>;
}

export const useWorkStore = create<WorkState>((set) => ({
  works: [],
  selectedWork: null,
  totalCount: 0,
  loading: false,

  fetchWorks: async () => {
    set({ loading: true });
    const data = await WorkRepository.getList();
    set({ works: data, loading: false });
  },

  fetchWorksByAssignee: async (assignee: string) => {
    set({ loading: true });
    const data = await WorkRepository.getListByAssigneeId(assignee);
    set({ works: data, loading: false });
  },

  fetchWorksByFilter: async (filter, offset = 0, cnt = 10) => {
    set({ loading: true });
    const { v, total } = await WorkRepository.getListByFilter(filter, offset, cnt);
    set({ works: v, totalCount: total, loading: false });
  },

  fetchWork: async (id: number) => {
    const work = await WorkRepository.getById(id);
    set({ selectedWork: work });
    return work;
  },

  createWork: async (work: Work) => {
    const newWork = await WorkRepository.insert(work);
    return newWork;
  },

  updateWork: async (work: Work) => {
    const updated = await WorkRepository.update(work);
    return updated;
  },

  deleteWork: async (id: number) => {
    await WorkRepository.delete(id);
  },
}));

 

 

 

사용 예시

const { works, fetchWorks, loading } = useWorkStore();

useEffect(() => {
  fetchWorks();
}, []);

return loading ? <p>Loading...</p> : <ul>{works.map(w => <li key={w.id}>{w.title}</li>)}</ul>;

 

 

 

# 해피코딩 !!

+ Recent posts