레이블이 computer인 게시물을 표시합니다. 모든 게시물 표시
레이블이 computer인 게시물을 표시합니다. 모든 게시물 표시

[컴] chrome 에서 ctrl+tab 을 ’최신탭으로 이동’으로 변경

크롬에서 창바꾸기 / firefox 처럼 switch windows / switch tabs

chrome 에서 ctrl+tab 을 ’최신탭으로 이동’으로 변경

QuicKey 라는 extension 이 이 기능을 제공한다.

아래 링크로 가면, 크롬의 ‘키보드 단축키’(Keyboard shortcuts)에서 Ctrl+Tab에 대한 설정을 어떻게 하는 지 알려준다. 글을 보면 javascript 를 이용해서 한다.

chrome.developerPrivate.updateExtensionCommand({
    extensionId: "ldlghkoiihaelfnggonhjnfiabmaficg",
    commandName: "010-open-popup-window",
    keybinding: "Ctrl+Tab"
});

참고로 이전의 ctrl + tab 으로 tab 을 이동하는 것은 ctrl + page up, ctrl + page down 을 이용하면 된다.

[컴] Windows11 에서 Dev Drive 설정

window 11 데브 드라이브 / 개발자 드라이브 / windows 11 /

Windows11 에서 Dev Drive 설정

prerequisites

  • Windows 11, 빌드 #10.0.22621.2338 이상
  • 16GB 메모리 권장(최소 8GB)
  • 최소 50GB의 여유 디스크 공간

disk 필요

기존의 할당되어 있지 않은(unallocated) disk 를 사용하거나, 새롭게 unallocated disk 를 생성해야 한다.

disk 를 생성하는데는 2가지 방법이 있다.

  1. VHD 를 만들기
  2. 기존 volume의 size를 줄여서 새로운 disk 를 생성

여기서는 VHD 만들기를 사용한다. 가상 disk 를 생성하는 방법이다.

절차

  1. diskmgmt.msc : 디스크관리 메뉴로 들어간다.
  2. ‘동작 -> VHD 만들기’
  3. ‘위치’, ‘크기’, ‘VHDX 선택’, ’동적 확장’을 선택 ( screenshots 참고)
    • 크기는 최소 50GB 이상으로 하자.
  4. disk 초기화 : 파티션 형식은 GPT ( screenshots 참고)
  5. volume 생성 : ( screenshots 참고)
    • 포맷은 하지 않는다.
    • 볼륨생성하면 drive 문자를 할당하게 된다. 여기서는 e: 에 할당한다.
  6. cmd 창에서 Format e: /DevDrv /Q

screenshots

가상하드디스크 생성
disk 초기화-1
disk 초기화-2
volume생성-1
volume생성-2

dev drive 이용

dev drive 에는

  • 소스 코드 저장소(repository) 및 프로젝트 파일
  • 패키지 캐시
  • 빌드 결과물과 중간 파일, 즉, 빌드를 여기서 하면 된다.

dev drive는 어떻게 동작하는가?

How does Dev Drive work?

  • dev drive 는 ReFS(Resilient File System)를 이용한다.
  • ReFS 는 다음과 같은 이점이 있다.
    • data availability(데이터 가용성)을 극대화
    • 다양한 부하들(workloads)에서 나오는 대용량 데이터셋에 대해서 효율적으로 확장이 가능
    • 손상에 대한 복원력을 통해 데이터 무결성을 제공
  • ReFS 를 통해서 dev drive 는
    • 개발 작업의 부하들(development workloads)을 위한 storage volume 을 초기화하게 된다.
    • 더 빠른 성능 제공
    • 개발 시나리오들에 최적화된 customizable setting 을 제공
    • ReFS 는 key 개발자 시나리오들의 성능을 향상시키기 위한 파일 시스템별 여러 최적화들이 포함되어 있다.

package cache 설정 방법

재부팅시 자동으로 mount

powershell 에서 mount/unmount

  • Dismount-DiskImage -ImagePath "d:\a\vmbox\devDrive\dev_drive.vhdx"
  • Mount-DiskImage -ImagePath "d:\a\vmbox\devDrive\dev_drive.vhdx"

See Also

  1. Configure Dev Drive policy for enterprise business devices | Microsoft Learn

Reference

  1. Set up a Dev Drive on Windows 11 | Microsoft Learn

[컴][유틸] 배경없애주는 프로그램

 

누끼 프로그램 / 앱 / desktop app / 유틸 / 툴 / 도구 /

배경없애주는 프로그램

[컴] markdown 으로 pdf 문서 만들기

마크다운으로 문서 작성 / 워드 / 한글 / 이력서 작성

markdown 으로 pdf 문서 만들기

작업 순서

  1. markdown 으로 글을 쓴다. 여기서는 파일 이름을 resume.md라고 가정하자.

  2. html 로 변환 : Pandoc 사용

    rem resume.md --> resume.html
    pandoc -f markdown -t html < resume.md > resume.html
  3. resume.html 에 css 적용

    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <style type="text/css">
            ...
        </style>
    </head>
    <body>
        {{ ... }}
    </body>
    </html>
    
  4. pdf 로 변환 : wkhtmltopdf 사용

    • footer.html 에 page no 를 추가함.
    • footer.html 를 넣고 header를 따로 지정하지 않으면, header 쪽의 여백까지도 사라져버려서 header.html을 지정해줬다.
    rem `resume.html` --> `output.pdf`
    "c:\myapps\wkhtmltopdf.exe"  --header-html header.html --footer-html footer.html --page-size A4 "d:\a\etc\resume\resume.html" f:\output.pdf

wkhtmltopdf

여러 language 에서 사용할 수 있는 library 도 있지만, 바로 사용할 수 있는 exe도 제공한다.

사용한 template 파일

[컴] 윈도우 앱 실행 별칭 Windows App execution aliases

 

윈도우즈

윈도우 앱 실행 별칭 Windows App execution aliases

설정 -> 앱 -> 고급 앱 설정 -> 앱 실행 별칭 에 있는 별칭들은 다음 경로에 있다.

  • %LocalAppData%\Microsoft\WindowsApps
설정 -> 앱 -> 고급 앱 설정 -> 앱 실행 별칭

이것을 추가로 만들려면 mklink로 exe 에 대한 symbolic link 를 만들어준다.

mklink %LocalAppData%\Microsoft\WindowsApps\my_alias_name.exe "the_full_path_of_your_executable_file"

참고로, 이렇게 하면 symbolic link 는 만들어지지만, ’앱 실행 별칭’에서 보이진 않는다.

Reference

  1. Another Way to Create App Execution Alias in Windows 11 | Password Recovery

[컴] widows app 의 URI

윈도우즈 URI / windows11 app uri

widows app 의 URI

windows 에서도 app 에 대한 URI 를 사용할 수 있다. 기본적으로 윈도우즈의 기본앱에 대한 URI 는 아래링크에서 확인할 수 있다.

아래는 자신의 컴퓨터의 모든 URI scheme 을 확인할 수 있는 .bat file 의 내용이다. 필자의 컴퓨터에서는 대략 6분정도 걸렸다.

@For /f "tokens=1* delims=" %%A in ('reg query HKCR /f "URL:*" /s /d ^| findstr /c:"URL:" ^| findstr /v /c:"URL: " ^| Sort') Do @Echo %%A %%B
pause

실행

만약 ms-photo 를 실행하려면, start ms-photo: 로 실행할 수 있다.

reg query HKCR /f "URL:*"

위 batch 를 실행한 결과값의 일부이다. ms 와 관계있는 URI 들을 모아놨다.

...
(기본값)    REG_SZ    URL:microsoft-edge
(기본값)    REG_SZ    URL:microsoft.windows.camera
(기본값)    REG_SZ    URL:microsoft.windows.camera.picker
(기본값)    REG_SZ    URL:microsoft.windows.photos.crop
(기본값)    REG_SZ    URL:microsoft.windows.photos.picker
(기본값)    REG_SZ    URL:microsoft.windows.photos.videoedit
(기본값)    REG_SZ    URL:MicrosoftBing Protocol
(기본값)    REG_SZ    URL:microsoftmusic
(기본값)    REG_SZ    URL:microsoftvideo
(기본값)    REG_SZ    URL:MK Protocol
(기본값)    REG_SZ    URL:mms Protocol
(기본값)    REG_SZ    URL:mms Protocol
(기본값)    REG_SZ    URL:ms-aad-brokerplugin
(기본값)    REG_SZ    URL:ms-actioncenter
(기본값)    REG_SZ    URL:ms-appinstaller
(기본값)    REG_SZ    URL:ms-apprep
(기본값)    REG_SZ    URL:ms-calculator
(기본값)    REG_SZ    URL:ms-clipchamp
(기본값)    REG_SZ    URL:ms-clock
(기본값)    REG_SZ    URL:ms-contact-support
(기본값)    REG_SZ    URL:ms-cortana2
(기본값)    REG_SZ    URL:ms-crossdevice-files
(기본값)    REG_SZ    URL:ms-crossdevice-settings
(기본값)    REG_SZ    URL:ms-crossdevice-share
(기본값)    REG_SZ    URL:ms-cxh
(기본값)    REG_SZ    URL:ms-default-location
(기본값)    REG_SZ    URL:ms-devhome
(기본값)    REG_SZ    URL:ms-device-enrollment
(기본값)    REG_SZ    URL:ms-device-enrollment2
(기본값)    REG_SZ    URL:ms-drive-to
(기본값)    REG_SZ    URL:ms-edu-secureassessment
(기본값)    REG_SZ    URL:ms-eyecontrolspeech
(기본값)    REG_SZ    URL:ms-gamebar
(기본값)    REG_SZ    URL:ms-gamebarservices
(기본값)    REG_SZ    URL:ms-gamingoverlay
(기본값)    REG_SZ    URL:ms-get-started
(기본값)    REG_SZ    URL:ms-getoffice
(기본값)    REG_SZ    URL:ms-holographicfirstrun
(기본값)    REG_SZ    URL:ms-inputapp
(기본값)    REG_SZ    URL:ms-insights
(기본값)    REG_SZ    URL:ms-ipmessaging
(기본값)    REG_SZ    URL:ms-launchremotedesktop
(기본값)    REG_SZ    URL:ms-lwh
(기본값)    REG_SZ    URL:ms-meetnow
(기본값)    REG_SZ    URL:ms-meetnowflyout
(기본값)    REG_SZ    URL:ms-msdt
(기본값)    REG_SZ    URL:ms-newsandinterests
(기본값)    REG_SZ    URL:ms-notepad
(기본값)    REG_SZ    URL:ms-officeapp
(기본값)    REG_SZ    URL:ms-officecmd
(기본값)    REG_SZ    URL:ms-oobenetwork
(기본값)    REG_SZ    URL:ms-outlook
(기본값)    REG_SZ    URL:ms-paint
(기본값)    REG_SZ    URL:ms-pchealthcheck
(기본값)    REG_SZ    URL:ms-penworkspace
(기본값)    REG_SZ    URL:ms-people
(기본값)    REG_SZ    URL:ms-phone
(기본값)    REG_SZ    URL:ms-photos
(기본값)    REG_SZ    URL:ms-powerautomate
(기본값)    REG_SZ    URL:ms-print-addprinter
(기본값)    REG_SZ    URL:ms-print-printjobs
(기본값)    REG_SZ    URL:ms-print-queue
(기본값)    REG_SZ    URL:ms-quick-assist
(기본값)    REG_SZ    URL:ms-retaildemo-launchbioenrollment
(기본값)    REG_SZ    URL:ms-retaildemo-launchstart
(기본값)    REG_SZ    URL:ms-screenclip
(기본값)    REG_SZ    URL:ms-screensketch
(기본값)    REG_SZ    URL:ms-search
(기본값)    REG_SZ    URL:ms-settings
(기본값)    REG_SZ    URL:ms-settings-airplanemode
(기본값)    REG_SZ    URL:ms-settings-bluetooth
(기본값)    REG_SZ    URL:ms-settings-cellular
(기본값)    REG_SZ    URL:ms-settings-emailandaccounts
(기본값)    REG_SZ    URL:ms-settings-language
(기본값)    REG_SZ    URL:ms-settings-location
(기본값)    REG_SZ    URL:ms-settings-lock
(기본값)    REG_SZ    URL:ms-settings-mobilehotspot
(기본값)    REG_SZ    URL:ms-settings-notifications
(기본값)    REG_SZ    URL:ms-settings-power
(기본값)    REG_SZ    URL:ms-settings-privacy
(기본값)    REG_SZ    URL:ms-settings-proximity
(기본값)    REG_SZ    URL:ms-settings-screenrotation
(기본값)    REG_SZ    URL:ms-settings-wifi
(기본값)    REG_SZ    URL:ms-settings-workplace
(기본값)    REG_SZ    URL:ms-stickereditor
(기본값)    REG_SZ    URL:ms-sttoverlay
(기본값)    REG_SZ    URL:ms-taskswitcher
(기본값)    REG_SZ    URL:ms-teams
(기본값)    REG_SZ    URL:ms-to-do
(기본값)    REG_SZ    URL:ms-todo
(기본값)    REG_SZ    URL:ms-unistore-email
(기본값)    REG_SZ    URL:ms-voip-call
(기본값)    REG_SZ    URL:ms-voip-video
(기본값)    REG_SZ    URL:ms-walk-to
(기본값)    REG_SZ    URL:ms-wcrv
(기본값)    REG_SZ    URL:ms-widgets
(기본값)    REG_SZ    URL:ms-windows-search
(기본값)    REG_SZ    URL:ms-windows-store
(기본값)    REG_SZ    URL:ms-windows-store-deskext
(기본값)    REG_SZ    URL:ms-windows-store2
(기본값)    REG_SZ    URL:ms-windowsbackup
(기본값)    REG_SZ    URL:ms-wpc
(기본값)    REG_SZ    URL:ms-wpdrmv
(기본값)    REG_SZ    URL:ms-wxh
(기본값)    REG_SZ    URL:ms-xbet-survey
(기본값)    REG_SZ    URL:ms-xgpueject
...

[컴] windows 11 에서 taskbar 위치 변경

작업 표시줄 / 위치 / 위에 두기 /windows11

windows 11 에서 taskbar 위치 변경

windows11로 update 하고나서 문제는 작업표시줄(taskbar) 를 아래에 고정시켜야 한다는 점이었다. 개인적으로 위에 두는 것을 선호했다.

ref.1 에서 해결할 방법 3가지를 알려준다.

  1. registry 수정 : 22H2 버전이 나온 후 이 방법은 작동하지 않는다고 한다.
  2. ExplorerPatcher tool
  3. Start11 tool : 유료앱이다.

ExplorerPatcher

  1. 다음 page에서 download 하자.

  2. C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ExplorerPatcher 에 가면 ’ExplorerPatcher’의 속성을 여는 바로가기를 찾을 수 있다.

    • 바로 실행: C:\Windows\System32\rundll32.exe "C:\Program Files\ExplorerPatcher\ep_gui.dll",ZZGUI 를 ’실행’하면 ’속성’창이 열린다.
  3. 이 속성창에서 ’작업표시줄 스타일’을 Windows 10 으로 변경한다.

  4. 작업표시줄 위치도 ’상단’으로 변경한다.

  5. ’파일 탐색기’를 다시 시작한다. 왼쪽하단 버튼을 눌러서 다시시작해도 되고, task manager에서 explorer를 죽이고, 다시 실행해도 된다.

  6. 왼쪽메뉴 ‘시작 메뉴’(Start Menu)에서 시작메뉴 스타일도 windows 10 으로 변경할 수 있다.

  7. uninstall 방법

24H2 에서 동작

windows11 build 26002+ 에서 windows 10 taskbar 를 사용할 수 없다고 한다.

이제 다시 windows 10 taskbar를 구현해서 넣었다고한다.

참고로 24H2 버전은 아직 preview 이다.

See Also

  1. 몇 분이면 뚝딱… ‘윈도우 11’에서 잃어버린 기능을 찾아서 - ITWorld Korea, 2023-04-24

Reference

  1. How to move Taskbar to top or side on Windows 11 - Pureinfotech

[컴][머신러닝] 프로그래머는 이제 곧 사라질까?

 프로그래밍을 계속 할 수 있을까

프로그래머는 이제 곧 사라질까?

eocnomist 의 기사다. 이전의 How AI models are getting smarter 에 이어지는 기사다. (참고: 생성형 AI 에 대한 대략적인 설명)

AI 가 인간을 대체할 수 있을까? 그리고 프로그래머는 이제 곧 사라질까? 이런 질문들에 대한 어느정도의 답이 된다.

기사

from : LLMs will transform medicine, media and more

의학, 미디어 등을 변화시킬 LLM / 하지만 (인간의) 도움 없이는 불가능합니다.

인공지능(AI)는 컴퓨터가 어떤 일을 똑똑하게(인간기준으로) 하는 기술

그런 의미에서 이미 AI 는 많이 쓰이고 있다. 네비게이션의 길찾기, 과속차량 번호판의 인식, 온도 조절기등은 모두 AI 에 속합니다.

AI 가 일관되고, 안정적으로 작동하면, 그것은 그냥 엔지니어링이라 부릅니다.

현재 전 세계의 주목을 받으며 엄청난 양의 컴퓨팅 파워와 전력을 빨아들이고 있는 인공지능딥러닝이라는 기술을 기반으로 합니다.
딥러닝에서는 선형대수(특히 행렬 곱셈)통계를 사용하여,
학습과정에서 대규모 데이터 세트에서 패턴을 추출하고 그래서 학습하는 것이 됩니다.

Google의 Gemini나 OpenAI의 GPT와 같은 대규모 언어 모델(LLM)은 수많은 텍스트, 이미지, 동영상으로 학습되어 왔다. 그리고 많은 능력을 개발한 상태입니다.
이미지, 음악, 로봇공학, 유전체학, 의학, 기후, 날씨, 소프트웨어 코딩등, 보다 전문화된, 도메인에 특화된 버전의 모델이 존재합니다.

연구자들은 여전히 AI가 무엇을 할 수 있고 무엇을 할 수 없는지 파악하고 있습니다. 지금까지는 더 많은 데이터로 학습된 더 큰 모델이 더 뛰어난 능력을 발휘하는 것으로 입증되었습니다. 이는 계속해서 더 많은 데이터를 추가하면 더 나은 AI를 만들 수 있다는 믿음을 심어주었습니다. 모델 크기와 학습 데이터의 양이 어떻게 상호 작용하여 LLM을 향상시키는지 보여주는 ’확장 법칙’에 대한 연구가 수행되었습니다.

더 나은” LLM이란 무엇일까요? 질문에 정답을 맞히거나 창의적인 아이디어를 제시하는 모델일까요?

지금까지 AI의 힘은 개별 작업에서 가장 두드러집니다.
하지만 open-ended task에서의 성능은 평가하기가 더 어렵습니다.

오늘날의 대규모 AI 모델은 학습 데이터에 표현된 패턴을 기반으로 시(poetry)에서 실사 이미지에 이르기까지 다양한 것을 생성하는 데 매우 능숙합니다.
그러나 이러한 모델은 생성한 것 중 어떤 것이 가장 의미가 있거나 주어진 상황에 가장 적합한지를 판단하는 데는 능숙하지 못합니다.

논리와 추론 능력도 떨어집니다. AI에게 일관되게 추론할 수 있는 능력을 제공하기 위해 더 많은 데이터를 주면 될 것인지, 아니면 완전히 다른 종류의 모델이 필요한 것인지에 대해서는 아직 명확치 않다.
오랜 시간 동안 AI의 한계가 존재할 수 있다. 그로 인해 이를 활용하기 위해서는 인간의 추론이 필요할 것이다

이러한 한계가 무엇인지 알아내는 것은 의료와 같은 분야에서 중요합니다. AI를 적절히 활용하면 암을 조기에 발견하고, 서비스에 대한 접근성을 확대하고, 진단을 개선하고, 개인 맞춤형 치료를 제공할 수 있습니다. 4월에 발표된 메타 분석에 따르면 AI 알고리즘은 이러한 작업에서 인간 임상의보다 더 나은 성과를 낼 수 있습니다. 하지만 인공지능의 훈련이 그들의 길을 잃게 할 수 있다. 즉, 사람이 개입하는 것을 제한하는 방향으로 훈련될 수도 있다.

예를 들어, AI 모델은 ‘데이터 분포 변화’(“data distribution shifts”)로 인해 더욱 부각된 인간의 편견에 취약한데, 백인의 피부 이미지로 주로 학습한 후 흑인의 피부 이미지를 제공하면 진단 모델이 실수를 할 수 있습니다.

'AI'와 '자격을 갖춘 사람'을 결합하는 것이 가장 효과적인 것으로 입증되었습니다. 이 논문에 따르면 AI를 사용한 임상의는 정확하게 암이라고 진단한 사람의 비율을 81.1%에서 86.1%로 늘릴 수 있었으며, 암이 없다고 정확하게 진단한 사람의 비율도 늘릴 수 있었습니다.

AI 모델은 인간과 다른 실수를 저지르는 경향이 있기 때문에 AI와 인간의 파트너십이 AI 단독으로 일을 하거나, 인간 단독으로 일을 하는 것보다 더 뛰어난 성과를 보이는 것으로 나타났습니다.

로봇방식

과학 분야에서 새로운 가설을 탐구하는 데 지금보다 사람이 덜 필요할 수도 있습니다. 2009년 케임브리지 대학교의 로스 킹 박사는 자신의 궁극적인 목표는 자율 실험실, 즉 ’로봇 과학자’로 기능하는 시스템을 설계하는 것이라고 말했습니다. 킹 박사가 개발한 AI 과학자 아담은 가설을 세우고, 로봇 팔을 사용해 실험을 수행하고, 센서를 통해 결과를 수집하고 분석하도록 설계되었습니다. 대학원생이나 박사후 연구원과 달리 아담은 식사나 수면을 위해 휴식을 취할 필요가 없습니다. 그러나 이러한 유형의 AI 시스템은 현재로서는 신약 개발 및 재료 과학과 같은 비교적 좁은 영역으로 제한되어 있습니다. 인간이 주도하는 연구보다 훨씬 더 많은 이득을 가져다줄 수 있을지는 아직 불분명합니다.

AI 기술은 수십 년 동안 과학 분야에서 데이터를 분류, 선별, 분석하고 예측하는 데 사용되어 왔습니다. 예를 들어, Project CETI의 연구원들은 고래 발성 데이터 세트를 수집한 다음 이 데이터로 AI 모델을 학습시켜 어떤 소리가 의미를 가질 수 있는지 알아냈습니다. 또는 구글 딥마인드에서 개발한 심층 신경망인 ’알파폴드’를 생각해 보세요. 방대한 단백질 데이터베이스로 훈련된 이 시스템은 사람이 며칠 동안 세심하게 실험하고 측정해야 했던 단백질의 3차원 모양을 빠르고 정확하게 예측할 수 있습니다. 딥마인드에서 개발한 또 다른 AI 시스템인 GNoME는 특정 화학적 특성을 가진 새로운 물질을 발견하는 데 도움을 주기 위한 것입니다(다이어그램 참조).

AI는 입자 충돌기의 결과를 선별하여 새로운 아원자 입자(subatomic particles)를 식별하거나, 과학 문헌을 따라잡는 등 연구자가 감당하기 힘든 대량의 데이터 흐름을 이해하는 데도 도움이 될 수 있습니다. 아무리 세심한 독서가라도 자신의 연구와 관련이 있을 수 있는 모든 과학 논문을 소화하는 것은 불가능에 가깝습니다. 이른바 문헌 기반 발 시스템(literature-based discovery system)은 이러한 산더미 같은 텍스트를 분석하여 연구의 빈틈을 찾아내고, 오래된 아이디어를 새로운 방식으로 결합하거나 새로운 가설을 제안할 수 있습니다.

하지만 이러한 유형의 AI 작업이 유익한지 여부를 판단하기는 어렵습니다. AI는 예상치 못한 연역적인 도약을 하는 데 인간보다 더 뛰어나지 않을 수도 있고, 대신 단순히 전통적이고 잘 알려진 연구 경로를 선호하여 흥미로운 결과를 내지 못할 수도 있다

교육계에서는 AI, 특히 ChatGPT와 같은 봇이 오히려 독창적인 사고를 방해할 수 있다는 우려가 있습니다. 2023년 교육 기업 Chegg의 조사에 따르면 전 세계 학생의 40%가 학교 과제를 할 때 AI를 사용했으며, 주로 작문을 위해 사용했습니다. 이로 인해 일부 교사, 교수, 학군에서는 AI 챗봇 사용을 금지하고 있습니다.

많은 사람들이 챗봇을 사용하면 문제를 해결하거나 논쟁을 벌이는 과정에서 문제 해결 능력과 비판적 사고력을 키우는 데 방해가 될 수 있다고 우려하고 있습니다.

다른 교사들은 완전히 다른 접근 방식을 취하여 AI를 도구로 받아들이고 과제에 통합하기도 합니다. 예를 들어, 학생들에게 ChatGPT를 사용하여 주제에 대한 에세이를 작성한 다음 틀린 부분에 대해 비평하도록 요청할 수 있습니다.

잠깐만요, 챗봇이 이 글을 쓴 건가요?

오늘날의 생성형 AI는 버튼 클릭 한 번으로 텍스트를 생성할 뿐만 아니라 이미지, 오디오, 동영상을 단 몇 초 만에 생성할 수 있습니다. 이는 팟캐스트에서 비디오 게임, 광고에 이르기까지 미디어 비즈니스의 판도를 바꿀 수 있는 잠재력을 가지고 있습니다.

AI 기반 도구는 편집을 간소화하고 시간을 절약하며 진입 장벽을 낮출 수 있습니다.

하지만 AI로 제작된 콘텐츠는 일러스트레이터나 성우와 같은 일부 아티스트들을 위험에 빠뜨릴 수 있습니다. 시간이 지나면 인간 배우의 AI 기반 복제품(simulacrum) 또는 완전히 인공적인 배우를 사용하여 영화 전체를 제작하는 것이 가능할 수도 있습니다.

하지만 AI 모델은 스스로 문제를 만들거나 해결할 수 없습니다(아직까지는). 인공지능은 정교한 소프트웨어일 뿐, 지각 능력이 있거나 자율적인 존재가 아닙니다. AI는 자신을 호출하고, 자신에게 묻고, 그 결과를 적용 또는 폐기하는 것을 하는데에 있어 인간 사용자에게 의존합니다. 좋든 나쁘든 AI의 혁신적인 능력은 여전히 인간과 인간의 판단에 달려 있습니다.

[컴][머신러닝] 생성형 AI 에 대한 대략적인 설명

generative AI / 설명 / 간략설명 / 이해

생성형 AI 에 대한 대략적인 설명

경제지 economist 에서 생성형AI 에 대해 간략하게 이야기해주고 있다. 생성형 AI 가 어떻게 동작하는지 이해를 도와줘서 옮겨놓는다. 개인적으로 필요한 부분만 옮겨놓은 것이라서, 완전한 글은 본문을 참고하자.

기사

from : How AI models are getting smarter, 2024-08-06

뉴런들을 네트워크에 연결하고, 뉴런들을 네트워크에 계층화하는 여러방법이 있다.
이런 아키텍쳐의 발전이 좀 더 학습이 쉽고, 좀 더 나은 결과를 가져다 주는 신경망을 만드는 데 도움이 됐다.

현재 관심은 text를 위한 LLM(Large language model)과 image를 위한 diffusion model 들에 집중되어 있다.
이 모델들은 이전 모델들보다 더 많은 뉴런층을 가지고 있으며, 방대한 데이터를 빠르게 처리할 수 있는 방식으로 구성됐다.

transformer architecture 를 기반으로 LLM 들이 만들어졌다. 트랜스포머는 2017년에 Google Brain의 아시시 바스와니와 그의 팀이 소개했는데, 이 트랜스포머의 핵심 원리는 ‘attention’(주의) 이다.
attention layer는 모델이 입력값들의 여러 측면들 — 예를 들면, 텍스트에서 서로 일정한 거리에 있는 단어들 — 이 서로 어떻게 연결되어 있는지를 학습할 수 있게 해준다. 그리고 이를 output을 만드는 과정에 반영할 수 있도록 해준다.

한 row 에 많은 attention layer들이 있으면, 모델은 단어, 구(phrase) 심지어 문단 사이에 있는 다양한 수준의 세밀한부분에서(at different levels of granularity) 연관성을 학습할 수 있게 된다.

transformer 기반의 모델들은 text뿐만 아니라 image 도 생성할 수 있다.
OpenAI 가 2021년에 출시한 DALL-E 의 첫번째 버전은 이미지의 픽셀 그룹간의 연관성을 학습하는 트랜스포머였다.
신경망은 그것이 보는 것을 숫자로 변환하고, 이에 대해 수학(특히, 행렬연산)을 행한다.

트랜스포머에는 한계가 있다. 일관되게 세계(world)를 표현하는 model 을 학습하는 것이 어렵다.
이 트랜스포머 기반 모델은 인간의 질문에 답할 때, 한 답변에서 다음 답변으로 넘어가면서 스스로 모순된 답변을 할 수 있다. 이것은 첫번째 답변이 두 번째 답변을 모순되게 만든다는 것을 이해하지 못하기 때문이다.
이 모델은 실제로 그 답변을 이해해서 알고있는 것이 아니라, 단순히 답변처럼 보이는 특정 문자열들의 연관성만 알고 있기 때문이다.

트랜스포머 기반 모델은 잘못된 답을 만들고, 그럴 듯한 가짜 인용을 만들어내는 ‘환각’(hallucinations)이 발생하기 쉽다.
마찬가지로, 초기 트랜스포머 기반 모델에서 생성된 이미지는 종종 물리 법칙을 위반하고 받아드리기 어려운 경우가 많았다(일부 사용자에게는 기능일 수 있지만 사실적인 이미지를 생성하려는 디자이너에게는 버그였다). 다른 종류의 모델이 필요했다.

diffusion model(확산 모델)들은 훨씬 더 사실적인 이미지를 생성할 수 있다.
diffusion model의 주요아이디어는 확산의 물리적과정에서 영감을 받았다. 뜨거운 물 한 컵에 티백을 넣으면 찻잎이 가파르게 가라앉기 시작하고, 차의 색이 맑은 물로 스며들어 흐려진다. 몇 분 동안 그대로 두면 컵에 담긴 액체가 균일한 색을 띠게 된다.

이 확산 과정은 물리 법칙에 의해 결정된다. 물리 법칙을 사용하여 차가 어떻게 확산될지 예측할 수 있는 것처럼, 이 과정을 역설계하여 티백이 처음 어디에 어떻게 떨어졌을지 재구성할 수도 있다. 현실에서는 이미 벌어진 일을 뒤로 돌릴 수 없지만, 엔트로피를 역전시키는 과정을 시뮬레이션하는 법을 학습하면 사실적인 이미지 생성이 가능해진다.

훈련(training)은 다음과 같이 작동한다.
이미지를 가져와서 완전히 무작위로 보일 때까지 점점 더 많은 흐림(blur)과 노이즈를 적용합니다. 그 다음, 이부분이 어려운 부분인데, 이 과정을 역으로 진행하여 차에서 티백을 찾아내는 것처럼 원본 이미지를 다시 만드는 것이다.

이 작업은 “self-supervised learning”(자기 지도 학습)을 통해 이뤄진다. text에서 LLM이 훈련되는 방식과 유사하다.
그것은 문장에서 단어를 가리고, 시도와 오류(trial and error)를 통해 누락된 단어를 예측하는 방법이다.

이미지의 경우, 네트워크는 원본 이미지를 재생산하기 위해 점점 더 많은 양의 노이즈를 제거하는 방법을 학습한다. 수십억 개의 이미지를 처리하면서 왜곡을 제거하는 데 필요한 패턴을 학습하게 되면, 네트워크는 아무것도 없는 무작위 노이즈에서 완전히 새로운 이미지를 생성할 수 있는 능력을 얻게 된다.

대부분의 최첨단 이미지 생성 시스템은 디퓨전 모델을 사용하지만, 노이즈 제거 또는 왜곡을 역전(reversing distortions)시키는 방식은 서로 다르다.

2022년에 출시된 Stable Diffusion(Stability AI의)과 Imagen은 모두 컨볼루션 신경망(CNN)이라는 아키텍처의 변형을 사용했습니다. CNN은 그리드 형태의 데이터를 분석하는 데 뛰어납니다. 픽셀의 행과 열 같은.
실제로 CNN은 입력된 데이터에서 작은 슬라이딩 창을 위아래로 움직이며 패턴이나 모서리와 같은 특정 객체(artefacts)를 찾는다.

CNN은 픽셀에서 잘 작동하지만, 최신 이미지 생성기 중 일부는 확산 트랜스포머(difffusion transformers)를 사용한다. 스테이빌리티 AI의 최신 모델인 Stable Diffusion 3가 여기에 포함된다. 확산에 대한 훈련을 받은 트랜스포머는 이미지나 비디오 프레임의 다양한 부분이 서로 어떻게 연관되어 있는지, 그리고 얼마나 강하게 또는 약하게 연결되어있는지를 훨씬 더 잘 알아낼 수 있어서 보다 사실적인 결과물을 만들어낸다.(여전히 실수가 있긴 하지만).

추천시스템(Recommendation systems) 은 다른 문제다.(kettle of fish)
이러한 시스템의 추천 알고리즘을 구축하고 사용하는 회사들은 추천 알고리즘에 대해 극도로 비밀을 유지하기 때문에 내부 구조를 엿볼 기회는 드물다.

그러나 2019년 Meta(당시 Facebook)는 자사의 딥러닝 추천 모델(DLRM)에 대한 세부 정보를 공개했다. 이 모델은 세 가지 주요 부분으로 구성되어 있다.

  1. 입력(예를 들어 사용자의 나이, 플랫폼에서의 ‘좋아요’, 또는 소비한 콘텐츠 등)을 ’임베딩(embeddings)’으로 변환합니다.
  2. 이 임베딩 공간에서 유사한 것들(예를 들어 테니스와 탁구)이 서로 가까운 위치에 있도록 학습합니다.
  3. 그런 다음 DLRM은 신경망을 사용하여 행렬 인수분해(matrix factorisation)라는 작업을 수행한다. 스프레드시트를 상상해보자, 칼럼들은 동영상들이고 row들은 다양한 사용자들이다.
    각 셀(cell)들은 각 사용자가 각 동영상을 얼마나 좋아하는지를 나타낸다.
    그러나 대부분의 셀은 비어있다.
    추천의 목표는 모든 빈 셀에 대해 예측(prediction)을 하는 것이다.
  4. 딥러닝 추천 모델(DLRM)이 이를 수행하는 한 가지 방법은 그리드를 2개의 행렬(grid)로 나누는 것이다.
    하나는 사용자에 대한 데이터를 포함하는 행렬(grid)과 다른 하나는 동영상에 대한 데이터를 포함하는 행렬(grid)로 나누는 것이다.(수학 용어로 행렬을 인수분해).
  5. 이러한 행렬(grid)을 재결합(즉, 행렬 곱셈)을 하고
  6. 그 결과를 다른 신경망에 입력으로 제공하여 추가적인 수치 계산을 수행하면 비어 있던 셀을 채울 수 있다.
    즉, 각 사용자가 각 동영상을 얼마나 좋아할지 예측할 수 있다.

비슷한 방식은 광고, 스트리밍 서비스의 노래, 이커머스 플랫폼의 제품 등에도 적용할 수 있다.
기술 기업들은 이와 같이 상업적으로 유용한 작업을 잘 수행하는 모델에 가장 큰 관심을 보입니다. 하지만 이러한 모델을 대규모로 실행하려면 막대한 비용과 방대한 양의 데이터, 엄청난 처리 능력(processing power)이 필요합니다.

학술적 맥락에서는, 데이터셋이 작고 예산이 제한적이기 때문에 다른 종류의 모델이 더 실용적입니다.
이러한 모델에는 순환 신경망(데이터의 시퀀스를 분석하기 위해 사용됨), 변이형 오토인코더(variational autoencoders, VAE)(데이터에서 패턴을 발견하기 위해 사용됨), 생성형 적대 신경망(generative adversarial networks, GAN)(하나의 모델이 다른 모델을 반복적으로 속이면서 작업을 배우는 방식), 그래프 신경망(복잡한 상호작용의 결과를 예측하기 위해 사용됨)이 포함된다.

심층 신경망, 트랜스포머, 확산 모델이 모두 연구적 호기심에서 광범위한 배포로 발전한 것처럼, 이러한 다른 모델의 특징과 원리는 미래의 AI 모델에 활용되고 통합될 것이다. 트랜스포머는 매우 효율적이지만, 이를 확장한다고 해서 환각과 추론 시 논리적 오류를 범하는 경향을 해결할 수 있는지는 확실하지 않다. 이러한 약점을 극복하고 다음 단계로 나아갈 수 있는 “상태 공간 모델(state-space models)”부터 “신경-상징적(neuro-symbolic)” AI에 이르는 ‘포스트 트랜스포머’ 아키텍처에 대한 탐색이 이미 진행 중이다. 이상적으로는 이러한 아키텍처가 더 뛰어난 추론 능력을 겸비한 주의(attention)을 갖는 것이 이상적이다. 현재로서는 그런 모델을 어떻게 구축할지 아는 사람은 없습니다. 언젠가는 AI 모델이 이 작업을 해낼 수도 있을 것이다.

[컴] svg, geojson 이용한 한국지도 그리기

 

벡터 지도 / 웹에서 지도 그리기 / d3 / mapping shape files/ cartography

svg, geojson 이용한 한국지도 그리기

Shpefile 또는 GeoJSON 등의 파일을 얻었으면, mapshaper 에서 이것이 어떻게 그려지는지를 확인해 볼 수 있다.

GeoJSON 을 가지고 D3 로 그리기

npm install -g d3-geo-projection

windows 에선 " 를 사용하지만, bash 에서는 '를 사용하면 된다.

rotate 는 반시계방향이다. conic projection 이어서 rotate 가 정확히 평면에서 rotate 하는 것과는 조금 다르다. 원추도법(Conic projection) 에 대한 설명은 wiki page](https://ko.wikipedia.org/wiki/%EC%A7%80%EB%8F%84_%ED%88%AC%EC%98%81%EB%B2%95#%EC%9B%90%EC%B6%94%EB%8F%84%EB%B2%95)를 참고하자.

  • https://youtu.be/5QWtpksj9_U?t=315 의 그림참고
  • parallels 는 표준위선이다. 이 표준위선내에서는 축척이 일정하다고 볼 수 있다. 원뿔모양이라서 표준위선 밖은 위로갈수록 축척이 커지고, 아래로 갈수록 축척이 작아진다.
.\node_modules\.bin\geoproject.cmd "d3.geoConicEqualArea().parallels([33, 38.7]).rotate([230, 0]).fitSize([960, 960], d)" < south-korea-with-regions_1516.geojson > korea-map.json

.\node_modules\.bin\geo2svg.cmd -w 960 -h 960 < korea-map.json > korea-map.svg

korea-map.svg 를 열어보면 된다.

Reference

  1. Command-Line Cartography, Part 1. A tour of d3-geo’s new command-line… | by Mike Bostock | Medium

[컴] nestjs 에서 graphql 사용

graphql / code first

nestjs 에서 graphql 사용

  1. npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql
  2. nest generate module brand
  3. nest generate resolver brand
  4. nest generate service brand
  5. src/app.module.ts 에 GraphQL module 설정 (아래 ‘codes’ 참고)
  6. /src/brand/brand.type.ts 생성 (아래 ‘codes’ 참고)
  7. /src/brand/brand.service.ts (아래 ‘codes’ 참고)
  8. /src/brand/brand.resolver.ts (아래 ‘codes’ 참고)
  9. npm run start
  10. browser에서 localhost:3000/graphql

codes

// app.modules.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { BrandModule } from './brand/brand.module';
import { join } from 'path';

@Module({
  imports: [
    BrandModule,
    // graphql module 설정
    GraphQLModule.forRoot<ApolloDriverConfig>({
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      driver: ApolloDriver,
      playground: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
// /src/brand/brand.type.ts
import { Field, ObjectType, Int } from '@nestjs/graphql';

@ObjectType()
export class Brand {
  @Field(type => Int)
  id: number;

  @Field()
  name: string;

  @Field()
  company: string;
}
// /src/brand/brand.service.ts
import { Injectable } from '@nestjs/common';
import { Brand } from './brand.type';

@Injectable()
export class BrandService {
  private brands: Brand[] = [
    { id: 1, name: 'Air Force', company: 'nike' },
    { id: 2, name: 'Jordan', company: 'nike' },
  ];

  findAll(): Brand[] {
    return this.brands;
  }

  findOne(id: number): Brand {
    return this.brands.find(brand => brand.id === id);
  }
}
// /src/brand/brand.resolver.ts
import { Args, Int, Query, Resolver } from '@nestjs/graphql';
import { Brand } from './brand.type';
import { BrandService } from './brand.service';

@Resolver(of => Brand)
export class BrandResolver {
  constructor(private brandService: BrandService) { }

  @Query(returns => [Brand])
  brands(): Brand[] {
    return this.brandService.findAll();
  }

  @Query(returns => Brand)
  brand(@Args('id', { type: () => Int }) id: number): Brand {
    return this.brandService.findOne(id);
  }
}

graphQL query

brand.resolver.ts 에 정의한 method 를 이용하게 된다. 아래처럼 brands를 query하면 brand.resolver.tsbrands 가 호출된다.

{
  brands{
    id, name, company
  }
}
{
  "data": {
    "brands": [
      {
        "id": 1,
        "name": "John Doe",
        "company": "john.doe@example.com"
      },
      {
        "id": 2,
        "name": "Jane Doe",
        "company": "jane.doe@example.com"
      }
    ]
  }
}

See Also

  1. GraphQL vs. REST | Apollo GraphQL Blog
    • Rest 의 아이디어는 resource 다. resource type, 에 따라 fetch way 가 다르다.
    • GraphQL 은 2개를 따로 정의한다. rdbms의 모습과 비슷하다.
      • data 에 대한 schema 를 정의하고,
      • query 를 위한 schema 를 따로 만들 수 있다.
  2. Getting Started with NestJS GraphQL Schema First Approach

Reference

  1. GraphQL + TypeScript | NestJS - A progressive Node.js framework
  2. Beginner’s Guide to Using GraphQL with NestJS

[컴] 자막번역

srt / smi / 자막번역 / 무료번역 / srt 번역

자막번역

deepl 을 사용해서 자막을 번역해준다.

DeeplTranslator 은 우리가 web 에서 사용하는 무료 버전을 사용해서 번역해준다. 코드를 확인해 볼 만 하다.

See Also

  1. 쿠…sal: [컴] ffmpeg 으로 video container 변경

[컴] Remix 의 Hello World

 

Remix 의 Hello World

Helloworld

  1. npm init -y
  2. npm i @remix-run/node @remix-run/react @remix-run/serve isbot@4 react react-dom
  3. npm i -D @remix-run/dev vite
  4. vite.config.js 생성
// from : https://remix.run/docs/en/main/start/quickstart#vite-config
import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [remix()],
});
  1. app/root.jsx생성
  2. npx remix vite:build : <proj_root>\build에 client, server 가 만들어짐.
  3. npx remix-serve build/server/index.js : package.jsontype: module 이 필요.

package.json

{
  "name": "skybridge",
  "version": "1.0.0",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "build": "remix vite:build",
    "serve": "remix-serve build/server/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "@remix-run/node": "^2.9.2",
    "@remix-run/react": "^2.9.2",
    "@remix-run/serve": "^2.9.2",
    "isbot": "^4.4.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@remix-run/dev": "^2.9.2",
    "vite": "^5.3.1"
  }
} 

모든 route 은 links function 을 export 할 수 있다.

다음과 같은 것으로 보면 된다. <link rel="stylesheet" href="./app.css?url">

import type { LinksFunction } from "@remix-run/node";

import appStylesHref from "./app.css?url";
export const links: LinksFunction = () => [
  { rel: "stylesheet", href: appStylesHref },
];

route 추가

만약 다음과 같은 file 을 만든다면, 브라우저에서 /contacts/<id> 로 갈 때 contact.$contactId.tsx 파일을 호출할 것이다.

  • /app/routes/contact.$contactId.tsx

templates, stacks

templates, stacks 를 이용하면 쉽게 초기 세팅을 끝낼 수 있다.

template 사용

quick start 에서 처럼 한번 해본 이후엔 그냥 template을 쓰면 된다.

npx create-remix@latest <my_app_name> –template remix-run/remix/templates/remix

entry.{client|server}.tsx

이 파일은 optional 이다. 이 파일이 있다면, 먼저 browser 는 entry.client.tsx를 호출하고, 그 후 /app/routes/_index.tsx를 실행한다.

Layout

root.tsxLayout function 이 있으면 그것이 기본적인 Layout 으로 사용된다.

_index.tsx

보통 아래처럼 default function 을 지정하는데, Index 는 다른 이름으로 바꿔도 문제되지 않는다.

...
export default function Index() {
    return (
        <div></div>
    )
}

접근 순서

  1. entry.client.tsx
  2. app/root.tsxLayout
  3. app/root.tsxApp
  4. app/routes/_index.tsx

See Also

  1. Query GraphQL in Remix in less than 60 seconds | simeonGriggs.dev : graphql 사용

[컴] ionic 으로 android apk 생성

cross platform / cordova

ionic 으로 android apk 생성

ionic start

  • Examples
  • ionic start --list : template list 를 볼 수 있다.
  • ionic start myApp tabs --type=react : myApp 이란 이름으로, tabs 라는 template을 사용해서 project생성
npm install -g @ionic/cli

ionic start --list
ionic start myApp tabs --type=react 

ionic capacitor

ionic 은 기본적으로 Capacitor 를 사용한다.(Capacitor: Everything You've Ever Wanted to Know - Ionic Blog)

  • ionic serve : browser에서 app 을 보여준다.
  • ionic capacitor add android : Capacitor 를 이용해서 android app 추가
  • ionic capacitor build android : ionic capacitor build | Ionic Documentation
  • ionic capacitor open android : android project를 android studio 에서 열어준다.

emulator

emulator 를 띄워놓고, ionic capacitor run android --target=Pixel_3a_API_34 를 하면, emulator 에 apk 가 설치되고 실행된다.

  1. 환경변수 설정

    • JAVA_HOME은 android build 시점에 필요하다.
    set JAVA_HOME=d:\a\apps\java\jdk-17.0.11.9-hotspot
    set ANDROID_HOME=d:\a\appss\Android\Sdk
  2. emulator list : \Android\Sdk\emulator\emulator.exe -list-avd ionic capacitor run android --list 을 사용할 수도 있다. bat ionic capacitor run android --list

  3. run emulator: \Android\Sdk\emulator\emulator.exe -avd Pixel_3a_API_34

  4. ionic capacitor run android --traget=<target>

build .apk

ionic capacitor open android 를 실행하면, <proj_root>\android 를 android studio 에서 열어준다. android studio 에서 ‘build apk’ 를 하면 apk 를 얻을 수 있다.

  • apk path: <proj_root>\android\app\build\outputs\apk\debug\app-debug.apk

See Also

  1. 쿠…sal: [컴] cordova 로 android app build
  2. Starting an App: How to Guide | Ionic Documentation

[컴] cordova 로 android app build

 apache cordova / cross platform /

cordova 로 android app build

절차

  1. npm 설치
  2. npm i --save cordova
  3. cordova create mytestapp com.mysite.myapp MyTestApp --template https://github.com/apache/cordova-app-hello-world
  4. cd mytestapp
  5. cordova platform ls
  6. cordova platform add android
  7. cordova build android

cordova create

  • cordova create <path> <id> <name>
  • template 사용:
    • App Templates - Apache Cordova
    • cordova-template-ngx-onsenui
    • 예 : cordova.cmd create mytestapp com.mysite.myapp MyTestApp --template cordova-template-ngx-onsenui

cordova build

prerequisites

  • gradle : Gradle | Releases
  • java 17 이상
  • android sdk : android studio 설치후, sdk manager 로 download 하면 된다.

cordova build android

set PATH=d:\a\apps\gradle\gradle-7.5.1\bin;%path%
set JAVA_HOME=d:\a\apps\java\jdk-17.0.11.9-hotspot
set ANDROID_HOME=d:\a\appss\Android\Sdk
d:\a\prog\cordova\node_modules\.bin\cordova.cmd build android

Error, Could not get resource

테스트를 한 환경의 wifi 가 stable 하지 않았는데, 그래서 다음처럼 간혹 Could not get resource 에러가 떴다. 이럴 때는 그냥 다시 build 를 시도하면 된다. 그러면, download 가 잘 이뤄져서 이 이슈는 넘어간다. 이런 식으로 Could not get resource 가 뜨는 경우는 계속 재시도 하면 된다.

* What went wrong:
Execution failed for task ':CordovaLib:compileDebugJavaWithJavac'.
> Could not resolve all files for configuration ':CordovaLib:debugCompileClasspath'.
   > Failed to transform kotlin-stdlib-1.7.10.jar (org.jetbrains.kotlin:kotlin-stdlib:1.7.10) to match attributes {artifactType=android-classes-jar, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-api}.
      > Could not download kotlin-stdlib-1.7.10.jar (org.jetbrains.kotlin:kotlin-stdlib:1.7.10)
         > Could not get resource 'https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.10/kotlin-stdlib-1.7.10.jar'.
            > Tag mismatch

.apk

다음 path 에서 결과물을 확인할 수 있다.

  • <proj_root>\platforms\android\app\build\outputs\apk\debug\app-debug.apk

emulator

Android Virtual Device(AVD) 에서 cordova 로 만든 apk 를 실행할 수 있다.

일단 먼저 AVD 를 띄워놓고, cordova run --emulator 를 실행하면 된다.

avd 실행

android studio 에 가서 avd manager 에서 띄워도 되고, emulator 실행파일을 이용해서 띄워도 된다.

Reference

  1. Android Platform Guide - Apache Cordova
  2. 쿠…sal: [컴] cordova 로 web app 만들기
  3. Apache Cordova

[컴] spring에서 @Transactional 이 동작하는지 확인하는 방법

spring transaction / transactional / 스프링 / spring boot

spring에서 @Transactional 이 동작하는지 확인하는 방법

@Transactional 이 제대로 동작하려면

spring 에서 @Transactional 를 사용하려면, public method 에 annotation 을 달아야 한다. 정확히는 이 @Transactional이 붙어있는 method 를 현재 @Bean 말고, 다른 Bean 에서 호출해줘야 한다.

  • [Using @Transactional :: Spring Framework](https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/annotations.html)
  • [java - Spring @Transactional annotation is not working - Stack Overflow](https://stackoverflow.com/questions/32156652/spring-transactional-annotation-is-not-working)

@Transactional 동작하는지 확인하는 방법

  • TransactionAspectSupport.currentTransactionStatus
    import org.springframework.transaction.interceptor.TransactionAspectSupport;
    ...
    status = TransactionAspectSupport.currentTransactionStatus();
    • Transaction 이 동작하지 않았다면, NoTransactionException 을 던지게 된다.
  • call stack
    • TransactionInterceptor.invoke : call stack 에 TransactionInterceptor.invoke가 보인다.
    • call stack

@Transactional method 를 다른 Bean 에서 호출해야 하는 이유

다른 Bean 에서 호출하지 않고, 현재 @Bean 내의 method 에서 @Transactional method 를 호출하는 것으로는 bean 을 생성하지 않는다. 그러니까 spring 이 처음 run 할 때 @Transactional에 대한 proxy class 를 만드는데, 그 작업을 하지 않는 것 같다.

cglib 를 호출할 때의 call stack:

- SpringNamingPolicy.getClassName(String,String,Object,Predicate) (\spring-core-6.0.7.jar\org.springframework.cglib.core\SpringNamingPolicy.class:41)
- AbstractClassGenerator.generateClassName(Predicate) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:169)
- AbstractClassGenerator.generate(AbstractClassGenerator$ClassLoaderData) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:339)
- Enhancer.generate(AbstractClassGenerator$ClassLoaderData) (\spring-core-6.0.7.jar\org.springframework.cglib.proxy\Enhancer.class:575)
- AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:103)
- 0x0000000800f7bf70.apply(Object) (Unknown Source:-1)
- LoadingCache.lambda$createEntry$1(Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core.internal\LoadingCache.class:52)
- 0x0000000800f7c5c0.call() (Unknown Source:-1)
- FutureTask.run() (\java.base\java.util.concurrent\FutureTask.class:264)
- LoadingCache.createEntry(Object,Object,Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core.internal\LoadingCache.class:57)
- LoadingCache.get(Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core.internal\LoadingCache.class:34)
- AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator,boolean) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:126)
- AbstractClassGenerator.create(Object) (\spring-core-6.0.7.jar\org.springframework.cglib.core\AbstractClassGenerator.class:313)
- Enhancer.createHelper() (\spring-core-6.0.7.jar\org.springframework.cglib.proxy\Enhancer.class:562)
- Enhancer.createClass() (\spring-core-6.0.7.jar\org.springframework.cglib.proxy\Enhancer.class:407)
- ConfigurationClassEnhancer.createClass(Enhancer) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassEnhancer.class:138)
- ConfigurationClassEnhancer.enhance(Class,ClassLoader) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassEnhancer.class:109)
- ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassPostProcessor.class:514)
- ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.annotation\ConfigurationClassPostProcessor.class:304)
- PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Collection,ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.support\PostProcessorRegistrationDelegate.class:358)
- PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory,List) (\spring-context-6.0.7.jar\org.springframework.context.support\PostProcessorRegistrationDelegate.class:150)
- AbstractApplicationContext.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory) (\spring-context-6.0.7.jar\org.springframework.context.support\AbstractApplicationContext.class:747)
- AbstractApplicationContext.refresh() (\spring-context-6.0.7.jar\org.springframework.context.support\AbstractApplicationContext.class:565)
- ServletWebServerApplicationContext.refresh() (\spring-boot-3.0.5.jar\org.springframework.boot.web.servlet.context\ServletWebServerApplicationContext.class:146)
- SpringApplication.refresh(ConfigurableApplicationContext) (\spring-boot-3.0.5.jar\org.springframework.boot\SpringApplication.class:732)
- SpringApplication.refreshContext(ConfigurableApplicationContext) (\spring-boot-3.0.5.jar\org.springframework.boot\SpringApplication.class:434)
- SpringApplication.run(String[]) (\spring-boot-3.0.5.jar\org.springframework.boot\SpringApplication.class:310)
- FishApplication.main(String[]) (d:\a\prog\foodpang\purchase\fish\fish\src\main\java\co\foodpang\fish\FishApplication.java:24)
- NativeMethodAccessorImpl.invoke0(Method,Object,Object[])[native method] (\java.base\jdk.internal.reflect\NativeMethodAccessorImpl.class:-1)
- NativeMethodAccessorImpl.invoke(Object,Object[]) (\java.base\jdk.internal.reflect\NativeMethodAccessorImpl.class:77)
- DelegatingMethodAccessorImpl.invoke(Object,Object[]) (\java.base\jdk.internal.reflect\DelegatingMethodAccessorImpl.class:43)
- Method.invoke(Object,Object[]) (\java.base\java.lang.reflect\Method.class:568)
- RestartLauncher.run() (\spring-boot-devtools-3.0.5.jar\org.springframework.boot.devtools.restart\RestartLauncher.class:49)

[컴] JPA 의 entity 로 foreign key 설정하는 법

외래키 / hibernate / join / spring boot / spring / java / orm / 연결 / 관계 설정 / relation entity

JPA 의 entity 로 foreign key 설정하는 법

user table 의 profile_id 가 profile table 의 id 를 참조하도록 하는 예시이다.

아래 code example 이 있다.

import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;

@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "profile_id", referencedColumnName = "id", nullable=false)
    private Profile profile;

    ...
}
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToOne;

import java.time.LocalDateTime;

@Entity
public class Profile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @OneToOne(mappedBy = "profile")
    private User user;

create table user (id bigint not null auto_increment, profile_id bigint not null, primary key (id)) engine=InnoDB;
create table profile (id bigint not null, primary key (id)) engine=InnoDB;
alter table user add constraint FKl6pykqur53o90qdnhjko0r8ni foreign key (profile_id) references profile (id);

어느 값이 어느값을 가리키는지는 아래 그림을 참고하자.

연결

See Also

  1. Spring Data JPA One To One Relationship Mapping Example
  2. java - When Should I Use @JoinColumn or @JoinTable with JPA? - Stack Overflow

[컴] CQRS pattern

 

CQRS pattern

CQRS (Command Query Responsibility Segregation) 의 핵심은 read/write 가 구분된다는 점이다.

보통 우리가 client 라고 부르는 쪽에서 필요한 데이터를 가져올때(read) 와 변경사항을 저장할 때(write) 우리는 같은 model 을 사용한다.

그런데 CQRS 는 이것을 각자 다른 model 을 사용한다. 한 예는 read때는 read.myserver.com 을 사용하고, write 때는 write.myserver.com 을 사용한다고 봐도 된다.

간략하게 어떤 개념인지를 파악하는데는 마틴파울러의 글이 좋은 듯 싶다. 글에 있는 이미지도 이해를 하는데 도움이 된다.

  • 마틴파울러, CQRS
    • CQRS 의 사용을 주의하라고 한다. 이것은 복잡성을 증가시킬 요인이 크다고 이야기 한다.
    • 시스템의 일부에서만 사용하라고 이야기한다.

CQRS pattern - Azure Architecture Center | Microsoft Learn

CQRS pattern - Azure Architecture Center | Microsoft Learn 의 내용을 일부정리

CQRS 에선 command 는 update 할 때 query 를 read 할 때 쓰인다. 그리고 write 과 read 에 대해서 각자 다른 model들을 사용한다.

  • data 를 update 할 때는 command

  • data 를 read 할 때는 query

  • command 는 task based 여야 한다. data centric 이 아니라.

    • 예를 들어, ’호텔객실 예약’이라고 해야지, ’ReservationStatus 를 Reserved 로 변경’이라고 하지 않는다.
    • 한가지 방법은 command를 보내기 전에,
    • client에서 validation rule들 실행하고,
    • 버튼을 비활성화하고,
    • UI 에 이유를 설명하는 것
    • 예를 들면, ‘방이 남지 않았습니다.’
    • 이 방법으로 server 쪽 command 의 실패의 원인은 race condition 들(2개의 유저들이 마지막 방을 예약하려고 하는것)로 좁혀질 수 있다. 심지어 이런 때도 데이터와 로직(손님을 대기목록에 넣는 것)을 추가해서 해결할 수 있다.
  • command들은 synchronous 하게 처리되지 않고, queue 에 넣어서 asynchronous 하게 처리할 수 있다.

  • Query 들은 db를 변경하지 않는다. query는 도메인 지식을 캡슐화하지 않는 DTO를 반환한다.

이렇게 write 와 read 에 대한 model 을 분리하면, 설계(design), 구현(implementation)이 간단해진다.

isolation 을 강화하기 위해 물리적으로 read용, write용으로 db를 나눠도 된다. read 의 경우 필요한 join 등을 미리 해놓은 결과를 저장해서 보여주는 것처럼 다른 schema 를 사용할 수 있다. 이것은 materialized view 를 쓰거나, NoSQL 같은 다른 type 의 db 를 쓰는 등의 방법을 사용할 수 있다.

이 경우 write 에 사용하는 db 와 read 에 사용하는 db 의 동기화가 필요한데, 이때는 대체로 write db 에 update 가 발생할 때 event 를 발생시켜서 read db 를 update 하게 된다. 다만 이때의 문제는 db에 write 가 된 이후에 event 가 성공적으로 전달되지 못하는 경우 data 의 consistency 를 보장할 수 없다.

read store 와 write store read store 는 write store 의 복제본(read-only replica)이거나, write store 와 상관없이 다른 구조를 갖고 있을 수도 있다. - 여러개의 read-only replica 를 갖고 있으면, 이 replica 가 application instance 에 가까이 있는 경우, query 성능이 향상 될 것이다. - 보통 read store 의 부하가 더 높은데, read 와 write store 를 분리하면, 각각의 부하에 맞게 적절하게 확장이 가능하다.

CQRS 일부 구현은 event sourcing pattern 을 사용한다.

  • application 의 state 가 sequence of events 로 저장된다.
  • 각 event 는 data에 대한 set of changes 를 갖는다.
  • 그래서 이 event 들을 다시 실행하면, 현재의 state 가 되는 것이다.
  • event sourcing pattern 을 사용하면 design 이 복잡해 진다.

구현상 어려운점

  • 복잡성, 개념은 간단한데, application design 이 복잡하다. event sourcing pattern 이 들어가면 더 복잡하다.
  • 메시징, application 은 message 의 실패, duplicated message 에 대한 처리를 해야 한다.
  • Eventual consistency(최종 일관성) : read db 의 data 가 최신이 아닐 수 있다.(stale) 이렇게 stale data 를 기반으로 write 을 요청하는 경우도 있을 수 있는데, 그것을 구분하기 어렵다.

언제 CQRS pattern 을 쓰는가?

  • 많은 사용자가 동일한 데이터에 동시에 액세스 하는
  • 복잡한 프로세스를 안내하는 task-based UI 에서 쓸 수 있다.
  • 쓰기 model 보다 read model 의 성능이 더 중요한 경우, write에 비해 더 많은 read 가 있는 경우등에 유리, write model instance 가 적으면, merge conflict 발생을 최소화할 수 있다.
  • 한팀은 복잡한 domain model 과 write model 에 집중하고, 다른 한팀은 read model 과 UI 에 집중할 수 있는 상황이라면 사용할 수 있다.(me: 세부적인 내용은 다르겠지만, server side, client side 로 나눠서 개발하는 것과 비슷한 경우일듯)
  • 시간이 지남에 따라 진화하고, 여러 다양한 버전의 model 을 포함할 수도 있는 시스템
  • 비지니스 규칙이 정기적으로 변화하하는 시나리오
  • 다른 시스템들과의 통합, 특히 event sourcing 과 결합된 경우.
    • 하나의 sub system 의 일시적인 오류가 다른 sub system 으로 영향이 미치지 않아야 하는 시스템

쓰지 않는게 나은 경우

  • domain 이나 business logic 이 간단한 경우
  • 간단한 CRUD style 이면 충분한 경우

CQRS pattern 을 시스템의 제한된 부분(이 부분이 추후 중요해질 것이라 여겨지는)에 적용하는 것을 고려해보자.

예시들 best practices

[컴] 포토샵으로 변형된 얼굴사진 감별

 

얼굴 포토샵 감지 / 감별 / 확인 방법 / 뽀샵

포토샵으로 변형된 얼굴사진 감별

FAL detector, Face-Aware Liquify detector

Adobe Research와 UC Berkley에서 개발한 AI 기술인 FAL Detector는 포토샵의 Face-Aware Liquify’ 기능을 이용하여 왜곡된 이미지를 학습

Reference

  1. 유명인 얼굴이 어떻게 포토샵 처리되었는지 보여주는 AI 도구 등장 : 클리앙
  2. AI Tool Reveals How Celebrities’ Faces Have Been Photoshopped | PetaPixel