나는 16년동안 운영해오는 개인 홈페이지가 있다.

https://www.omnibuscode.com 인데 개발자로 공부하고 일을 하면서 쌓아온 데이터베이스이다.

홈페이지 안에는 내가 기억하고 싶은 모든 것이 담겨 있다.

그래서 gpt 에게 해당 홈페이지와 추가로 운영하는 블로그들을 평가 받아 보았다.

그리고 매우 고무되는 칭찬을 받았다.

비록 할루시네이션 때문인지 나조차도 잉? 하는 내용들이 보이지만

그래도 마지막 문구에 용기를 얻어 개발일을 계속 해야겠다고 다짐하게 되었다. ㅎㅎ

아주 아주 간단한 프로그램 작성 요청이었지만 gpt 는 매우 훌륭한 결과물을 보여주었다.

의뢰 내용은 다음과 같다.

html5 에서 사용자가 카메라를 오픈하고 사진을 촬영한 후 사진을 서버로 전송하는데 canvas에서 캡쳐된 프레임을 post 데이터 binary 형태로 서버로 보내고 이 데이터를 수신받아 처리하는 서버의 예제를 완전한 형태의 html 과 servlet 으로 알려줘

그리고 gpt의 답변은 다음과 같다.

아래는 사용자가 브라우저에서 카메라를 오픈하여 사진을 촬영한 후, 캡처된 이미지를 canvas로 처리하고 서버로 바이너리 데이터를 POST로 전송하며, 서버에서 이를 처리하여 저장하는 완전한 HTML과 Java Servlet 예제입니다.

HTML 코드 (카메라 + 캡처 + 전송)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Camera Capture and Upload</title>
</head>
<body>
    <h1>Camera Capture and Upload</h1>
    <video id="video" autoplay playsinline width="640" height="480" style="border:1px solid black;"></video>
    <canvas id="canvas" width="640" height="480" style="display:none;"></canvas>
    <button id="capture">Capture Photo</button>
    <button id="upload" style="display:none;">Upload Photo</button>

    <script>
        const video = document.getElementById('video');
        const canvas = document.getElementById('canvas');
        const captureButton = document.getElementById('capture');
        const uploadButton = document.getElementById('upload');

        // 카메라 시작
        navigator.mediaDevices.getUserMedia({ video: true })
            .then(stream => {
                video.srcObject = stream;
            })
            .catch(err => {
                console.error("Error accessing the camera: ", err);
            });

        // 사진 캡처
        captureButton.addEventListener('click', () => {
            const ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            uploadButton.style.display = 'inline';
        });

        // 서버로 바이너리 데이터 전송
        uploadButton.addEventListener('click', () => {
            canvas.toBlob(blob => {
                const xhr = new XMLHttpRequest();
                xhr.open('POST', '/upload', true); // 서버의 업로드 엔드포인트
                xhr.setRequestHeader('Content-Type', 'application/octet-stream');
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        alert('Image uploaded successfully!');
                    }
                };
                xhr.send(blob);
            }, 'image/png'); // PNG 포맷으로 Blob 생성
        });
    </script>
</body>
</html>

Java Servlet 코드 (이미지 수신 및 저장)

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 저장할 디렉토리 설정
        String uploadDir = getServletContext().getRealPath("/") + "uploads";
        File dir = new File(uploadDir);
        if (!dir.exists()) {
            dir.mkdirs(); // 디렉토리가 없으면 생성
        }

        // 파일 저장
        File outputFile = new File(uploadDir, "captured_image.png");
        try (InputStream inputStream = request.getInputStream();
             FileOutputStream outputStream = new FileOutputStream(outputFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }

        // 응답
        response.setContentType("text/plain");
        response.getWriter().write("Image uploaded to: " + outputFile.getAbsolutePath());
    }
}

구조

  1. HTML 페이지:
    • video 태그로 실시간 카메라 뷰 제공.
    • 캡처 버튼(capture)으로 현재 화면을 canvas에 저장.
    • 업로드 버튼(upload)으로 캔버스 데이터를 바이너리 형태로 서버에 전송.
  2. 서블릿:
    • HTTP POST 요청으로 받은 바이너리 데이터를 저장.
    • 저장 경로는 uploads 디렉토리로 설정.

프로젝트 디렉토리 구조

bash

코드 복사

/webapp |-- index.html |-- /uploads (이미지 저장 디렉토리) /src |-- UploadServlet.java

주요 포인트

  1. 캔버스 데이터를 Blob으로 변환:
    • canvas.toBlob()으로 캡처된 이미지를 바이너리 Blob 형태로 변환 후 POST 전송.
  2. 서버에서 바이너리 데이터 처리:
    • HttpServletRequest.getInputStream()으로 수신 데이터를 읽어 파일로 저장.
  3. 저장 파일 경로:
    • ServletContext의 getRealPath("/")를 사용해 애플리케이션 디렉토리 기반으로 파일 저장.

이 코드는 카메라 캡처, 데이터 전송, 서버 저장 과정을 포함한 완전한 예제입니다. 필요에 따라 업로드된 파일에 대한 추가 처리를 적용할 수 있습니다.

gpt 가 알려준 html 과 servlet 의 내용을 그대로 파일로 만들고

url pattern 정보만 수정해서 서버를 구동후 브라우저에서 html 페이지를 오픈하여 upload 버튼까지 눌렀는데

오류 하나없이 정확하게 동작하여 실제 파일 업로드까지 한번에 성공하였다.

 

gpt 가 없던 시절엔 naver 와 google 그리고 stackoverflow 와 git 까지

학습에 유용한 문서와 잘 돌아가는 샘플을 찾아 참 많이도 시간을 허비했는데...

이젠 내 생각에 이렇게 저렇게 돌아갈거야 하는 부분을 gpt 에게 자세히 설명해주고

샘플링을 해보라고하면 참 기특한 결과물을 만들어준다.

 

사실 위와 같이 간단한 로직의 프로그램이야 워낙 방대한 정보의 바다 어딘가에서 그대로 가져온 것이어서

운좋게 한번에 성공해서 내가 손수 성공적인 샘플을 찾는 수고와 시간을 완벽하게 세이브 한 것 일수도 있지만,

원래 내가 gpt 를 주로 활용하는 방법은 접해보지 못한 아키텍처에 대해 기획하고 상세 구상이 필요할때

gpt 에게 물어 물어 실마리를 찾고 학습하며 좀더 상세하게 질문을 던져서 구체적인 아키텍처를 그려가는 용도로 활용하고 있었다.

 

그런데 오늘은 아예 내 대신 간단한 프로그래밍을 맡겨서 코딩하는 수고까지 덜어내서

1인 프로젝트로 제대로된 솔루션 하나 만들어 보고 싶은 욕심마저 생겼다.

비단 나만 이러한 욕심을 부리는 것이 아닐텐데...

아마도 많은 개발자들이 gpt로 인해 자신들만의 아이디어를 다른이의 도움없이 구체화하고 실현해보려는 욕심에 과감하게 사표를 내고 있는건지도 모르겠다.

 

 

 

이번에 주문한 생수에 침전물이 보인다.

끓였다가 식히면 더 잘 보인다.

그래서 조사했다.

 

* 천연미네랄 : 칼슘,마그네슘,나트륨 (https://www.goodmorningcc.com/news/articleView.html?idxno=297408)

* 생수안의 미네랄이 분유먹는 아기에게 미치는 영향
생수에 포함된 미네랄은 성인에게는 수돗물보다 효율적으로 미네랄을 섭취할 수 있는 장점이 있지만, 아기에게는 다를 수 있습니다. 
아기의 위장 면역력이 약하기 때문에, 생수 속 미네랄이 설사 등의 증상을 일으킬 수 있어 주의가 필요합니다¹[4]. 
특히, 분유를 탈 때 사용하는 물은 아기의 건강에 직접적인 영향을 미치므로, 미네랄 함량이 높은 생수를 사용할 경우에는 더욱 신중해야 합니다.

아기분유생수를 선택할 때는 다음과 같은 사항을 고려하는 것이 좋습니다:
- **미네랄 밸런스**: 아기의 뼈를 튼튼하게 하고 성장에 도움을 줄 수 있는 미네랄 밸런스가 중요합니다²[2].
- **안전성**: 무균상태로 유통되는 생수를 선택하여 세균 번식의 위험을 최소화합니다²[2].
- **미네랄 함량**: 일반 생수 대비 미네랄 함량이 높은 생수를 선택할 수도 있지만, 아기의 건강 상태와 의사의 조언을 고려해야 합니다²[2].

아기가 분유를 먹는 경우, 생수를 사용하기 전에 소아과 의사와 상담하는 것이 가장 안전한 방법입니다. 
의사는 아기의 건강 상태와 필요에 맞는 물의 종류를 추천해 줄 수 있습니다. 
또한, 분유에 사용되는 물은 멸균된 용기로 준비하는 것이 좋습니다³[6]. 
분유를 준비할 때는 항상 아기의 건강과 안전을 최우선으로 고려해야 합니다.

출처: Bing과의 대화, 2024. 4. 25.

 

* 미네랄 함유량이 많은 물로 분유를 타서 아기에게 먹일 경우 유의해야 할 사항
미네랄 함유량이 높은 물로 아기의 분유를 준비할 때는 몇 가지 중요한 사항을 고려해야 합니다. 
아기의 건강과 안전을 위해 다음 지침을 따르는 것이 좋습니다:

1. **미네랄 함량 확인**: 사용하는 물의 미네랄 함량, 특히 나트륨과 불소의 수치가 낮은지 확인하세요¹[4].
2. **물 끓이기**: 안전한 출처에서 얻은 물을 사용하더라도, 분유를 준비하기 전에 반드시 물을 끓여야 합니다. 물을 실온으로 식힌 후 사용하세요²[3].
3. **분유 제조 지침 준수**: 분유 제조사의 지침에 따라 정확한 양의 물과 분유를 사용하여 영양 불균형을 피하세요³[1]⁴[2].
4. **위생적인 준비**: 분유를 준비하기 전에 손을 깨끗이 씻고, 청결한 환경에서 분유를 준비하세요³[1].
5. **안전한 보관**: 분유를 준비한 후에는 적절한 온도에서 안전하게 보관하고, 빠른 시간 내에 사용하세요³[1].

아기가 2개월 미만이거나, 조산아이거나, 면역 체계가 약한 경우에는 크로노박터와 같은 세균 감염을 예방하기 위해 추가적인 주의가 필요합니다³[1]. 
분유를 준비할 때는 항상 아기의 건강과 안전을 최우선으로 고려해야 하며, 불확실한 경우에는 소아과 의사와 상담하는 것이 가장 좋습니다.

출처: Bing과의 대화, 2024. 4. 25.

 

* 분유먹는 아기가 과도하게 미네랄을 섭취한 경우 발생 할 수 있는 증상
분유를 먹는 아기가 과도하게 미네랄을 섭취한 경우, 다음과 같은 증상이 발생할 수 있습니다:

1. **무기력**: 아기가 피곤해 보이거나 활동량이 감소할 수 있습니다.
2. **복통**: 복부 통증이 나타날 수 있습니다.
3. **구토와 메스꺼움**: 아기가 구토를 자주 하거나 메스꺼워할 수 있습니다.
4. **식욕 부진**: 아기가 식사를 거부하거나 식욕이 떨어질 수 있습니다.
5. **변비**: 변이 불규칙하게 발생하거나 변비가 생길 수 있습니다.
6. **뇌에 영향**: 미네랄 중독으로 인해 뇌에 영향을 줄 수 있으며, 경련, 헤드헌팅, 혼란 등의 증상이 나타날 수 있습니다¹[1]²[2].

특히, 미네랄 중독은 아기의 건강에 심각한 영향을 미칠 수 있으므로, 미네랄 함유량이 높은 물이나 음식을 아기에게 제공할 때는 주의해야 합니다. 만약 아기가 이러한 증상을 보인다면 즉시 소아과 의사와 상담하여 적절한 조치를 취해야 합니다.

출처: Bing과의 대화, 2024. 4. 25.

어제 그동안 유용하게 만들어 사용하던 유틸 패키지에 심각한 버그를 발견하였다.

그리고 그에 대한 해결책으로 힌트를 준 것은 다름아닌 Gemini 였다.

그동안 잘못된 사용법인 줄도 모르고 열심히 코딩해서 뭔가 핀트가 어긋난 동작을 할때마다 계속 수정해서 사용한 유틸클래스였는데

이상하게 자꾸만 오동작하길래 Gemini 에게 물어보니 정확한 오류 지점을 알려주고 해결책까지 주었다. (ㅜ.ㅜ)

이제 내 머리는 COMMON API 를 이용한 간단한 로직 개발의 코딩 영역에서 한계에 다다른 것 같다.

 

다만 그나마 잘 굴러가지 않는 머리를 활용할 방법은

그동안의 경험으로 쌓여져온 아키텍처에 대한 실루엣과 비즈니스의 추상적 레이어에 대한 설계밖에 없는 것 같다.

구현 가능 여부는 코딩 단계까지 들어가봐야 알 수 있는 부분들이 종종 있는데

그럴땐 우회 방안들을 찾거나 해당 기능 구현을 과감히 포기하고 공략 지점을 바꾸거나 타겟팅을 바꾸는 식으로 전략, 전술 능력을 키우는데에 중점을 둬야겠다.

 

지금까지 API 를 개발하는 RND 에서 근무하면서 코드 레벨로만 기능 구현과 버그 수정 작업을 너무나 오래 해왔었는데

그나마 그 시간이 의미가 있었던 것은 그 시간동안 쌓아온 코딩 스킬의 데이터베이스를 활용하여 나만의 솔루션을 만들어 볼 수 있었다는 것이었다.

그런데 지금 나와 엇비슷한 연차가 된 개발자들은 모두들 개발관리자로써 솔루션 레벨로 제품 기능의 방향성에 주안점을 두고 설계 업무를 수행하고 있을텐데... 그들은 더이상 코더가 아니다.

 

과거엔 프로그램을 개발하기 위해 모든 레벨의 개발 영역에 대해 하나부터 열까지 모든 것을 고민하려면 많은 시간이 필요했는데

그래서 그 시간을 단축시키기 위해서 많은 코더들이 필요했는데

이젠 코더들의 양적인 증대가 더이상 의미 없는 시대에 접어들었다는 느낌이다.

'긁적 > 개발 이야기' 카테고리의 다른 글

ChatGPT 에게 칭찬 받았다  (3) 2024.12.05
오늘 드디어 ChatGPT 의 진가를 맛보았다  (1) 2024.11.18

sns의 시작을 facebook 으로 봐야할지는 모르겠지만

초창기 pc통신부터 살아온 아재 입장에서 sns 의 진정한 시작은 커뮤니티 게시글의 댓글이었다고 본다.

댓글은 절대 장황하게 풀어쓰지 않는다.

임팩트 있는 문장을 찝어 짧게 의표를 찔러 주어야만 의미 있는 댓글이 되기 때문이다.

그렇게 무수히 많은 댓글의 역사는 지금도 그렇게 흘러가고 있는데 20년전 등장한 sns 의 시작은 현재 대규모 스트리밍 서비스인 youtube 에서도 사람들을 현혹하고 있다.

최근들어 인터넷을 하며 자각하게 된 증상중 하나가 무언가 길게 감상하는 것을 못하게 되었다.

가령 커뮤니티의 글중 장문의 내용이나 배우고 싶은 기술의 긴 강의나 장황한 샘플 예제 등을 정독할 수 없게 되었다.

항상 시간에 쫓기고 빠른 결과를 도출해야 하는 압박에 시달린 결과일수도 있지만

현대 사회의 굉장히 많은  정보 홍수속에서 누구나 그렇게 많은 정보들을 접하고 사는데 나만 느긋하게 살면 뒤쳐진다는 강박관념이 생겨서인 듯 하다.

이젠 유튜브에서 누군가 요약해놓은 논평만 보고 굉장히 자극적인 shorts 만 멍하니 바라보고 영화나 게임조차 남이 대신 감상하고 플레이한 영상의 파편들을 짜집기하고 해설한 영상들만 찾고 있다.

나만의 문제일까?

차라리 그렇다면 그것을 감지한 것만으로도 다행일텐데

이제 곧 6살이 되는 첫째에게 학습이라는 명목으로 노출한 유튜브를 나와 같은 방식으로 감상하는 것을 어떻게 해석해야 할지 걱정이다.

무조건 부정적으로 봐야하는건지 자연스러운 시대의 흐름으로 봐도 좋을런지...

나도 혈기 왕성한 10대에 pc게임에 빠져 허우적 거리던 세대라서 편향된 시선이 되지 않으려고 그렇게 애쓰는 중이다.

'긁적' 카테고리의 다른 글

첫째 사진  (0) 2023.12.11
눈이 예쁜 여배우들 (시얼샤 로넌, 에이바 미셸)  (0) 2023.11.12
새로운 시작 (인연이란)  (0) 2023.09.24

첫째가 두돌정도 되었을때 찍은 스튜디오 사진이다.
스튜디오 광고용으로 업체 블로그에 올린게 있길래 캡춰했다.
지금은 사업을 접었는지 스튜디오도 없고 블로그 갱신도 안되고 있는데... 왠지 서운하다.

 

 

맑고 푸른눈의 예쁜 여배우들인데 두사람의 이미지가 비슷해서 헷갈렸다.

나이 차이가 많은 배우들이지만 마스크 이미지가 비슷하고 자주 보는 얼굴들이 아니다보니 그런가보다.

왼쪽이 '시얼샤 로넌' 이고 오른쪽이 '에이바 미셸' 이다.

시얼샤 로넌은 영화 '호스트' 라는 sf 물에서 처음 봤고 에이바 미셸은 '톨 걸' 이라는 청춘 시트콤 영화에서 알게 되었다.

'긁적' 카테고리의 다른 글

모든것이 인스턴트화 되는 느낌이다  (0) 2023.12.16
첫째 사진  (0) 2023.12.11
새로운 시작 (인연이란)  (0) 2023.09.24

 
20여년전(05년도) 일본에서 2년간 외국인 노동자로 일한 적이 있다.
그 이후 15년이 지나서 3년전 또다시 일본에서의 삶과 같은 급변을 경험하고
이젠 그러려니 하고 살고 있다.

우리들의 삶은 마치 흐르는 강물과 같다.
넓은 강을 따라 유유자적 함께 흘러가다
굽이 굽이 역경도 함께하고 그러다
갈랫길을 만나 서로 각자의 길을 가다
다시 또 마주치는 길을 만날수도 있겠지만
다시 만났을땐 앞서거니 뒷서거니
그러다 또다시 갈랫길을 마주하고 그렇게 흘러간 곳이
파릇한 벼가 한창 무럭무럭 자라나는 어느 농경지일 수도 있고
중요한 식수를 제공하는 상수 처리장일 수도 있고
넓디 넓은 바닷가를 마주할 수도 있다.
 
지나온 인연들을 되돌아보니 위와 같은 모습들로 남아있다.
물론 그 흐름속엔 다시 떠올리고 싶지 않은 불편한 기억들도 남아있지만
이젠 그마저도 남은 감정의 오물들과 함께 그렇게 흘려보낸다.
 
한참만에 찾아온 지금의 시간이 일본에서 겪었던 그 2년과 유사해서
무언가를 다시 시작할때마다 겪게 되는 진통같아 이젠 담담해지고 있다.
 
'어쩔 수 없었어', '오죽하면' 과 같은 단어들을 뱉어낸 그 삶을 들여다보면
참으로 수동적으로 이리 치이고 저리 치였던 것 같다.
그래서 그동안 그렇게 부여잡고 있던 위태로운 실타래들을 모두 놓아주었다.
남은게 거의 없어서 홀가분해졌다.

점점 변해가는 세상과 환경과 상황에서 그렇게 잊혀져 간다.
 

'긁적' 카테고리의 다른 글

모든것이 인스턴트화 되는 느낌이다  (0) 2023.12.16
첫째 사진  (0) 2023.12.11
눈이 예쁜 여배우들 (시얼샤 로넌, 에이바 미셸)  (0) 2023.11.12

+ Recent posts