목록전체 글 (385)
만족

여러가지 nodejs 데몬 툴 중 forever와 pm2가 특히 유명한데, forever는 기능은 적지만 사용법이 매우 간단해 운영중인 nodejs 서비스에 사용 중이었다. 그러나 모니터링, 무중단 업데이트와 같은 다양한 기능들이 필요하게 되었고, 따라서 forever에서 pm2로 이주해보려 한다. https://pm2.keymetrics.io/ PM2 - Home Advanced process manager for production Node.js applications. Load balancer, logs facility, startup script, micro service management, at a glance. pm2.keymetrics.io PM2 Nodejs 데몬 프로세스 매니저다. 단순..

Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState at androidx.fragment.app.FragmentManager.checkStateLoss(FragmentManager.java:1844) at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1884) at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:329) at androidx.fragment.app.BackStackRecord.commit..
마이렛저는 광고 표시를 위해 Google Admob을 사용하고 있습니다. 광고 표시를 위해 Admob에서 일부 정보를 수집할 수 있으며, 이 정보는 개발자에게 전달되는 것이 아니며, Admob에서 최적화된 광고 표시를 위해 자체적으로 사용합니다. Admob의 개인정보 처리방침은 Google 개인정보 처리방침을 따릅니다. https://policies.google.com/privacy?hl=ko 개인정보처리방침 – 개인정보 보호 및 약관 – Google 방침 정보 이 방침의 적용 이 개인정보처리방침은 YouTube, Android, 타사 사이트에서 제공되는 서비스(예: 광고 서비스)를 포함해 Google LLC 및 계열사가 제공하는 모든 서비스에 적용됩니다. 이 개인 policies.google.com 개..
Android Studio에서 JDK 버전을 업데이트하려면 다음 단계를 따르세요. 공식 웹 사이트( https://www.oracle.com/java/technologies/javase-downloads.html ) 에서 최신 JDK 버전을 다운로드하여 설치합니다 . Android Studio를 열고 파일 > 프로젝트 구조로 이동합니다. 프로젝트 구조 대화 상자의 왼쪽 메뉴에서 SDK 위치를 선택합니다. JDK 위치에서 경로 옆에 있는 줄임표 버튼을 클릭하고 최신 JDK 버전을 설치한 위치를 선택합니다. 적용을 클릭한 다음 확인을 클릭합니다. 변경 사항을 적용하려면 Android 스튜디오를 다시 시작하세요. 그게 다야! 이제 Android Studio에서 설치한 최신 JDK 버전을 사용합니다. -----..

CLS(Cumulatie Layout Shift) 누적 레이아웃 변경 수치를 말한다. 예를 들어 img 태그에 가로/세로값을 지정하지 않았을 때, 이미지 로딩이 끝난 이후에야 크기를 추정할 수 있으므로 이미지 로딩 중에는 크기가 0으로 추정되고 로딩이 끝나고 나면 크기가 결정되어 레이아웃의 위치가 변경된다. 네트워크의 속도가 느리거나, 크기를 지정하지 않은 이미지의 갯수가 많은 경우 많은 레이아웃 이동이 발생하고, 레이아웃의 이동은 사용자가 의도하지 않은 항목의 클릭과 같은 문제로 UX가 저해된다. 이것을 수치화시킨 것이 CLS 수치이다. (lower is better) CLS 측정하기 크롬 개발자 도구의 lighthouse 를 이용해 측정할 수 있다. 이미지와 글밖에 없는 간단한 html이지만 벌써부터..
전면 광고가 성공적으로 로딩되었음에도 로딩되지 않는 현상이 포착되었다. 조건 만족 시 전면 광고 로딩이 실패하거나 표시된 후 다음 동작이 실행되었기 때문에 매우 치명적인 문제였다. 오류 설명 코드에서는 전면 광고를 담당하는 로직을 분리해 별도의 클래스에서 관리하고 있었다. public void load(Context context) { mInterstitialAd = new InterstitialAd(context); if (BuildConfig.DEBUG_MODE) { mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712"); } else { mInterstitialAd.setAdUnitId("AD_UNIT_ID"); } mInters..

골든래빗 출판사로부터 책을 제공받아 작성했습니다 -골든 래빗 출판사- 소위 말하는 '고수' 분들의 이야기를 담은 책이다. 작년에 대학을 졸업하고, 올해 개발자로서 1년차를 맞이하게 되었기 때문에 어떻게 내 커리어를 만들어갈 지에 대한 고민이 많던 중 이라는 책의 리뷰어를 신청해 선정되었다. 어떤 내용인가? 사실 책의 표지에서 풍기는 분위기로는 딱딱하게 풀어갈 줄 알았지만, 저자와 커피 한잔 하며 궁금한 것을 대답해 주는것만 같은 편안한 분위기로 내용이 진행된다. 책의 추천사에서도 말했듯이, '꼰대스럽지 않게' 생각의 방향을 제시해준다. 목차 1. 덕업일치를 넘어서 2. 오류를 만날 때가 가장 성장하기 좋을 때다 3. 소프트웨어 디자인 원칙 4. 나의 메이저 버전을 업그레이드하는 마이너 원칙들 5. 이직,..

갑자기 정책 위반 관련 메일을 받고 수익창출이 아예 틀어막혀버렸다. 원인 파악과 의심되는 원인을 수정하는 과정을 소개한다. (정확한 문제를 알려주지 않아 추정해서 수정해야 한다) 원인 파악 1: 다른 액티비티에 의해 전면 광고가 가려질 수 있음 현재 사용중인 광고는 전면 광고, 배너 광고, 네이티브 고급 광고이다. 배너 광고와 네이티브 고급 광고는 구조적으로 가려질 수 없었기에 전면 광고를 의심했다. 내 앱의 전면 광고 표시 로직을 요약하면 다음과 같다. 1. 액티비티를 새로 여는 동작이 감지됨 2. 액티비티를 여는 동작을 인터셉트하여 중지시키고, 전면 광고 데이터가 로딩 완료되었는지 체크 3-1. 예) 전면 광고를 표시하고 광고가 닫힌 후 액티비티 여는 동작 마저 실행 (3-1이 한번 실행된 이후에는 ..

컴알못, AS 편의성을 중요하게 생각하는 사람들을 대상으로 하여 '사무용~가벼운 작업/게임이 가능'한 '국내 AS 지원이 좋은' 울트라북 노트북을 소개한다. 어차피 컴잘알들은 알아서 찾을 수 있잖아... 2023.02.06~14까지 진행되고, 여름 전까지는 아마 없을 것 같으니 이번에 구매하는게 좋다. https://www.gmarket.co.kr/e/bigs/digital/tab4 [G마켓] 디지털·가전 빅세일! 올해 최고의 쇼핑찬스 단 9일, 누구나 3일마다 최대 20만원 할인 혜택! www.gmarket.co.kr + 돈받은거 없고 노트북 바꿀까 고민하면서 그냥 정리해봤다. 삼성 갤럭시북2 NT550XEZ-A58A (49만원) http://item.gmarket.co.kr/Item?goodscode..
렌더링 타임에 state의 갯수가 달라져서 발생하는 오류다 const Mycomponent= ()=>{ const [foo, setFoo]= useState(''); if(foo!== ''){ const [bar, setBar]= useState(''); } return ( setFoo('foo')}>버튼); } 위 코드에서는 버튼을 클릭하기 전에 state가 한 개(foo) 였다가, 버튼을 클릭하고 나면 const [bar, setBar]= useState(''); 에 의해 state가 하나 더 생긴다. 이런 경우 발생하는 오류이므로, state의 갯수는 조건과 관계없이 동일하도록 변경하고, 그 state에 따른 사이드이펙트를 조건부 처리하는 방식으로 수정한다.

프로젝트에서 githook을 이용해 커밋 전 검사를 하고 있다. yarn eslint ./src --cache && tsc --noEmit && yarn test 3개의 커맨드가 모두 정상적으로 종료되어야만 커밋되고, 이 작업들은 현재 의존성을 가지고 있어 이전 작업이 끝나야만 다음 커맨드가 실행된다. (yarn eslint ... > tsc ... > yarn test...) 정말 의존성이 필요할까? eslint는 js, jsx파일의 코드 포맷 검사, tsc는 ts, tsx파일의 코드 유효성 검사, test는 테스트를 수행한다. 사실 이들의 순서가 바뀌어도 상관없고, 심지어는 동시에 실행되어도 결과에는 영향을 미치지 않는다. 위 명령을 실행하면 약 20~30초가량이 소모되는데, 점점 프로젝트의 규모가 ..

웹 개발을 하다보면 특이한 경험을 한 적이 있을 것이다. 김흥국이 나온 대학교는? 구글로 이동 예를 들어, 이 코드에서는 처음에 '김흥국이 나온 대학교는?' 이 표시되고 3초 뒤 '으아 들이대 ㅋㅋ'가 표시된다. ㅋㅋㅋ 그렇다면 다른 페이지로 이동한 다음 뒤로가기로 페이지로 돌아오면 어떻게 될까? 여전히 '김흥국이 나온 대학교는' 이 표시되고 3초 뒤 '으아 들이대 ㅋㅋ'가 표시될까? 로딩도 없이 바로 '으아 들이대 ㅋㅋ'가 표시된다. 어떻게 된 일일까 bfcache(back/forward cache)가 작동했기 때문이다. 브라우저에서는 조건에 맞으면 페이지를 벗어나기 전에 memory snapshot을 찍어두고, 다시 돌아왔을 경우 이를 복원해 사용자에게 표시한다. 리소스를 다시 다운로드하고, 스크립트..

//... const router= useRouter(); useEffect(()=>{ //... }, [router]); //... 이런 코드가 있을 때, bfcache로부터 페이지가 복원된다면 어떻게 될 것 같은가? 내 생각에는 당연히 memory snapshot을 복구했으니 router가 업데이트되지 않을 것이라고 생각했다. 실제로 데스크탑 크롬에서는 그렇게 동작한다. 그런데 모바일/데스크탑 사파리와 모바일 크롬, 삼성 브라우저에서는 router가 업데이트된다. 아래 코드를 기준으로 설명할 것이다. (원본 코드는 https://github.com/NamGungGeon/why-router-is-updated 에서 확인할 수 있다) // page/index.js function Home() { cons..

리액트 프로젝트를 빌드하면 나오는 결과물들을 간단히 다음과 같이 분류할 수 있다. 1. css 2. js 3. html 4. asset (png, svg ...) 이들에 관해 어떻게 캐시 전략을 세울 수 있을까? css, js css와 js는 빌드할때마다 결과물이 변경될 경우 파일네임 중간의 해시값이 바뀌게 된다. 예를 들어 처음 빌드했을 때 다음과 같은 빌드 결과물이 나왔다면, js코드를 일부 수정하고 다시 빌드했을 때 이런 식으로 js가 변경되었으므로 main.[HASH].js 에서 HASH가 업데이트된다. 따라서 같은 이름의 css, js는 다시 로드할 필요가 없고, 영구적으로 캐싱하기로 결정했다. (빌드 결과물에서 직접 코딩하는게 아닌 이상... 어차피 빌드 파일 이름이 변경되므로 영구캐싱이 타당..

이번에 전면 광고의 로딩 시점과 표시 시점을 변경하여, 그렇게 변경한 이유와 장점에 대해 소개한다. 기존 기존에는 스플래시 화면이 초기화될 때(onCreate)에서 로딩을 시작하고, 3초를 기다리거나 그 전에 광고가 로딩된 경우 표시했다. 그러나 admob의 응답 속도는 그다지 빠르지 않으며, 네트워크가 느린 환경에 있는 유저도 꽤나 많았기 때문에 노출률이 그다지 높지 않았다. https://satisfactoryplace.tistory.com/133 [Android] Google Play - 앱, 타사 광고, 기기 기능 방해 정책 위반 갑자기 다음과 같은 메일이 날라오며 앱 업데이트가 거부되었다. 의아한 것은 해당 업데이트 내용은 버그 수정 및 편의성 강화로써 광고 관련 코드는 수정된 바가 전혀 없다는..

현재 시간 기준으로 타겟SDK가 31 미만인 경우 업데이트 제출이 불가능하다. 추후 또 기준이 변경되면 올리고 문제찾고 해야하는데 이것이 귀찮기 때문에.. 이번에 33까지 한번에 올렸다. 아니나다를까 오류가 우수수 쏟아졌는데 하나씩 해결법을 설명하겠다. kaptDefaultsDebugKotlin ... InvocationTargetException Execution failed for task ':app:kaptDefaultsDebugKotlin'. > A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction > java.lang.reflect.Inv..

요약 맥에서 mx keys시리즈 키보드에서 f1~f2가 눌리지 않는 현상은 카라비너(karabiner)등의 키 맵핑 유틸리티와 충돌을 일으켜 발생하는 문제다. 해당 유틸리티에서 mx keys mini에 대한 매핑 정보를 날려주면 된다. https://m.blog.naver.com/bzwon/221953747472 로지텍 MX Keys - Karabiner Elements 설정 로지텍 MX Keys 리뷰 포스팅 링크 본 포스팅은 OSX 사용 환경에서 로지텍 MX keys의 한/영 전환 설... blog.naver.com
시간없어서 일단 참고링크만 걸어두고 나중에 작성할 예정 https://medium.com/@niraj_prajapati/automate-android-app-publishing-on-play-store-using-github-actions-554de7801c36 Automate Android App Publishing on Play Store using GitHub Actions In this post, I’ll show how I managed to automate android app publishing on Play Store. medium.com https://github.com/r0adkll/upload-google-play/issues/127 Error: Invalid value at 'tra..

웹 서버를 구성할 때 가장 간단하면서 흔한 LAMP Stack(Linux, Apache, Mysql, Php)를 사용하고 별다른 설정을 하지 않았다면 이 포스트가 도움이 될 것이다. 기본적으로 prefork기반의 mpm을 사용하게 되는데, prefork방식은 요청 1개가 프로세스 1개에 대응되기 때문에 사용자가 늘어날 수록 메모리 사용량이 급증한다. (30~40%정도의 메모리를 사용하고 프로세스의 갯수도 매우 많다) 나 역시 이 문제를 해결하기 위해 event기반 mpm으로 변경했다. mpm은 어떤 종류가 있을까? 종류별로 어떤 장단점이 있을까? 어떻게 변경할 수 있을까? 한번 알아보자 Apache mpm prefork (기본값) 프리포크 방식은 한 개의 프로세스가 한 개의 연결을 처리한다. 아파치 설치..

2600x+b350m 쓰다가 5600x로 올렸는데 바이오스 업뎃하면서 설정이 날아가가지고 램타이밍값을 다시 잡기 어려웠다. 왜냐면 18년도에 램값개비쌀때 싼거 하나 집어온거라 국민오버도 안먹는 개뿔딱 게일램이기 때문이다. 뭔짓을해도 2933클럭 위로는 먹지를 않는데, 너도 뿔딱이라면 아래 값으로 한번 3200에 도전해보기 바란다. 설정값 램타이밍: 18-20-20-20-40 램클럭: 3200Mhz 램전압: 1.25V 램전압은 맨날 1.3, 1.35주다가 라이젠은 오히려 전압을 낮게 줬을때 오버가 잘먹는다는 글을 봐서 1.25로 해봤더니 잘되더라~