서론

프론트앤드와 서버를 분리한 후, Web API를 통하여 통신을 하다보면, 필연적으로 마주치는 것이 CORS 오류이다.

이 오류를 여러 번 마주쳐서, 나는 이 문제를 이해하고, 문제를 해결했다고 생각했지만, 최근에 CORS에 관한 질문을 받고, 대답하는 중, 내가 이해를 제대로 하지 못했구나!라고 생각하며 좀 더 깊게? 공부해보기로 했다.

 

그리고 앞으로는 여러 개념들을 깊게 공부해보며, 개인 Notion에 정리해놓은 것들을 블로그에 깔끔하게 정리해보려 한다.

 

SOP( Same-Origin Policy )란?

MDN에서는 이렇게 설명한다.

 

동일 출처 정책(same-origin policy)은 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다. 동일 출처 정책은 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여줍니다.

 

간단하게 설명하자면 a.com이라는 사이트에서는 a.com에서만 정보를 가져올 수 있다는 것이다. 즉 프론트 서버는 a.com으로, 백앤드 서버는 b.com으로 분리하면 안되고, 둘 다 a.com에 존재해야 데이터를 주고 받을 수 있다는 것이다.

 

그럼 같은 출처(origin)은 어디까지가 같은 출처인가? 

MDN에서는 다시 이렇게 말한다.

 

두 URL의 프로토콜, 포트(명시한 경우), 호스트가 모두 같아야 동일한 출처라고 말합니다. "스킴/호스트/포트튜플"이나 그냥 "튜플"(2개 이상의 요소가 전체를 구성하는 집합)이라고 하기도 합니다.

 

 URL http://store.company.com/dir/page.html의 출처를 기준으로 친절하게 표까지 작성해주었다.

URL 결과 이유
http://store.company.com/dir2/other.html 성공 경로만 다름
http://store.company.com/dir/inner/another.html 성공 경로만 다름
https://store.company.com/secure.html 실패 프로토콜 다름
http://store.company.com:81/dir/etc.html 실패 포트 다름 (http://는 80이 기본값)
http://news.company.com/dir/other.html 실패 호스트 다름

 

즉 프로토콜 ( http, https ), 포트( :81, :3000 등), 호스트 ( www.tistory.com  )까지 같아야하고, 이 중 하나라도 다르면 같은 출처( Same-Origin) 으로 간주하지 않는다는 것이다.

 

이 문제를 해결하기 위하여 다양한 방법이 있고, MDN에 이 방법들이 적혀있다.

여러 방법이 있지만, 그 중 가장 안전하고 권장하는 방법이 바로 CORS이다.

 

CORS ( Cross-Origin Resource Sharing ) 란?

진리의 MDN에서는 이렇게 설명한다.

 

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.

 

즉 간단하게 말하면, HTTP 헤더에 정보를 추가하여, 다른 Origin끼리도 데이터를 주고 받을 수 있게 한다!라는 것이다.

 

a.com에서 b.com의 데이터를 요청한다면,

클라이언트에서 서버로 요청할 때 http header에 { Origin : a.com } 이렇게 요청하는 곳의 출처를 넣고, 

서버에서 클라이언트로 응답할 때는 { Access-Control-Allow-Origin : 허용할 주소 } 이렇게 응답을 보낸다.

 

그리고 만약 내가 요청한 주소가 허용할 주소에 포함되어 있다면, 데이터를 받아서 화면에 뿌려준다.

 

그렇지만 반대로 요청한 주소가 허용할 주소에 포함되어 있지 않다면, CORS 오류가 발생한다.

 

CORS 오류 해결 방법

이 문제를 해결하기 위해서는 서버 측에서 응답할 때 http header 내에 있는 { Access-Control-Allow-Origin : 허용할 주소 }에 a.com을 넣어주면 CORS 오류는 발생하지 않게 된다. 

 

혹은 어느 사이트에서 요청할지 모르니, { Access-Control-Allow-Origin : * } 로, 모든 주소를 허용하면 편하게 해결할 수 있다. 물론 이렇게 된다면 보안상 문제가 생길 수 있다.

만약 내가 서버를 건들일 수 없다면, 이 문제는 브라우저에서 막아서 발생하는 문제이므로, 프록시 서버를 하나 만들어서, 프록시 서버에서 정보를 받아온 후, 클라이언트에  { Access-Control-Allow-Origin : 허용할 주소 }를 허용하여 문제를 해결할 수 있다.

 

이 부분은 시간이 되면 그림과 함께 자세히 다루어보려고 한다.

그리고 클라이언트 쪽에서 문제를 해결하는 방법을 찾아보려한다.

 

CORS의 보안 문제?? 어디가??

사실 이 윗부분은 CORS를 구글에 검색하면 나오는 보편적인 내용이다. CORS를 검색하면 가장 위에 나오는 MDN을 한 번 읽어본기만 해도 이해할 수 있는 내용이다. 만약 이 글이 이해가 안된다면, MDN에는 친절하게 그림과 함께 설명되어 있고, 친절하게 설명되어 있는 블로그들이 많다.

 

하지만 이 글을 적게 된 이유는 나처럼 이 글들을 읽고 이해가 안되는 부분이 있는 사람이 있을 것 같아서이다.

 

내가 이해가 안되는 부분은 보안상 문제라는 부분이었다.

처음에 나는 보안상 문제라고 하여,

허가 받지 않은 클라이언트가 서버의 정보를 몰래 빼오려고 요청하는 것을 막는 것인줄 알았다.

API를 만들어서 내 사이트에만 뿌리고 싶은데, 다른 사용자들이 맘대로 가져가서 사용하려고하는 것을 막으려는 건 줄 알았다.

 

하지만 이렇게 이해를 하면 막히는 부분이 생긴다. 

 

서버에 정보를 요청하면 정보는 보내주지만, 단지 http header에 { Access-Control-Allow-Origin : 허용할 주소 } 를 넣어서 보내고,

이 http header를 클라이언트의 브라우저에서 확인한 후, 자신이 허용할 주소가 아니라면 정보를 클라이언트에게 보여주지 않는 것이다.

 

서버에서 정보는 잘 보내줬는데 클라이언트에서 막을까?라는 생각과 내가 생각한 보안 문제가 아닐 것이라는 의심을 하였다.

그리고 그 이유를 찾아보았고, 맞는지는 모르겠지만 어느 유튜브에서 그 이유를 들을 수 있었다. 유튜브의 출처는 글 맨 하단에 작성하였다.

 

내가 알게된 CORS 정책의 이유를 예시를 들어서 설명하면,

 

내가 서비스를 만들었는데, a.com이라는 사이트를 만들고, b.com이라는 WEB API를 만들었다고 가정하자.

a.com에서는 로그인 한 후, 그 정보를 이용하여 b.com에서 데이터를 가져올 수 있다.

 

이런 상황에서 Trudy라는 정보를 탈취하고 싶은 사람은 t.com이라는 나쁜 사이트를 만들었다.

 

t.com에 사용자가 접속하면, b.com으로 정보를 요청해서 받아온다.

이 때, 클라이언트에 저장되어 있는 쿠키 같은 정보를 이용하여 사용자가 로그인되어 있는 상태로 요청하여 정보를 캐올 수 있다.

 

이 때 b.com에는 a.com만 허용하는 CORS 설정을 해놓았다면,

t.com에서 b.com으로 요청해서 받아오는 정보는 CORS 오류가 발생하게 되어 t.com한테 정보를 탈취당하지 않을 수 있다.

 

맥락과 흐름이 이렇게 이루어져, CORS는 이런 보안을 위하여 존재하는 정책이고,

이 부분도 시간이 난다면 그림과 함께 자세하게 설명하겠다.

 

 

[회고] CORS에 대한 공부를 하고,,, 

CORS에 대해 공부를 하며, 생각보다 보안의 의미가 크고, 글을 읽으며 내가 네트워크 보안이라는 과목을 듣지 않았다면 이해를 한 번에 할 수 없었을 것이라 생각이 들어, 전공에 대한 기초 지식의 중요성을 느꼈다...

 

그리고 문제를 해결할 때, 문제가 해결되었다고 끝내는 것이 아니라, 해결할 때 들었던 의문점들을 제대로 해소해야되겠고, 왜라는 의문을 더 깊게 해야되겠다는 생각이 들었다.

 

 

 

참고한 사이트

developer.mozilla.org/ko/docs/Web/HTTP/CORS

 

교차 출처 리소스 공유 (CORS)

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

developer.mozilla.org/ko/docs/Web/Security/Same-origin_policy

 

동일 출처 정책

동일 출처 정책(same-origin policy)은 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다. 동일 출처 정책은 잠재적으로

developer.mozilla.org

youtu.be/6QV_JpabO7g

velog.io/@yejinh/CORS-4tk536f0db

 

Same-Origin Policy 동일 출처 정책과 CORS 에러

동일 출처 정책 Same-Origin Policy 동일 출처 정책(same-origin policy)은 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다.

velog.io

coding-groot.tistory.com/91

 

CORS Error의 올바른 해결법

CORS Error에 대해서 알아보자! * 이 글은 Flask로 예시를 보여주지만 딱히 Flask를 몰라도 이해하는데 아무 상관이 없을 겁니다! Flask 자체가 간결하고 간단하기 때문에 모르는 사람도 어떤 코드인지 �

coding-groot.tistory.com

velog.io/@jmkim87/%EC%A7%80%EA%B8%8B%EC%A7%80%EA%B8%8B%ED%95%9C-CORS-%ED%8C%8C%ED%97%A4%EC%B3%90%EB%B3%B4%EC%9E%90

 

지긋지긋한 CORS 파헤쳐보자

CORS (Cross Domain) 서버와의 통신을 위해 ajax나 XMLHttpRequest를 사용하다보면 CORS 에러가 나오는 경우가 종종 발생합니다. 할때마다 설정 방법이나 우회 방법을 항상 찾다보니 매번 고생하는거 같아 ��

velog.io

 

반응형

오늘 2020 쿠팡 공채 코딩테스트를 봤다.

 

공채 공고가 나왔을 때, 내가 너무 바빠가지고, 자소서를 쓸 시간이 없었는데, 다행히도 쿠팡은 카카오처럼 1차는 자소서가 없이 코테만 보기에 바로 신청했다.

 

추첨을 통해 기념품? 같은 것도 준다고 했는데, 연락이 없는 것을 보면 당첨이 되지 않은 것 같아서 슬프다....

 

코딩 테스트는 다른 기업들처럼 프로그래머스라는 플랫폼에서 봤고, 코드 복사는 되지 않아서, 알아서 스페이스바와 탭을 쳐주어야했다..

네이버도 그렇고 쿠팡도 그렇고 외부 복사 막는 것은 이해가 되나, 코드 복사를 하지 않으면 인덴트가 너무 어렵다... ㅠㅠ 

 

C언어나 C++ 같은 경우 프로그래머스에 내장된 vim으로 명령어를 입력하면 인덴트가 되는데, JS는 지원을 안하는 건지 내가 모르는건지, 되질 않아서 한땀한땀 스페이스 바를 쳐줬고, 어떨 때는 컨벤션이 기억이 나지 않아, 내 vscode에 입력한 다음, 정렬된 코드를 한땀 한땀 손으로 쳤다... 물론 이래도 모든 부분을 완벽하게 하지는 못했다 ㅠ

 

문제의 난이도는 그렇게 어렵지는 않았다. 시간은 3시간에 총 4문제가 나왔고, 모든 문제를 다 풀었고! 시간이 많이 남아 리팩토링과 반례도 넣어보았다.

한 문제 빼고는 다들 30분 이내로 풀었던 것 같다. 그리고 그 문제도 알고리즘적으로 어렵다기보단 구현할 때 고려해야할 사항들이 많아서 어려웠다.

 

근데 살짝 걱정되는 부분은 테케를 많이 주지 않아 잘 돌아가나 싶었고, 괜히 리팩토링해서, 제대로 짠 코드를 망치지 않았나라는 걱정도 들었다. 

 

요즘 이렇게 알고리즘 문제를 풀 때 드는 생각은, 예제 넣고 결과가 나오고, 그걸로 코드가 잘 짜여진거구나 확인하는 이 방식이 바로 TDD가 아닌가 싶다 ㅋㅋㅋ 테케가 많으면 리팩토링하거나 새로운 기능과 함수를 추가해도, 내가 제대로 짠 건지 알 수 있으니까.... 이런 생각이 드니까 TDD를 공부하고 프로젝트에 적용시키는 것에 익숙해지면, 프로젝트가 훨씬 편하고 견고해질 수 있을 거라는 생각이 들었다.

 

잡담은 여기까지고, 이번에도 문제는 다 JS로 풀었다.

 

사실 중간중간 많이 고민했다.

 

C++이나 Python 같은 언어로 풀면 제공하는 자료 구조가 있었고, 그 자료 구조로 풀면 훨씬 쉽고, 효율성도 좋아지기에 다른 언어를 사용해야하나 고민했다.

 

그리고 잘못짜면 스택오버플로우가 일어날 수 있는 문제가 있었는데, JS의 기본 스택 크기가 어느 정도 되는지 몰라서 너무 걱정이 되었다.

찾아보니 프로그래머스는 Node 12 버젼 환경이고, 이 버젼의 default 값으로는 터지지 않을 것 같았지만, 그래도 불안했기에 다른 언어로 짤까 많이 고민했다.

 

하지만 JS로 풀기로 마음 먹었고, JS로 풀면 효율성은 몰라도, 코드는 더 깔끔하게 짤 자신이 있기에 JS를 선택해서 모든 문제를 JS로 풀었다.

 

JS으로 함수 단위로 코드를 짜서, 함수형 프로그래밍을 하면 깔끔하게 짤 수 있기에, JS로 짰다. 그리고 좀 복잡하고 긴 문제가 있었는데, JS로 풀었기에 이 문제에서 시간을 많이 잡아먹지 않았던 것 같다. 물론 다른 언어 쓸까 고민을 많이하느라, 그 부분에서 시간을 많이 잡아먹었다.

그리고 사실 함수형 프로그래밍이라기엔 많이 부족하고, 그냥 함수로 나누어서 짜고, 순수 함수를 지향했지만, 배열이나 객체는 프로그래머스 사이트 내에서 코딩을 해야하는게 익숙하지 않아, 괜히 실수할까 좀 불안해서 그렇게 하지 못한 점이 좀 아쉽다.

 

이렇게 함수 단위로 나눌 수 있다는 점에서 자바스크립트나 파이썬은 프로그래머스 같은 solution으로 입출력을 받는 플랫폼에서 함수형으로 깔끔하게 짤 수 있어서, 코딩테스트할 때 좀 유리한 것 같다. 물론 자바스크립트는 자바나 C++, 파이썬 같은 언어보다는 제공하는 자료 구조가 너무 없긴 하지만,,,이래서 다들 파이썬 파이썬 하나보다..

 

한 문제 빼고는 코드 길이도 길지 않았고, 매직 넘버나 매직 스트링을 따로 선언해주거나, 변수명을 의미 있게 짓는 등 노력도 많이 했으니 결과만 기다려야겠다.

 

다만 자바스크립트로 짜느라 효율성을 조금 포기한 부분이 없잖아 있어 그 점은 조금 불안하긴 하다.

 

진짜 문제를 다 풀어도 불안하고 뭔가 찜찜하고 아쉬운 것 같다... 대체 언제쯤 풀고나서 만족스럽게 나는 합격이다!라는 생각이 들까? ㅋㅋㅋ..ㅠ.ㅠㅠㅠ

 

아주아주 잘하시는, 예를 들어 코드포스 레드이신 분들은 그런 생각이 들려나..?

 

그래도 이번 코테를 보며, 알고리즘 실력은 모르겠지만, 구조화하는거나, 함수를 나누는 것 등 코드 짜는 실력은 많이 늘은 것 같다. 내가 짜놓고 나름 깔끔하게 잘 짰다는 생각이 들었다. 물론 예전에 비해서 많이 늘은거지, 아직 발전해야할 부분이 많다. 

 

확실히 계속하다보니, 깔끔하게 하면서도 빠르게 짜게 되었고, 이런 습관은 코드를 짜다가 중간에 헷갈리거나, 꼬이는 부분을 방지해서, 문제를 안정적으로 풀 수 있게 해주는 것 같다. 자바스크립트 실력을 계속해서 늘려서, 앞으로 코테 다 자바스크립트로 뿌시리라!! 그리고 취뽀까지 파이팅!!!

반응형

문제의 시작은 이렇다.

나는 데이터베이스에 20만개 이상의 데이터를 넣으려했고,

그렇기 위해서 하나하나 Insert를 하면 속도 측면에서 느리고, 반복문으로 넣게 되면 스택이 터지는 문제도 발생하였다.

따라서 데이터들을 CSV 파일로 변경 후, 그에 맞는 쿼리? 문을 날려서 넣는 방법을 택했다.

그 방법은 아래와 같다.

 

LOAD DATA INFILE "파일의 절대경로"

INTO TABLE transactions 
FIELDS TERMINATED BY ',' 
LINES TERMINATED BY '\n'
(transaction_id, user_id, type_id, money, date, category_id, payment_id, content);

 

이렇게 컬럼 명과 경로를 잘 입력해주면, CSV에 입력된 파일이 빠르게 들어간다고 하여, 이 방법을 택했다.

 

하지만 문제가 발생했다.

이 글의 제목처럼 --secure-file-priv 옵션이라 안된다고 한 것이다.

 

이 옵션에 의해서 내가 쓰는 쿼리? 명령? 문이 작동할 수 없다는 것이였다.

 

그리고 

 

SHOW VARIABLES LIKE "secure_file_priv";

혹은
SELECT @@GLOBAL.secure_file_priv;

 

라는 명령어로 어떤 경로에 있는 파일들만 LOAD DATA INFILE을 할 수 있는지 알 수 있다고 하였다.

 

 

구글링을 하니 3가지 경우가 있었다.

1. 저 경로가 특정 경로로 지정되어 있다

2. null

3. ""

 

 

만약 1번의 경우 내가 넣으려는 파일을 저 경로 안에 넣어주어서 해결하면 되고,

2번의 경우에는 아무것도 넣을 수 없고,

3번의 경우가 모든 경로에 있는 파일을 넣을 수 있다는 의미라고 한다.

 

 

그러니까 3번으로 바꾸어주어서 해결할 수 있고, 이건 my.cnf 파일을 수정하여 해결할 수 있다!라고 되어있다.

 

또는 LOAD DATA LOCALE INFILE "파일의 절대경로" 으로 해결 할 수 있다고 한다. 

하지만, 버젼 문제로 안된다고 하였고, 아마 내가 MariaDB를 사용하거나, 아니면 예전 버젼을 설치해서 문제가 되는 것 같았다.

그리고 배포할 서버에서, 최신 버젼을 지원하지 않을 수도 있으니, 나는 my.cnf를 수정하여 해결해보기로했다.

 

여기까지는 구글링하면 맨 위에 뜨는, 정석적인 방법이다. 아마 저 위 두 방법을 사용하면 대부분 문제가 해결될 것이다.

 

하지만 이 글을 쓰게 된 이유는 my.cnf 파일이 없는 경우이다.

 

분명 /etc/mysql/my.cnf 혹은 /etc/my.cnf에 있다고 하는데, 없다... 없다

my.ini

mysqld

 

등등 뭐든 다 찾아봤는데 없다!!!!

그냥 없다...my-small my-big 이런 파일로 있을 수도 있다해서 뒤졌는데 없다...

 

찾아보니 설치하는 방법에 따라 다르다고 한다.

누군가는 brew로 설치했을 것이고, 누구는 .dmg 파일로 설치했을 것인데, 이에 따라 달라지고, my.cnf 파일이 없는 경우가 있다고 한다.

 

그래서 저 위치에 my.cnf를 내가 직접 만들면 되지 않을까?했는데 일단 만들어지지 않는다.

 

sudo 옵션으로 만들어볼까 했지만, mysql이란 폴더가 없는데, 경로 설정이 저길로 안되어 있을 것 같아서 my.cnf를 찾아보기로 했다.

 

 

이걸 위해서 진짜 한참 구글링을 하던 와중 이 글을 보게 되었다.

 

serverfault.com/questions/346647/mysql-wheres-the-my-cnf-path

 

MySQL where's the my.cnf path?

I've managed to locate my install directory for MySQL: /usr/local/mysql/ Where can I find the path to my.cnf to know where I should configure the server? I've tried creating a /etc/my.cnf(as shown

serverfault.com

 

mysql --help | grep "Default options" -A 1

 

이 명령어로 my.cnf 찾을 수 있다고 하는 것이다.

덕분에 찾았다!!! 다른 사람들과는 조금 다른 경로에 있었다

그래서 그 my.cnf 파일을 수정하고 mysql 서버를 껐다 켰지만,, 안된다...

 

이것도 이상한게 사실 mysql 서버 재부팅은 service mysql restart 하면 된다는데, 나는 service라는 명령어를 실행할 수 없다고한다...ㅋㅋㅋ...

디비를 진짜 하나도 모를 때, 설치한 mariaDB라 설치할 때, 정말 많이 잘못 설치한 것 같았다. 아니면 MariaDB라서 그런가...

 

어쨌든 이 방법도 틀렸으니, 이제 다시 문제 탐구를 시작했다.

 

그래서 구글링을 열심히하다가 이 분의 글을 보게 되었다.

 

blog.naver.com/alsdomm/221737364291

 

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option

MySQL에서 load data(또는 select into outfile, load_file()함수)를 사용할 때, 다음과 같은 오류가 ...

blog.naver.com

 

최근 글인데도(2019년) 네이버 블로그에 작성하신게 신기했고, 구글에 네이버 글이 검색된다는 것도 의아했지만, 덕분에 문제를 해결했다.

 

MacOS 설정 -> MySQL -> Configuration에서 해답을 찾을 수 있었다.

MySQL

현재는 맨 위에 Configuration File의 경로가 지정되어 있었지만, 원래는 되어 있지 않았다.

이 Configuration File 부분을 아까 grep으로 찾은 파일로 설정해주니 해결되었다.

 

왜 맨날 나는 CLI로 먼저 끝장을 보려고 하는지 모르겠다.. 다음부터 이렇게 제공해주는 설정부터 보며 문제를 해결해봐야겠다.

 

그리고 아마 구글링을 하다가 흘러흘러 여길로 왔을거라 생각하여, 중간에 생략했지만, my.cnf 파일에

 

[mysqld]

secure-file-priv=""


이것을 추가해주어야 문제가 해결된다! 이건 구글링하면 바로 나오니, 쉽게 해결하실 수 있을 것이라 생각한다.

혹여나 모르겠으면 댓글 남겨주시면 도와드리겠습니다

진짜 오늘 이 문제 때문에 MariaDB 삭제하고 MySQL 설치할까 고민했었는데 해결해서 너무 행복했다...ㅎㅎ

반응형

코딩 테스트는 어제(9월 29일) 봤는데, 하루 늦게 올린다.

 

결론부터 말하자면 난이도는 쉬운 편이었던 것 같다.

 

함수를 최대한 나누려고 했는데 50줄이 넘어가는 문제는 없었던 것 같다.

 

사실 평일 아침이라서, 할 일이 있어 급하게 보느라, 2시간 시험 중 1시간 정도만 사용한 채 제출했다.

 

그 점이 좀 아쉽고, 좀 더 깔끔하고, 반례를 생각하지 못한 점은 아쉽지만, 그래도 나쁘지 않게? 반례 고려도 하고, 코드도 깔끔하게 짠 것 같다.

 

좀 아쉬운 점은, 1번 같은 경우 방법이 바로 생각나지 않았는데, 요즘 진짜 코테 공부를 따로 안해서 그런지, 방법적인 부분이 바로바로 퍼뜩퍼뜩 생각나지 않는 것 같아, 공부를 좀 하긴 해야할 것 같다.

 

코테는 짧은 시간 내에 푸는 것이 중요한 점 중 하나라, 평소 코딩하는 것처럼 아름답고 깔끔하게 짜려고 고민하다보면 시간이 너무 많이 가는 것 같다.

 

특히 원래는 C++로 하다가 JS로 하니까, C++은 습관처럼 풀 수 있는데, JS는 습관처럼 풀지는 못해서, 더욱 시간을 잡아먹는 것 같다.

 

계속 연습하고 공부하다보면 나아지겠지 싶다. 사실 JS를 공부하고,  코딩테스트 문제를 풀기 시작한건 5월 정도 였는데, 지금은 거의 모든 문제를 JS로 푸는 것을 보면, 조금 더 하면, C++만큼 잘할 수 있지 않을까라는 생각도 든다.

 

하지만 또 언어적 한계로 인해, C++만큼 역량이 안 나올 수도 있을 것이라는 생각도 한다.

반응형

코테를 3일 연속으로 보는 중...이다....너무..힘들지만.,.연휴 때..쉬면 되니까..버티고 있다..

 

네이버는 토요일 일요일 고르라고 해서 어제 카카오를 봐야해서 일요일로 골랐다.

시간은 카카오 12:30~, 네이버는 10:00~12:00로 겹치지 않았지만 하루에 2개를 보면 힘들까봐...

 

결론을 말하자면 아쉬웠다??라고 해야하나 

왜 항상 아쉬운지 모르겠다 ㅋㅋ.. 사실 테스트를 보고 만족스럽다라는 생각을 한 적이 없는 거 같긴하다..

문제를 다 풀어도 컨벤션이나 그런 것을 걱정하니..

 

근데 문제는!! 문제를 못 풀었다

마지막 문제를 못 풀었다!!!!!!!!!악!!!!!!!!!!!!!

 

일단 너무 방심을 했다. 문제를 다 읽어봤어야하는데, 어제 문제가 쉽게 나왔다고하여, 당연히 쉬울 줄 알고, 코드의 질에 집착했다.

 

함수를 나누고, 변수명을 계속 고민했다.

 

이게 개인 IDE에 복붙이 안되는 시스템이라, 깔끔하게 짜기 더더욱 어려워서 시간을 많이 낭비했다.

 

특히 2번 같은 경우, 메모리 낭비 안하겠다고, 좀 돌아돌아 푼 것 같다.

 

또 함수 하나에 한 역할만 시키겠다고 함수를 분리하느라 정말... 시간을... 쭉쭉 풀면 20분이면 풀거 50분 넘게 걸린 것 같다.. IDE와 Lint의 소중함을 뼈저리게 느꼈다.

 

마지막 문제는 풀다가 내가 만든 알고리즘의 허점을 발견하고, 5분 정도 멘탈이 나갔다..

덕분에 내가 만든 알고리즘도 제대로 구현을 하지 못했다!!! ㅋㅋㅋㅋ 수정해야하나 말아야하나 고민을 하다가..

 

끝나고 지금 복기하는데, 내가 짠 알고리즘으로 하면 안될 것 같다는 느낌이 확실히! 든다!! 반례가 머리 속에서 계속 떠오른다..

 

아 근데 다음부터는 시간은 없고, 내 알고리즘이 틀린걸 알게 되면, 일단 끝까지 짜야할지, 아니면 포기를 하고 짧은 시간이라도 새로운 방향을 모색해야할지 모르겠다... 

 

하...근데 좀 아쉽다... 3번 문제 시간이 있었으면 풀었으려나... 

 

네이버 계열이 클린 코드 지향한다고 해서, 코드 깔끔하게 짠다고 시간 낭비한게 흠인 것 같다.

물론 내가 잘해서 그런 클린 코드가 툭 툭 나올 정도의 실력이었다면, 시간을 허비하지 않았겠지..

 

실력을 더 기르고, 구조를 짜고, 변수 명 예쁘게 짓는 연습 좀 해야겠다.

 

이번에 산 함수형 자바스크립트 책 읽으면서 공부 좀 해봐야겠다.

 

다음에는 빠르게 짜서, 어려운 문제 풀 시간을 벌어야겠다.

 

 

그리고 항상 느끼는 것이지만, 알고리즘 문제 풀 때, 함수형으로 짜면 보기도 편하고, 짜기 꽤 괜찮은 것 같아, 계속 연습해봐야겠다.

 

조금 아쉽긴한데, 어제와 비교하여 난이도가 어려운 편인 것 같으니 2솔까지 구제를 해주기를 빌어야겠다..

 

그리고 3번도 테케 몇 개는 돌아가는 것 같으니...........ㄸㄹㄹ...

 

일단 이제 좀 쉬어야겠다....학교+동아리+부캠+취준...

쉰다고 유튜브를 보거나 게임을 한지도 너무 오래된 것 같다... 확실히 바쁘니까 인생의 우선순위에서 낮은 거부터 정리하는구나 싶다.

 

결과가 어떻게 될지는 이번 달 나 자신 너무 수고 많았고, 연휴동안 재충전해서 남은 올해도 열심히 달려야겠다!!

반응형

한 줄로 요약하자면, 생각보다 어려웠고, 생각보다 쉬웠다.

 

물론 나는 그렇게 잘 보지 못한 것 같다. 생각보다 쉬웠기 때문에...상대적으로 못 봤을 것이라 생각한다.

 

시험은 필기 + 실기 테스트였다.

필기는 15분 정도 진행했고, 실기는 4시간 45분 정도? 진행했다.

15분이라는 정보를 듣고 그렇게 어렵게 나오진 않겠다해서 준비를 안했는데, 다행히 예상대로 어렵게 안나와서 풀 수는 있었다!

 

일단 실기 테스트 복기를 해보자면, 초반에 너무 바보 같은 짓을 했다.

 

API를 가져와야하는데, 나는 node를 사용하면 안되는 줄 알고 JS만으로 처리하려고 했다. 처음에는 https request로 해결하려하다가, POST까지는 되는데, GET에서 계속 안되길래, 관리자 분께 Node 사용 가능한지 여쭈어봤고, 사용 가능하다고 하셔서, 익숙한 npm init을 하고 미션을 그제서야 제대로 시작할 수 있었다...

 

그리고 node 모듈에서 axios를 사용하였는데, axios에 헤더를 사용하는 것은 처음이라, 익숙치 않아 하라는대로 해도 오류가 생기길래, 바로 fetch api로 방향을 변경하여 해결할 수 있었다. 다행히 여기서는 정상 작동했다.

 

여기서 거의 2시간 잡아먹었다...

 

그리고 이 다음도 문제였는데, 서버에 720개 정도의 요청을 동기적으로 보내야했다...하...

처음해보는 것이라, 어떻게할까 고민을 많이했다. 콜백 함수로 재귀적으로 함수를 넣으면 스택이 터질 것 같아서 ( 근데 지금 생각해보면 720개면 안터질거같기도...) then이나 async를 사용하려했는데, then으로 자기 자신과 같은 함수를 호출하는 법이 생각이 나지 않아, async await으로 b라는 인자를 받아, 다시 b라는 인자를 자기 자신의 파라미터로 넣어주는 방식을 사용했다.

 

while(조건문){

b = await 함수(인자들 , b)

}

 

이렇게 해서 해결했지만... 당연히 이건 똥 같은 코드다...진짜 경험의 부족인 것 같다.....이런 경험을 해본 적이 없으니..생각보다 막막했다.

그리고 요즘 슬럼프가 온건지 뭔지 모르겠는데, 구글링을 잘 안하는 것 같다. 구글링도 좀 해야하는데, 막히면 멍하니 혼자서 해결하려고 다양한 시도만 하는 것 같다....학교 다닐 때, 과제를 스스로 해결하려고, 구글링 안하고, 남의 코드 안보는 습관 때문에 그런  것 같다... 그 때는 혼자서 생각해서 다 해결하긴 했는데... 급할 때, 막히면 빠르게 찾아보는 연습도 해야겠다. 

 

그래도 하면서 JS에 대해서 색다른 경험을 하게 되고, 내 부족한 점을 알 수 있었던 좋은 시간이었다.

api 가져올 때, 헤더를 사용하는 것과, axios, http request, fetch 에 대해서 좀 더 구체적으로 공부해봐야겠고, 같은 요청을 동기적 그리고 연속적으로 하는 방법도 공부해봐야겠다.

 

사족이지만, 파이썬으로 하면 api 가져오는 것과, 비동기, 이 모든 문제가 쉽게 해결된다... 시험 끝나고 주변 사람들에게 물어보니, 이런 고민을 안했고, 모두 파이썬으로 코테를 봤다고 한다....ㅠㅠㅠ 어쩐지 작년 재작년 카카오 코테 본 사람 거의 3분의 2가 파이썬으로 진행했다는데, 이유를 알 것 같다... 하 ㅠㅠ 2시간 아낄 수 있었는데... 왜 파이썬 생각을 못했을까... 그래도 JS 경험을 쌓을 수 있었으니 먼 미래에는 더 도움이 되지 않을까 싶다라고 믿어야지ㅠㅠ

 

 

그리고 필기 테스트는 쉽게 나왔는데, 가끔 헷갈리는 개념이 있었고, SQL은 내가 진짜 다 까먹었구나 혹은 모르는구나를 깨닳았다. 백앤드 공부하면서 SQL도 다시 한번 공부해봐야겠다. 

 

그리고 제일 화나는건 respone 400 !!!!!!!! 통신이 성공적이면 200번대지 왜 나는 400번대가 통신이 성공적이라고 생각했을까!!!!! 심지어 문제 풀면서 error 404는 page fault니까 400번대가 오류겠지~~라고 생각하면서 왜 혼자 생각이 너무 깊어져서, 이상한 망상을 하다가 400이 통신 성공시 보내는 http 상태 코드라고 했다ㅠㅜㅡㅎ루ㅠ뤃ㅁ 정말 바보같다.. 300이 리다이렉팅, 200이 성공, 400이 실패!!! 절대 안까먹겠다 진짜!! 이제!!! 헷갈리지도 않고1!!

 

진짜 요즘 힘들어서 컨디션도 최악이고, 나름 슬럼프? 였는데, 그래도 5시간 넘게 집중해서 코테를 본 내 자신이 대견하지만, 너무 많이 아쉽긴하다.. 파이썬으로 풀 껄... 아니 좀 미리 공부해둘껄... 솔직히 미리 공부하는 건 현실적으로 힘들다고 생각하지만, 요즘 JS에 대한 쓸데없는 고집이 있어서, JS로 어떻게든 풀어내겠다!! 이러다가 시간을 날린게 조금 아쉽다!!  하지만 다음에도 JS로 도전할거고, 그때는 코테를 보고 뿌듯하게 잘 풀었네! 나 성장했네 라는 생각을 가질 수 있었으면 좋겠다!!

 

 

반응형

라인 코딩테스트를 운 좋게 통과해서 필기 테스트를 봤다. 

 

시험은 필기 테스트로 진행되었다.

 

필기 테스트는 전공 지식을 많이 물어본다고 하여 예전에 star을 해둔 어떤 분이 정리해 두었던 깃허브 정리글을 한번 보고, 필요한 부분을 좀 더 공부하고 들어갔다.

 

놀라운 것은 다른 기업에 합격한 친구한테 필기 테스트를 어떻게 준비했냐고 물어보니, 내가 star해둔 글을 보고 들어가서 도움을 받았다고 해서 내가 "내가 star을 해둔게 있다고?"하고 후다닥 달려가니 있었다. 

 

어렴풋이 나중에 공부해야지 하고 1-2년 전쯤에 star을 눌러놨는데, 진짜로 보게될 줄은 몰랐다...과거의 나...칭찬해...

 

 

도움이 많이 된 깃허브

github.com/WooVictory/Ready-For-Tech-Interview

 

WooVictory/Ready-For-Tech-Interview

💻 신입 개발자로서 준비를 하기 위해 지식을 정리하는 공간 👨‍💻. Contribute to WooVictory/Ready-For-Tech-Interview development by creating an account on GitHub.

github.com

 

오랫만에 전공 복습하니 기억 새록새록 나면서, 플젝을 몇 번 진행하다보니, 전공 공부가 다 쓸모가 있다는 것을 새삼 느끼게 되었다.

 

하지만 플젝을 먼저 진행하고, 전공 과목 수업을 들었으면, 진짜 빡집중하고, 교수님께 많은 질문 드릴 수 있었을 것이라는 생각이 들었고,

'왜 나는 웹 개발을 늦게 시작했을까'라는 후회도 많이 남았다 ㅠㅠ

 

문제의 구체적인 내용은 규정에 걸릴까봐 못 말하겠고, 범위는 정말 중요한 전공 과목은 다 나왔다.

 

운영체제, 네트워크, 컴퓨터구조, 데이터베이스, 알고리즘, git, 소프트웨어공학, 객체지향 등등...

운영체제하고 네트워크 부분이 많이 나왔고, 수도 코드를 읽고 결과를 예측하는 문제도 나왔다.

 

예상했던 것보다 깊게 물어봤고, 암기보다는 이해를 원하는 것 같았다.

그리고 시간이 너무 부족했...다...

 

읽고 애매모호하다고 느낀 것이 많았고, 코드도 익숙한 문법이 아니라 해석하는데 애를 먹었다.

 

하지만 차분히 풀었으면 다 풀었을 수 있었을 것 같은데, 괜히 말려서,,, 좀 못 풀었다 ㅠㅠ

 

마음을 비우고 풀어야 긴장하지 않고 잘 풀텐데, 뭔가 갑자기 라인을 꼭 가고 싶다는 마음이 생기고, 그러니까 긴장하고 조급해져서 제 실력 발휘를 못한 것 같아서 너무 슬프다... 어제 잠도 못 자고ㅠㅠ

 

그래도 정말 좋은 경험이었다. 오랜만에 시험 전날에 전공 공부하는 기분이었고, 전공 과목들을 복습하면서 다시 많은 것을 배웠다!

특히 네트워크 쪽, 웹 개발하면서 얻은 경험과 결합해서 보니 새롭게 보였다!!! 이래서 CS 지식이 중요하다하는구나 싶더라

 

다음에는 미리미리 네트워크나 운영체제 같이 중요한 과목은 공부를 좀 해놔야겠다.

반응형

오늘 라인 채용 코딩 테스트를 봤다.

 

네이버, 라인 계열은 클린 코드를 중요시한다고 하여, 그나마 클린 코드나 컨벤션을 잘 아는 JS를 모두 이용해서 문제를 풀어봤다.

 

난이도는 적당한 정도였던 것 같다.

 

1,2,3 번 문제는 구현의 난이도가 낮았지만, 알고리즘적으로 생각할 점이 있었는데, 그렇게 어렵진 않아서 함수를 분리하고, 깔끔하게 짜도록 노력했다.

 

하지만 아쉬운 점은 함수형으로 코드를 짰는데, 커링 혹은 합성 함수 쓰는 법, 고차 함수 이용법 (reduce나 map, forEach 같은?)을 좀 더 잘 숙지했다면, 코드를 더 빠르고, 예쁘게 짤 수 있었을 것이라는 후회가 든다. 좀 더 연습해야겠다.

 

4,5,6번은 알고리즘적으로 어렵다기보단 조금 까다로운 구현 문제였다.

 

4번 문제를 풀다가, 예외 사항을 처리하고, 복잡한 구현을 하다가, 중간에 어딘가에서 오류가 나서 포기할까 고민을 많이했는데, 다행히 5분 정도 더 고민하다가 코드를 조금 수정하니 잘 돌아갔다.

어제 같은 경우도 그렇고 평소에 코테를 볼 때, 꼬이면 포기하는 경향이 있었는데, 포기하지말자!!

 

그리고 코드를 함수형으로 분리하고, 컨벤션을 지키고, 주석을 달면서 짜니 확실히 중간에 꼬이거나 오류가 발생하더라도 문제가 잘 풀리는 것 같다.

 

설계를 하고 코드를 깔끔히 짜는 것이 조금 돌아가는 것 같이 보여도, 결국엔 제일 빠른 길이라는 걸 알게 되었다.

 

 

마지막 남은 1시간 동안 5번 문제를 붙잡았는데, 집중력이 떨어지고, 의욕이 떨어지니 빠르게 못 풀어서 중간에 끝나게 되었다. 

기능들을 다 구현하고 테스트하고, 로직에 따라 넣어주기만 하면 되는데 너무 아쉬웠다 ㅠㅠ

 

다음부터는 끝까지 집중해서 빡세게 코딩을 해야겠다.

 

어제 아쉬웠던 점을 보완해서 코테를 봤는데, 어제보다는 좀 더 만족스러웠다.

 

확실히 구현 부분에서 아직 JS는 익숙하지 않아서 좀 더 연습해봐야겠다.

 

그리고 node를 사용해서 테스트 코드를 돌리는 것이 훨씬 빠르고, 관리하기도 쉽다는 것을 알아냈다.

 

그리고 함수형으로 코드를 분리해서 짜면, 함수 하나하나를 테스트할 수 있어서 코드를 짜기에 정말 좋은 것 같다.

 

좀 더 연습하고, 익숙해져서 다음엔 자연스럽고 빠르게 짜서 모든 문제를 풀 수 있도록 노력해봐야겠다!!

 

그리고 어려운 문제를 빠르게 푸는 것도 중요하지만, 쉬운 문제도 빠르게 풀어보자!!!

반응형

+ Recent posts