728x90

특별한 풀이까지는 아니고, 차근차근 풀어가는 과정을 담아보았습니다.

프로그래머스 답 제출 후에 보면

번뜩이는 풀이들도 있으니 한번쯤 보면서 이런 방법들도 있구나 찾아보면 좋을 것 같습니다.

 

문제는 아래와 같습니다.

 

문제 설명

어떤 게임에는 붕대 감기라는 기술이 있습니다. 붕대 감기는 t초 동안 붕대를 감으면서 1초마다 x만큼의 체력을 회복합니다. t초 연속으로 붕대를 감는 데 성공한다면 y만큼의 체력을 추가로 회복합니다. 게임 캐릭터에는 최대 체력이 존재해 현재 체력이 최대 체력보다 커지는 것은 불가능합니다. 기술을 쓰는 도중 몬스터에게 공격을 당하면 기술이 취소되고, 공격을 당하는 순간에는 체력을 회복할 수 없습니다. 몬스터에게 공격당해 기술이 취소당하거나 기술이 끝나면 그 즉시 붕대 감기를 다시 사용하며, 연속 성공 시간이 0으로 초기화됩니다. 몬스터의 공격을 받으면 정해진 피해량만큼 현재 체력이 줄어듭니다. 이때, 현재 체력이 0 이하가 되면 캐릭터가 죽으며 더 이상 체력을 회복할 수 없습니다. 당신은 붕대감기 기술의 정보, 캐릭터가 가진 최대 체력과 몬스터의 공격 패턴이 주어질 때 캐릭터가 끝까지 생존할 수 있는지 궁금합니다. 붕대 감기 기술의 시전 시간, 1초당 회복량, 추가 회복량을 담은 1차원 정수 배열 bandage와 최대 체력을 의미하는 정수 health, 몬스터의 공격 시간과 피해량을 담은 2차원 정수 배열 attacks가 매개변수로 주어집니다. 모든 공격이 끝난 직후 남은 체력을 return 하도solution 함수를 완성해 주세요. 만약 몬스터의 공격을 받고 캐릭터의 체력이 0 이하가 되어 죽는다면 -1을 return 해주세요.

 

풀이

1. 필요한 변수 정리

필요한 값들을 먼저 정리합니다. 주어진 값들을 통해서 쓰기 편하도록 정리해둡니다.

    const maxHealth = health;
    const [time, healPerSec, additionalHeal] = bandage;
    const attackTime = []; // 공격시기
    const attackDmg = []; // 공격 데미지
    var success = 0;		// 연속성공
    var attackCount = 0;	// n번째 공격

    attacks.forEach((item)=>{
        attackTime.push(item[0])
        attackDmg.push(item[1])
    })

 

2. 0초부터 하나씩 올라가는 루프 함수인 for 사용합니다

공격이 있을 때와 공격이 없을때를 나누어서 로직을 구성합니다.

공격이 있을때는 health가 0이 되거나 혹은 모든 공격이 끝났을 때 해당 for 문을 벗어납니다.

for(var i=0; i <= attackTime[attackTime.length-1]; i++){
        if(i === attackTime[attackCount]){
            health = health - attackDmg[attackCount];
            if(health <= 0) return -1
            if(attackCount === attackTime.length-1) break;
            attackCount++;
            success = 0;
        } else {
             success++;
            health = Math.min(health + healPerSec, maxHealth);
            if(success === time) {
                health = Math.min(health + additionalHeal, maxHealth);
                success = 0;
            }

        }
    }

 

그리고 health 값을 리턴해주면 끝납니다!!

 

저 같은 경우에는 중간에 전체 공격이 끝났을때 break 해주는 조건을 빼먹고 했더니,

테스트는 통과 하지만 제출 후 채점에서는 박살나더군요..

 

무튼, 특별하지는 않지만 머리속에 플로우를 그대로 편안하게 옮겨보았습니다.

번뜩이는 풀이들을 보고 공부도 필요하고, 이렇게 차분하게 흐름 따라서 짜는 연습도 좋은것 같습니다 :)

또 긴장하는 코테에서 번뜩이기 쉽지 않을 것 같기도ㅎ

728x90
728x90

 

예상치 못한 에러 처리 등을 위해서 루트쪽에 
<ErrorBoundary> 컴포넌트를 추가해서

에러를 관리한다. 오늘은 이를 가볍게 만들고

어떻게 테스트하는지 가볍게 알아보고자 한다!

 

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    //
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback;
    }

    return this.props.children;
  }
}

 

위는 기본적으로 리엑트 document에서 제공하는 errorboundary의 모습이다. 

https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary

 

Component – React

The library for web and native user interfaces

react.dev

 

 

클래스형을 기본으로 제공해준다. 후에 함수형으로 변환해보는것도..

그리고 나서는 원하는 프로젝트를 감싸준다. 그러면 끝!

<ErrorBoundary>
	<MyProject />
</ErrorBoundary>

 

이제 만들었으니 테스트를 해봐야겠죠?

테스트를 위해서 Errorboundary class 내부에 에러발생 함수를 추가하고

버튼을 클릭해서 에러를 유도했다.

 

triggerError = () => {
throw new Error('Intentional 500 Error');
};
 
....
 
render(){
...
<div>
    <button type="button" onClick={this.triggerError}>
     Trigger 500 Error
     </button>
    {this.props.children}
</div>
}

 

 

하지만 Uncaught runtime errors 만 발생할 뿐 

원하는 방향으로 처리 되지 않았다.

콘솔값을 확인해 보니

this.state.hasError 값이 바뀌지 않았던 것.. 왜와이??

 

이유는 Errorboundary가 처리하지 않는 에러가 있기 때문이다.

1. 이벤트 핸들러

2. 비동기적 코드

3. SSR

4. 에러바운더리 스스로 던진에러

 

 

위 4가지에 대해서는 잡지 않는다.

따라서 내가 유도한 버튼은 4번에 해되기에 

에러를 잡지 않는것이다.

 

따라서 Errorboundary 클래스에서

아예 다른 컴포넌트로 버튼을 분리하고 에러를 발생시키면

this.state.hasError 값이 바뀌고 확인해볼 수 있다.

 

물론 이 상황에서도 무섭게

Uncaught runtime error alert창은 발생하지만,

이는 development 모드에서만 발생하지

빌드 후 production 에서는 발생하지 않기 때문에 걱정하지 않아도 된다.

 

728x90
728x90

 

GPT를 시작으로 AI 발전이 무섭다.

계속해서 새로운 것들이 나오고 있다. 

하지만 아직도 GPT 만 무지성으로 사용할 것인가!

라는 것에서 출발해서 다른 모델을 하나 추천해보려고 한다.

 

바로

클로드 3 Opus 

이다.

 

기본적으로 업계 벤치마크 테스트에서

GPT와 Gemeni를 제쳤다고 하니.. 한번 정도 찍먹할 가치는 충분하다고 본다. 

또한 설명상 기계에게 인권을 주는 접근을 하고있고(?)

분야에 따라 적합한 어휘와 문법을 사용하며

더 높은 수준의 어휘까지도 사용가능하다고 강조하고 있다.

 

claude.ai

 

Claude

 

claude.ai

 

 

여기에 접속해서 구글계정 등을 통해서 가입하면 사용할 수 있다.

가입하고 나면 아래와 같은 단계를 몇개 거친다.

 

 

그러고 나면..! 본격적으로 사용할 수 있다.

기본적으로 이런 류의 친구들과 같이 중앙의 채팅창에 원하는 바를 요청하면 된다.

른 것보다 뭔가 좀더.. 친근한 느낌이 괜히 든다

데이터는 2023년 8월을 최신으로 가지고 있다고 한다.

 

사진이나 파일을 첨부할 수 있다! 무료료!! GPT 무료버전은..

물론 누군지는 알아보지 못했지만,

어린 여자, 짧고 검은 머리, 큰 눈, 빨간 입술, 터틀넥 등의 입고 있는 것들을

해석해 준다. 

사진을 첨부할 수는 있지만, 이미지를 출력해 주지는 못한다!

 

 

그 후에도 코딩이나 몇몇 시답잖은 질문들을 던진 것에 대해 스무스하게

답해주었다. 그런데 갑자기.. 

 

어라랍스타..

아직은 베타라 무제한으로 사용하지 못하고

일일 용량 제한이 있다고 한다.. 아앗... 생각보다 짧긴 하다.

 

 


 

물로 아직 베타고 이런 제한이 있는 모델이지만, 

간간히 질문을 던지면서 

자신의 분야에서

만족할만한 답을 잘 주는지 확인해 보는 것도 좋은 것 같다.

이 친구들이 밥그릇을 얼마나 빨리 먹어버릴지 모르지만

지금은 어떤 친구를 옆에 두고

잘 이용하는지가 중요한 시기인 것 같으니 말이다.

 

 

 

728x90
728x90

 

우리가 많이 보는 크롬의 url 창이다.

익숙한 naver.com 등 앞에는 항상 추가로 붙는 부분이 있다.

뭐 항상 봐서 그렇게 신경이 쓰이지 않지만

한번 속 썩이는 일이 생겼다.

localhost와 같이 말이다.

 

간단히 정의만 체크해보쟈

 

HTTP

hyper text trasfer protocol의 약어로 서버 간에 통신을 위한 규칙이나 프로토 콜을 의미한다.

유저가 브라우저에서 무슨 행동을 하면 브라우저는 

웹 서버에 HTTP요청을 하고, 웹 서버는 또 그에 대한 HTTP 응답을 해요. 데이터를 텍스트로 교환해 주는데

그냥 네트워크 통신이 가능하게 하는 기본 기술이다! 생각하면 편하다

 

하지만 이 방식은 브라우저에서 전송된 정보를 나쁜 제삼자들이 가로챌 수 있어서 보안성이 떨어진다.

그래서 나온데 HTTPS!!

 

HTTPS

HTTP에 Secure 가 붙은 단어이다.

이 프로토 콜에서는 보안을 위해서 데이터를 교환하기 전에 인증서를 공유하여

SSL(Secure Sockets Layer) 인증서 암호화 정보도 함께 담아서 보내주죠! 그래서 함부로 제삼자가 볼 수 없는 게 되었다

 


 

 

 

웹뷰 작업을 하기 위해 개인 로컬 웹뷰를 react-native에 연결할 일이 생겼었다. 

 

내 로컬에 주소를 연결하는데

https://localhost:3000.......

로 작성해 두었다. 과연 연결이 잘 되었을까?

NOPE.

 

뭔가 연결이 잘 안 된 건가 싶어서 다른 원인들을 찾았지만

정답은 https 이 녀석이다.

 

localhost는 https대신에 https를 사용한다.

위 정의에 따라서 https는 인증서가 있어야 하는데,

로컬에서 인증서가 필요로 하지 않는다

그렇기에

http://localhost..로 연결해주어야 하는 것이다.

 

 

 

 

 

 

728x90
728x90

 

개발자 모드가 없었다면 어찌 프런트 개발을 했을까

콘솔도 찍어주고, warning , error에 대한 디테일한 부분까지 보여준다.

또한 로컬 스토리지, 쿠키 등의 정보도 표시해준다.

 

좀 더 맛있게 개발자 모드를 사용 하기 위해 한 가지를 추천한다.

 

렌더링 탭 진입하기

기본적으로 상단에 요소, 소스, 콘솔 등과 표시 되지 않는다. 따라서 렌더링 탭을 확인하려면 우상단 세로로 된 more(...) 아이콘을 클릭해서 열어야한다. 렌더링 탭의 다른 옵션들도 좋으니 한번 정도 클릭해보는 것을 추천한다.

 

 

렌더링탭 / 코어 웹 바이탈

해당 부분에 대해서 약간 살펴보고자 한다. 해당 기능을 체크하면 성능을 표시해주는 상자가 나온다.

 

저 중에서 Largest Contentful Paint, 줄여서 LCP라고도 하는 이 친구는 로딩 성능을 측정하는 지표이다.  

로드 시작을 기점으로 가장 큰 이미지나 텍스트의 렌더링 시간이다.

2.5s 이내의 값이 나와야 좋은 사용자 경험을 제공하는 페이지라고 할 수 있다. 한번 정도 자기프로그램의 LCP를 확인해보기 바란다.

네이버는 많은 정보를 불러옴에도 불구하고 평균적으로 0.8s 이전의 값들이 나온다.  

 

개발중인 페이지가 이미지를 많이 불러오고 있기는 한데 8.80s 이라는 말도 안되는 수치가 나와서 당황.. 

해당 부분들에 대해서 수정이 필요함을 절실하게 느낄수있다

 

개발중인 페이지가 2.5s 이내로

나오는지 체크해보고 넘는다면

리소스를 줄이거나 (이미지 크기 최적화), 스타일 시트의 크기를 줄이는 등의

방법으로 LCP를 줄여보는것을 권한다!! (일단 저부터)

 

 

 

 

 

728x90
728x90

 

오늘은 5월에 진행되는 이벤트 하나를 소개하려고 해요!

5/16~17 코엑스에서 AWS Summit seoul 행사가 열립니다.

 

자세한 정보는 아래 링크를 참고해 보세요

https://aws.amazon.com/ko/events/summits/seoul/

 

AWS Summit Seoul

30+ 산업별 강연, 25+ 고객 사례, 20+ AWS 및 파트너 부스 생성형 AI, 기계학습 및 지속가능성 등 최신 클라우드 트렌드와 활용도 높은 기술을 함께 소개하고, 산업별 AWS 솔루션을 통해 달성한 다양한

aws.amazon.com

 

 

여러 분야의 리더들의 연설을 통해서 최신 IT트렌드와 AWS 서비스를 한눈에 파악할 수 있는 좋은 기회예요.

15일, 16일 둘로 나뉘어서 

9시 반부터 6시까지 , 목요일 금요일 진행돼요. (8시부터 등록!!)

 

 

목요일에는 산업별 비즈니스 트렌드에 대해,

그리고 금요일에는 생성형 AI 기반의 기술 혁인에 대한 주제로 다룹니다.

3/15 일 기준으로 금요일 강의는 구체적으로 나오지 않았고 목요일만 나와있네요

목요일 강의 분야는 아래와 같습니다

 

 

[목요일]

생성형 AI

신기술 트렌드

산업 트렌드

금융 및 핀테크

통신, 미디어 및 엔터테인먼트

유통 및 소비재 상품

제조 및 하이테크

비즈니스 인사이트

공공 부문

게임 데이

 

 

아래 링크에서 분야별 발표제목과 발표자를 확인할 수 있어요!

관심 있는 분야의 발표자에 대해 미리 확인해 보는 것도 좋겠죠?

https://aws.amazon.com/ko/events/summits/seoul/agenda/

 

AWS Summit Seoul | Agenda

Race for prizes, glory, and a chance to advance to the AWS DeepRacer Grand Finale to compete for the coveted AWS DeepRacer Championship Cup. Build and train a reinforcement learning model at a workshop, or bring one you have trained at home. You can then p

aws.amazon.com

 

 


 

 

나는 관련 없는 분야다~ 

하고 넘기지 말고 한번 찬찬히 살펴보시길 추천드려요

개발자에게 최근 트렌드를 접하고 느낄 수 있는 기회는 

많으면 많을수록 좋다고 생각하거든요.

또한 IT를 이끌고 있는 탑 리더들의 자리에서는

얻어가는 게 많을 것이라고 생각되기도 하고요!

 

회사에 개발자 개발을 위해 보내달라고 해보세요!!

 

728x90
728x90

 

기본적인 스킨 중 하나인 나의 블로그

 

유독 아래 recent posts 사진 비율 깨지는 게 눈에 보인다.

으윽... 이런 블로그의 첫인상에서 일그러짐이 보이게 나둘수는 없다.

물론 애초에 올릴때 대표사진이나, 첫 사진을 이쁜 비율로 잘라 올릴 수도 있지만.. 너무 귀찮

수정해 보자 조금만 이쁘게..!

 

 

1. 스킨 편집 클릭!

블로그 설정하는 사이드 바에서 스킨 편집을 클릭한다!

 

 

 

 

2. HTML 편집 클릭

 

3. CSS 클릭!

그러면 css 관련된 코드가 아래 쭈르르르르륵 보인다. 쫄 필요 없다!

recent-post ul li img 를 ctrl + F 를 통해 찾기
 
이중 우린 위에 #을 수정할것이다. 수정 시 오류날 수 있다는 문구.. 괜찮다. 혹시 문제 생기면 
다시 스킨으로 덮으면 그만이다!

4.  min-height: 100% 삭제

 #recent-post ul li img에 있는 내용 수정할 것이다!!!!

그중에 min-hight: 100% 

해당 라인을 지우고 나서 ctrl+S 를 눌러준다. 아예 삭제!!

그러고 나서 왼쪽에 있는 미리 보기 화면을 보면 이렇게 정상적인 비율의 사진이 나온다. 유후~

하지만 아직 뭔가 애매하다. 다 천장에 붙어있다..

 

5. 사진 정렬 중앙에 맞춰주기!

이번엔

#recent-post ul li 를 찾고
display: flex;
align-items: center;
 
값을 추가해준다!!

 

파랑 하이라이트가 추가된 부분이다!

 

그리고 적용을 누르면 사진이 가운데에 잘 배치된 것을 볼 수 있다. 그리고 [적용]을 클릭하고 블로그 홈으로 돌아오면

쌈뽕 한 내 AK.. 아아

야무지게 배치된 사진들을 볼 수 있다!

After
Before

 

 


 

생각보다 html css 수정 자유도가 높아서 원하면

커스터마이즈를 조금 더 해볼 수도 있을 것 같다.

일단은 여~까지.

728x90
728x90

 

돌고 돌아온 VSCode 업데이트 맛보기

오늘은 v1.87 입니다.

정확히는 오늘 날짜로 Update 1.87.2까지 나왔군요

바로 확인해 보시죠!

 

제가 재밌어하는, 제 위주의 몇몇 부분만 가지고 왔기에

전체 릴리즈 노트를 보고 싶으신 분들은 아래를 참고해 주세요

 

https://code.visualstudio.com/updates/v1_87

 

 

 

Multiple Cursors Completion

기존에도 맥북 기준으로 여러 라인을 동시에 타이핑 및 수정할 수 있었어요.

[option] + [command] 누른 상태에서 위아래 방향키를 누르면 해당 라인까지 같이 수정이 가능하죠.

하지만 그렇게 작업 시 자동완성이 메인 라인에만 적용되는 현상이 있었어요.

이제는 패치가 되어서 동시에 가능하답니다! 

Setting in Release Note

 

릴리즈 노트를 읽다 보면 아하 이런 게 추가되었구나.. 하지만 또 직접 해보기는 귀찮은 게 사실에요.

하지만! 이제 릴리즈 노트에서 바로 새로운 세팅을 설정해 볼 수 있어요.

릴리즈 노트에서 톱니바퀴를 클릭하면 관련 세팅페이지로 바로 넘어갈 수 있어요!

 

 

새로운 기능을 이제 편리하고 빠르게 적용시켜 볼 수 있겠죠?

참고로 릴리즈 노트 빠르게 여는 저만의 방법은

맥 기준 [command] + [shift] + [p] 누르고 'release' 치면 최상단에 나온답니다! 

나오면 바로 X 누르던 그 릴리즈 노트, 오늘 한번 열어보는 건 어떨까요 ㅎㅎ

 

 

 

Command duration tracked

실행한 명령어에 한해서 기록을 볼 수 있습니다.

저 라인 가장 왼쪽 파란색 원에 마우스를 hover 하면 해당 명령어에 대해,

언제, 얼마나 걸렸는지에 대한 정보가 보입니다.

 

Close all Unmodified file

개인적으로 제일 맘에 드는 기능입니다.

작업하다 보면 수정하지 않은 많은 파일들이 탭에 쌓여 있어서 원하는, 작업하는 파일 찾기가 귀찮아집니다.

이때!!! close all unmodified file 명령어를 실행하면 모두 닫을 수 있습니다!!!

실행방식은 위에 릴리즈 노트 여는 것과 같습니다.

맥 기준 [command] + [shift] + [p] 누르고 Close all unmodified editors 명령어를 실행하면

작업하지 않은 탭들이 정리됩니다!!!!!! 멍꿀멍꿀

 

 


 

 

copilot 관련한 패치가 많은데,

해당 부분은 제가 사용하지 않아서 올릴 수가 없군요..

써봐야 하나...

사용하는 분들은 한 번씩 참고해 봐도 좋을 것 같아요

그럼 오늘도 열코딩!

728x90
728x90

 

process.env.NODE_ENV = 'production'

 

몸 담고 있는 곳의

정책별로 상이할 수 있지만 보통 개발할 때 서버를

development / stage / production

나눠 사용한다.

 

너무나 귀엽게도 난

NODE_ENV 값이

stage 나 production에서는  production,

개발계에서는  development

라고 생각했다..

 

하지만 저 3개의 서버에서 

NODE_ENV 값은 모두 production 이 나온다. 

저만 바보예요? 네 맞아요

 

지금껏 development, production 표시를 보고 그거겠다~

싶은 무생각 논리가 불러온 대단한 착오였다. 생각하며 코딩하기.. 메모..

당장 코드를 한 두줄만 읽어 보더라도 절대 그럴 수 없음을 확인할 수 있었다.

혹시나 그렇게 그러려니 생각했던 분이 계시다면..

아닙니다!!

 

 

process.env.NODE_ENV 값은?

nextjsd에서 기본적으로 해당 값은 아래와 같다.

 

[실행 명령어]     =>  [process.env.NODE_ENV]

npm run dev    => development

npm run build  => production

npm run start   => production

 

각각의 서버에서는 보통 빌드해서 돌리기 때문에 해당 값이 production으로 떨어진다.

개발 서버라고 'development'라고 나오지 않아요!!ㅜㅠ

 

 

환경변수 설정해 보기

그렇다면..?! 우리가 원하는

그 개발 서버임을 확인하는 방법은..?

 

 

루트 폴더에 있는 해당 파일들에 변수를 설정해 두면 된다. 

우선순위는 env > env.dev... or env.production이다. 상세한 파일이 우선순위가 더 높다.

 

그러고 나면 화면에서process.env.NEXT_PUBLIC_QWERTY로 접근가능하다.

next에서 설정 시 앞에 NEXT_PUBLIC  prefix를 꼭 붙여 줘야만 한다~!

prefix가 없으면 Node.js 환경에서만 읽을 수 있다.

 

NEXT 프로젝트에서 prefix 없는 변수는 /page에서만 읽을 수 있고,

클라이언트단 페이지에서는 undefined 값이 나오는 것을 직접 확인해 볼 수 있다.

 

이제 저기에 development에서는 dev, poroduction에서는 production 등의 값을 넣어서개발서버인지를 확인해 볼 수 있다!

 

 


 

 

일을 처리하는 것만 생각하지 않고

하나하나 나의 코드에 이유와 의미를 찾으면서 작업해 나가면

좀 더 멋쟁이 개발자가 될 수 있지 않나 싶다.

우다다다 코드만 늘어 두지 않기!

728x90
728x90

typescript에서 
try-catch 구문을 사용하면서

error 값을 사용하려 하면

 

 

특정 버전까지는 error의 타입이 any여서 문제가 안되었지만

이젠 unkown 이 되면서 해당 에러가 발생한다.

어떤 방법으로 해결할 수 있을까?

 

 

킹갓 any 를 사용한다

 

위처럼 error의 타입을 any로 해준다면 에러는 없어진다

역시 애니는 신이야!!

하지만.. any는 다른 케이스에서도 그렇고

타입 스크립트 사용 시 추천되는 방식은 아니다.

 

 

 

isAxiosError 타입가드 사용하기

axios에서 제공하는 타입가드를 사용할 수 있다.

 

해당 조건을 걸어주면

일반적으로 axios에서 발생하는 에러를 쉽게 케어할 수 있다.

때문에 바로 response 까지의 값을 사용할 수 있다.

 

보통 서버로 부터 받는 응답은 response.data 에 실려온다.

여기서 response는 옵셔널 한 선택지기에 response 뒤에 ? 를 붙여주어야 한다.

혹은 if 조건문에 해당 내용을 추가해 주어도 된다.

 

아래는 해당 관련 깃허브 링크이다.

 

https://github.com/axios/axios/tree/main#typescript
 

GitHub - axios/axios: Promise based HTTP client for the browser and node.js

Promise based HTTP client for the browser and node.js - axios/axios

github.com

 


 

에러 사유를 굳이 디테일하게 노출해야하는 상황이 아니라면

try-catch 에서

error 값으로 분기를 태우기보다

실패 상황 처리만 하는 것도 하나의 팁이지 싶다.

 일반적인 팝업을

보여주는 식으로 말이다.

 

 

'서버와의 연결이 불안합니다. 잠시 후에...'

'...기능이 실패했습니다.'

등으로 말이다.

 

 

 

 

728x90

+ Recent posts