번개애비의 라이프스톼일

왜 우리는 코딩테스트를 보게 되었는가, 그리고 신입개발자 대상 코딩테스트 문제(배경지식, 데이터베이스, CS코딩, 알고리즘 등) 본문

IT

왜 우리는 코딩테스트를 보게 되었는가, 그리고 신입개발자 대상 코딩테스트 문제(배경지식, 데이터베이스, CS코딩, 알고리즘 등)

번개애비 2022. 5. 10. 09:20

이번에 회사에서 신입개발자(1년미만)를 채용하게 되었다.

내가 경험한 것처럼 다른 회사의 파트장이나 팀을 이끄는 리더에게 조금이나마 도움이 됬으면 하는 바램에 경험내용과 코딩테스트 문제를 공유하게 되었다.

 

이전까지는 면접과 배경지식과 관련된 간단한 문제만으로 개발자를 뽑았었는데, 그 결과 조금만 로직이 복잡해지면 굉장히 힘들게 일을 하는 경우가 많았고 그 빈도가 점차 증가하면서 주니어개발자 그 자신에 대한 자존감이 크게 하락하는 경우를 경험하게 되었다.

그 친구만의 문제라고 단정짓지 않고 Recruit 프로세스부터 OJT, Todo 관리, Capa 측정등 회사 내 개발조직의 모든 프로세스를 점검하면서 되돌아본 계기가 되었다.

 

선을 넘는 학원 광고문구. 데이터 사이언스가 몸 값이 이렇게 비싼데 이걸 90일만에 배울수 있다고? 취준생입장에서는 정말 혹 할만하다.

최근 개발자 몸 값이 크게 뛰면서 많은 사람들이 직업학교등을 통해 개발에 입문하는 경우가 많은데, 짧은 기한내 빠르게 개발언어를 습득하고 어디든 빠르게 취업을 시켜야하는 학원 특성상, 논리적인 사고나 알고리즘적인 접근에 취약할 수 밖에 없었던것 같다. (이건 데이터사이언티스트든 일반 CS개발이든 IT관련 직종에 최근 거품이 잔뜩 낀 트랜드인것 같다.)

 

이것은 마치, 

의사면허 90일 완성, 야, 너두 할 수 있어!

이런 이야기인 셈이다.

 

⚠️ 이 글은 직업학교나 학원 출신 개발자를 폄하하는 글은 아니니 오해하지 않았으면 한다.
필자는 대학이전부터 실무를 했었고 일과 관련된 학과를 나왔지만, 어느 출신이고를 떠나서 IT분야에 새로운 사람들이 계속 유입되는것에 대해 시장의 성장에 있어서 긍정적으로 생각한다. 
다만, 당부하고 싶은 말은 앞으로 IT업계에서 학원출신(?) 개발자는 미래에도 계속 "출신"에 대한 제약과 선입견이 따름으로 남들보다 몇배는 더 많은 스터디와 자기개발을 통해 이를 극복해야 할 것이다.

 

주니어개발자의 자존감이 크게 하락된 상태에서 시니어 입장에서 어떻게든 이끌고 나가는 것에 큰 한계를 맛보게 되었고,

무엇보다 코드를 단순히 짤수 있는 수준에서 무작정 개발에 투입하여 새로운 스파게티코드를 양산하는것을 그저 두고 볼 수 없게 되었다.

 

 

당장은 급박한 개발을 처리할 수 있을지 몰라도, 짧게는 1개월, 길게는 1년뒤의 서비스를 확장하거나 유지하는 관점에서는 엄청난 기술채무가 발생되는게 뻔했다. (아마 이런 문제 때문에 적어도 한국에서는 프레임워크에 크게 의존받는 JAVA Spring기반이 지속적인 주력언어가 되지 않을까 싶다.)

 


 

OJT를 조금더 효율적으로 하기위해 회사내부에서 사용하는 프레임워크부터 세부적인 모든 기능들에 대한 구체적인 기술문서와 각각의 코멘트등을 작성하였고, 윗선의 양해를 구하고 소스코드의 각종 스파게티들을 당장 리팩토링하여 바로잡았다.

(리팩토링보다는 정확히는 서비스를 아예 갈아엎은 경우가 많았다... ㅜ)

 

Capa를 좀더 명확하고 공정하게 측정하기 위해 Notion을 활용하여 개인별 Todo를 공유하게끔 변경하였다.

 

프레임워크의 구조에서부터 말단 Functional 코드까지 최대한 알아보기 편하게 개발자관점에서 최적화를 했고, 복잡한 인덱싱에 따른 쿼리최적화에 머리싸매지 않도록 모든 형태의 쿼리를 단순한 함수로 쿼리가 실행할 수 있도록 변경했다.

 

이외에 업무상의 어려움을 가감없이 피드백 받기위해 개발자들에게 지속적으로 접근(?)하거나 공통된 공감대를 형성하기 위해 꾸준히 행동하거나 대화를 시도하였다.

 

Recruit 과정에서 조금 번거롭더라도 간단한 배경지식부터 CS능력검증을 위한 테스트, 기본적인 알고리즘과 관련된 코딩테스트를 보완하게 되었고 다음과 같은 결과가 나왔다. (참고로 난이도나 변별력등은 회사마다 요구하는 조건이 달라 장담할 수 없으나 단순 노가다 코더가 아니라 적어도! 최소한! 개발자라고 한다면 이정도의 문제풀이는 가능해야 한다고 생각한다.)

 


개발 배경지식 관련 문제

1. 변수와 상수의 차이점을 설명해주세요 Explain the difference between a variable and a constant

//모범답안
변수 : 값이 변경되는 어떠한 값
상수 : 값이 변경되지 않는 어떠한 값

변수와 상수는 메모리상에 값을 저장한다. 메모리(RAM)상에 어떤 값을 저장하게 되면 
해당 공간에 우리가 선언한 변수나 상수의 이름을 메모리의 특정공간에 주소값을 부여하게 됩니다.
서버에서 실행 되는 언어(Java, Go등)들은 서버의 메모리를 사용하며, 
클라이언트에서 실행되는 언어(Javascript, C#등)들은 클라이언트의 메모리를 사용합니다.
변수와 상수를 구별하여 사용하는 이유는 개발자 관점에서 코드의 가독성과 편리성 때문에 사용하는 것이며,
상수로 선언한 값은 주석을 달거나 누가 설명하지 않더라도 코드 내부에서 갑자기 값이 변하지 않는다는 것을 알게 해줍니다.
변수로 선언한 값은 코드 내부에서 갑자기 값이 변화함으로 
어떠한 값을 임시로 저장하기 위한 메모리(RAM) 그 자체의 기능을 위해 사용합니다.

변수는 코드가 실행되면서 잠깐씩 저장되는 내용.
예를들면(루프의 카운터, 출력직전의 값, 사용자의 입력데이터등)과 같은 값을 "임시"저장하는곳에 사용됩니다.
개발언어마다 상이하나 연산이 모두 종료되면 자동으로 메모리에 할당된 변수 값이 자동으로 초기화되지만,
부족한 메모리 혹은 메모리의 누수가 발생되는 코드에서는 코드 중간중간에 변수 초기화를 통해 메모리를 그때마다 반환하는게 유리합니다.

상수는 미래, 환경, 사용자등에 따라 개발자의 코드수정이 있지 않는 한 바뀌지 않는 절대적인 내용.
예를들면(DB정보, 관리자계정정보, 환경설정)과 같은 값을 저장하는곳에서 사용하며, 이렇게 사용함으로써 발생되는 이득은
DB정보를 상수로 선언하고 Dev환경에서 상수값만 불러와 개발을 진행하다가 
개발이 모두 완료되어 Production환경으로 전환할때 
상수가 선언된 DB정보 하나만 변경하면 모두 바뀌기 때문에 손쉽게 모든 코드의 정보를 일괄적으로 수정이 가능합니다.

 

2. Javascript에서 var, let, const의 차이점을 설명해주세요 Explain the difference between var, let and const in Javascript

//모범답안
var, let, const 모두 메모리에 변수나 상수등을 저장하기 위한 선언문입니다.
var : 변수를 재선언, 재할당이 가능합니다.
let : 변수를 재할당할 수 있지만, 재선언이 불가능합니다. (즉, 호이스팅이 불가능)
const : 변수를 재선언, 재할당 모두 불가능하기 때문에 상수값으로써 활용합니다. (호이스팅도 당연히 불가능)

ES6이전까지는 Javascript에서는 변수를 선언할때 반드시 var를 이용해서만 선언이 가능했습니다.
하지만 코드중간에 개발자의 착오등의 이유로 재선언되지 말아야할 변수를 재선언으로 인한 버그가 발생되기도 하고,
무엇보다 var의 경우 초기값이 없으면 자동으로 undefined를 초기값으로 메모리를 할당해버립니다.
이러한 과정속에 메모리누수가 발생될 수 있기 때문에
 상황에 따라 적절하게 var, let, const를 활용하여 변수나 상수를 선언해야 합니다.

 

3. 변수를 선언할때 변수명에 한글이나 특수문자를 사용하지 않는 이유를 설명해주세요 Please explain why you do not use Korean characters or special characters for variable names when declaring variables

//모범답안
개발자관점 : 코드 가독성이 떨어짐, 매번 한/영키로 전환하는 어려움 발생
프로그램관점 : 변수할당시 할당되는 메모리의 용량이 조금더 필요로 함

변수명을 정하는 것은 영문이든 한글이든 특수문자든 무방하다고 생각합니다.
하지만, 많은 개발자들이 변수를 선언할 때 한글이든 특수문자든 사용하지 않는 이유는 다음과 같습니다.
통상적으로 변수명을 선언하기 위해 camelCase 라는 대문자 작성법을 사용하거나 
간단하게는 '_' 와 같은 문자로 복잡한 변수명을 구분하여 사용합니다.
개발자들이 통상적으로 이러한 작성법을 두루 사용한다는 이야기는 코드를 읽기 편하기 위함도 있고,
특히 한글이 아닌 다른 언어를 사용하는 개발자도 코드를 쉽게 볼 수 있기 때문입니다.
+, =, / ! 등과 같은 일부특수문자들은 언어에서 연산자로 처리되기 때문에 사용하지 못합니다.
변수를 선언할때 변수값을 메모리(RAM)에 저장하게 되는데 일반 영문으로 변수명을 선언할 때 대비
한글로 변수명을 선언할때 메모리의 사용량이 더 높을 수 밖에 없습니다.
다수의 접속자에 대해 지속적인 인터프리티 작업을 하는 서버쪽 언어에서는 접속자수에 따라 메모리 사용량이 비례합니다.
무엇보다 개발언어는 영어로 구성되어 있는데 만약 변수명을 한글로 써야한다면
매번 변수를 선언할때 마다 한/영 키를 눌러야하는 번거로움이 생길 것 같습니다.

 

4. Javascript 관점에서 function 혹은 class는 변수로 선언되어 사용할 수 있는지 선택해주세요 From a Javascript point of view, select whether a function or class is declared as a variable and can be used.

//모범답안
function 혹은 class는 변수다

Javascript 관점에서 function 혹은 class 는 변수가 맞습니다.
function test(){}; 은 var test = function(){}; 과 같습니다.
임의의 함수를 생성한 뒤 Chrome console에 함수명만 타이핑해보면 함수의 객체를 확인할 수 있습니다.

 

5. Client browser의 Request 방식중 post, get, put의 차이점을 설명해주세요 Please explain the difference between post, get, and put among client browser request methods

//모범답안
post : 생성할때 사용하는 method, body를 통해 피라메터가 전송
put : 전체수정할때 사용하는 method, body를 통해 피라메터가 전송
get : 읽을때 사용하는 method, url을 통해 피라메터가 전송

post, get, put은 HTTP 에서 RESTful API에서 사용하는 method입니다.
post는 CRUD에서 Create(생성)에 해당되는 기능과 매칭되는데 이처럼 어떠한 값을 생성할 사용됩니다.
get은 CRUD에서 Read(읽기)에 해당되는 기능과 매칭되고 게시판의 게시물을 읽거나 할때 사용됩니다.
put은 CRUD에서 Update(수정)에 해당되는 기능과 매칭되고 patch와 동일한 수정기능을 담당하지만, 
부분적으로 수정하는 patch와 달리 모든정보를 수정하기 위해 사용됩니다.
게시판을 예시로 들어 설명하자면,
게시판에 글을 작성하는 행위는 post, 게시물을 보는 행위는 get, 게시물을 수정하는 행위는 put이라고 설명할 수 있다.
다만, post와 put, 그리고 get과의 또 다른 차이점이 있는데
get은 URL자체로 데이터를 전송할 수 있는 반면, post와 put은 HTTP 패킷내 body를 통해 전송된다.
eg) https://www.naver.com/?test=1
전송되는 데이터의 특징으로 인해 로그인 기능과 같이 회원의 패스워드가 유출되지 않아야 되는 기능이나
첨부파일과 같이 데이터의 길이 긴 내용을 전송할때 get이 아닌 post방식을 사용한다.

 

6. Web의 비동기 통신에서 XMLHttpRequest과 fetch의 차이점에 대해 설명해주세요 Please explain the difference between XMLHttpRequest and fetch in asynchronous communication on the web

//모범답안
XMLHttpRequest : 전통적인 이벤트 통신기반, 브라우저간 기능불일치, 코드가 긴편
fetch : promise 기반, 브라우저에 내장되어 기능일치, 코드가 간편함, ES6 미지원 브라우저는 사용불가

비동기통신 이전에는 form 태그를 통해서 웹서버로 submit을 해야만 데이터전송이 가능했습니다.
기존의 form 태그로 데이터를 주고받을 경우 매번 새로운 페이지를 보내줬어야 함으로
불필요하게 많은 데이터가 올뿐만 아니라 페이지를 새로 받는 불편함이 있었습니다.
XHLHttpRequest와 fetch와 같은 비기통신은 서버에 요청하고 해당하는 내용만 받는 것임으로
대역폭의 낭비를 줄일 수 있고 필요한 부분만 요청할 수 있음으로 새로고침의 과정없이
서버와 클라이언트간 상호통신이 가능해졌습니다.
fetch 이전에는 XHLHttpRequest를 이용한 비동기 통신을 위해서는 그 과정이 매우복잡했으며,
이 때문에 jQuery에서 ajax() 라는 것을 만들어 손쉽게 사용할 수 있게 되었습니다.
안타깝게도 외부라이브러리를 사용하는 XMLHttpRequest는 브라우저마다 기능이 작동되는게 조금씩 불일치되었습니다.
ES6에서부터는 fetch가 나오면서 브라우저에 그 기능이 내장되게 되었으며, XHLHttpRequest보다
코드를 사용하는 과정자체가 손쉬웠다. 특히 fetch에서는 promise를 사용할 수 있음으로
페이지의 응답만 체크하는 종전의 XHLHttpRequest보다 비동기연산이 손쉽게 가능해졌습니다.
표준화된 규격을 브라우저에 내장했음으로 ES6이상을 지원하는 브라우저에서는 모두 동일한 기능으로 작동되는 장점이 있습니다.

 

7. 통상적인 반복문 (while, for, foreach, do while) 중에서 제일 빠른것을 선택해주세요 Choose the fastest one out of the usual (while, for, foreach, do while)

//모범답안
while >= for >>>> do while >>>> foreach
//for와 while 모두 정답으로 처리된 문제입니다.
//참고로 "통상적인" 단순 반복문에서의 속도를 묻는 문제입니다.

for : 반복횟수를 정확하게 명시하고 동작하는 반복문이며 OOP가 나오기전까지 가장 많이 사용한 반복문입니다.
while : 조건을 부여하여 조건이 만족될때까지 반복합니다. 제일 빠른 반복문이지만, 잘못된 코드로 인해 무한루프에 빠질 수 있습니다.
do while : for문과 while문이 병합된 형태이며, 손쉽게 사용할 수 있지만, for문과 while문에 비해 속도가 느린 반복문입니다.
foreach : OOP환경에서 굉장히 사용하기 좋은 반복문이며, while문과 같이 무한루프에 빠질염려가 없지만 제일 느린 반복문입니다.

 

8. 대부분의 프로그램 혹은 서비스에서 String형태의 문자열을 서버에서 Static 파일이 아닌 Database를 이용하여 서비스하는 이유를 설명해주세요 Please explain why most programs or services use Database instead of Static file for string type string

//모범답안
DB제어와 파일제어역시 실제로 서버에서 동일하게 파일로 저장되어 파일을 제어하지만,
DB제어의 경우 인덱싱이나 제어할 데이터가 메모리에 올라가 있는 상태임으로 더 빠르게 제어가 가능합니다.
특히 동시다발적인 데이터를 가공하는 과정에서 트랜잭션의 지원여부가 큰 차이를 보입니다.
이외에 Replcation등과 같은 부하분산을 고려할때 데이터간 동기화가 DB제어방식이 더 용이합니다.

 

9. 서비스가 대규모로 확장될수록 기업들이 Cloud Service를 사용하는 이유를 설명해주세요 Explain why companies use Cloud Services as services scale to a larger scale

//모범답안
보통의 환경에서 Cloud Service는 일반적인 호스팅비용 대비 높은 비용을 지불해야 하지만,
AutoScaling을 지원하기 때문에 비용을 효율적으로 사용할 수 있는 장점으로 인해 사용합니다.

예를 들면 평소에 100명 안밖의 방문자가 방문하는 웹서비스가 매일 특정시간대만 1억명 안밖의 방문자가 방문할 경우,
일반적인 호스팅에서는 1억명 안밖의 방문자가 방문할 것을 대비하여 그만큼의 비용을 지속적으로 지불해야하지만,
Cloud 환경에서는 시간대별, 방문자별로 VM을 자유자재로 늘리거나 줄일수 있기 때문에
방문자가 몰리는 환경에 처했을때만 그에 상응하는 비용을 지불할 수 있기 때문에 대규모서비스로 확장될수록 Cloud를 도입합니다.

 

 


데이터베이스 관련 문제

1. RDBMS에서 하나의 column의 String데이터를 조회할 때 가장 빠른 결과가 나오는 SQL방식을 선택해주세요 단, RDBMS는 MySQL과 MariaDB에 한정하며, 검색 대상이 되는 column의 String데이터는 "검색어 검색어 검색어"와 같이 띄어쓰기가 포함되어 있다. 해당 column은 fulltext 인덱싱이 걸려있지 않는다고 가정한다. Select the SQL method that produces the fastest result when querying string data for one column in RDBMS

However, RDBMS is limited to MySQL and MariaDB, and String data in the column to be searched includes spaces such as "search word search word search word". It is assumed that the column does not have fulltext indexing.

//모범답안
SELECT field FROM A_table WHERE field LIKE '%검색어%’ <- 실행 가능
SELECT field FROM A_table WHERE field in ('검색어') <- 검색결과 없음
SELECT field FROM A_table WHERE MATCH(field) AGAINST('검색어') <- #1191에러 (Can't find FULLTEXT index matching the column list)
SELECT field FROM A_table WHERE field LIKE '검색어’ <- 검색결과 없음
ELECT field FROM A_table WHERE field LIKE '검색어’ <- 검색결과 없음

 

 

2. 아래와 같은 DB테이블 user, session 에서 left join을 활용하여 department(분류)의 column값이 Partner 인 사용자의 token(토큰정보) column을 출력하는 SQL문을 완성해주세요 Using the left join in the DB table user and session as below, complete the SQL statement that outputs the token column of the user whose department value is a Partner. The first table name on the image is user and the second table name is session. 

//모범답안
SELECT * 
FROM user 
LEFT JOIN session 
ON user.sid = session.sid 
WHERE user.department = 'Partner';

 

 

3. RDBMS에서 외래키(Foreign key) 설정을 CASCADE로 설정할 경우 부모테이블(Parent table)의 데이터가 삭제될 때, 자식테이블(Sub table)의 데이터는 어떻게 되는지 설명해주세요 If foreign key setting is set to CASCADE in RDBMS, please explain what happens to the data in the child table when the data in the parent table is deleted 

//모범답안
자식테이블의 데이터가 삭제된다.

CASCADE(부모테이블에 종속) :	부모테이블의 데이터가 수정/삭제 시 자식테이블의 데이터도 함께 수정/삭제된다.	
RESTRICT(자식테이블에 종속) :	자식테이블의 데이터가 존재하면, 부모테이블을 수정/삭제할 수 없다.
NO ACTION(종속강제 X) :	부모테이블의 데이터가 수정/삭제해도 자식테이블은 별다른 Action을 하지 않는다.

 

 

4. 아래와 같은 DB테이블 station 에서 lat(위도), lon(경도) column을 활용하여 나의 위치와 가장 가까운 순으로 출력하는 SQL문을 완성해주세요 현재 나의 위치는 위도 : 37.51490471, 경도 : 126.98274432 라고 가정하고 SQL문을 완성해야 합니다 In the DB table station as below, please use lat (latitude) and lon (longitude) columns to complete the SQL sentences that are printed in the order closest to your location  Assume that the current latitude: 37.51490471, longitude: 126.98274432 and complete the SQL statement 

//모범답안
SELECT * 
FROM station 
ORDER BY POW(lat - 37.51490471, 2) + POW(lon - 126.98274432, 2);

 

5. RDBMS에서 1억개의 row를 갖고 있는 DB테이블과 10개 미만의 row를 갖고 있는 DB테이블을 병합하여 Web Client에게 가장 빠르게 서비스하는 방법을 선택해주세요 단, 2개의 DB테이블은 RDBMS를 통해 외래키로 설정되어있지 않으며, 별도의 인덱싱이 설정되지 않은 조건이다. 2개의 DB테이블은 논리적인 방법으로만 연결되어 있으며, 10개 미만의 row를 갖는 DB테이블의 특정값에 해당되는 데이터만 보여주면 된다. Please select the fastest way to serve the Web Client by merging the DB table with 100 million rows and the DB table with less than 10 rows in RDBMS  However, the two DB tables are not set as foreign keys through RDBMS, and separate indexing is not set. The two DB tables are connected only in a logical way, and only data corresponding to a specific value of the DB table with less than 10 rows need to be displayed. 

- JOIN을 통해 한 번의 쿼리 후, 프로그램 코드의 반복문을 통해 쿼리결과를 서비스한다. After one query through JOIN, the query result is serviced through a repetitive statement of the program code. 

- 1억개의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 10개미만의 row를 갖는 DB테이블을 서브쿼리하여 서비스한다. After querying the DB table with 100 million rows, the DB table with less than 10 rows is subquerated and serviced through the repetition statement of the program code. 

- 10개 미만의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 1억개의 row를 갖는 DB테이블을 서브쿼리하여 서비스한다. After querying the DB table with less than 10 rows, the DB table with 100 million rows is subquerated and serviced through an iterative statement of the program code. 

- 1억개의 row를 갖는 DB테이블과 10개 미만의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 두 쿼리결과를 서비스한다. After querying a DB table with 100 million rows and a DB table with less than 10 rows, the two query results are serviced through repetitive statements of the program code. 

//모범답안
1억개의 row를 갖는 DB테이블과 10개 미만의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 두 쿼리결과를 서비스한다. 

JOIN을 통해 한 번의 쿼리 후, 프로그램 코드의 반복문을 통해 쿼리결과를 서비스한다. 
-> 1억개 * 10개의 데이터를 JOIN하여 10개의 데이터중 특정 값만 출력되는 상황에서는 DB에 모든 연산을 넘겨주는 것은 1번의 반복문을 사용하지만 실제로는 느린 구현방법입니다.
1억개의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 10개미만의 row를 갖는 DB테이블을 서브쿼리하여 서비스한다. 
-> 가장 느리게 구현하는 과정입니다. 1차 반복문에서 10억개가 반복되며 2차 반복문에서 10개씩 추가로 쿼리를 질의해야합니다.
10개 미만의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 1억개의 row를 갖는 DB테이블을 서브쿼리하여 서비스한다. 
-> 1차 반복문에서 10개가 반복되며, 2차 반복문에서 1억개씩 추가로 쿼리를 질의해야 합니다.
1억개의 row를 갖는 DB테이블과 10개 미만의 row를 갖는 DB테이블을 쿼리한 뒤, 프로그램 코드의 반복문을 통해 두 쿼리결과를 서비스한다.
-> 10개 DB테이블중에서 특정값에 해당되는 값만 찾은뒤 1억개의 DB테이블에 쿼리만 하기 때문에 1번의 반복문만으로 가장 빠른 결과를 가져옵니다.

 

 


CS코딩 및 알고리즘 관련 문제

1. whatisme 함수가 하는 역할을 설명해주세요 Describe the role of the whatisme function

n 이라는 숫자값을 주어졌을때 x의 길이만큼 숫자값 앞에 0을 붙이는 기능을 하는 함수입니다.
이런 함수를 통해 시간정보를 손쉽게 변환할 수 있습니다.
eg) 5월 -> 05월, 7시 -> 07시 등

let test = 5;
let output;
output = whatisme(test, 2);
console.log(output);

위와 같은 예시의 경우 출력값이 05가 됩니다.

 

 

 

2. 다음의 코드를 확인하여 결과가 제대로 출력되도록 완성하여 제출해주세요 결과가 0.6이 되어야 합니다 Please check the following code and submit it completely so that the results are printed properly  The result should be 0.6

//모범답안
const a = 0.1;
const b = 0.2;
const c = 0.3;
var output = Math.round( ( a + b + c ) * 1e12 ) / 1e12;
console.log(output);

//또다른 방법
const a = 0.1;
const b = 0.2;
const c = 0.3;
var output = +( a + b + c).toFixed(12);
console.log(output);

 

 

3. 반복문과 "#" 문자열을 활용하여 아래 아스키아트를 생성하는 function(함수)를 코딩하여 제출해주세요  Javascript, JAVA, PHP, go, Python, Swift 언어 중 택일하여 작성해야 하며, #문자이외의 공백은 " " 공백문자열을 활용해야합니다 Please code and submit the function that generates the ASCII art below using the repetitive sentence and the string "#" Javascript, JAVA, PHP, go, Python, Swift languages must be selected, and spaces other than # character must be used with " "

//모범답안 (Javascript)
var ascii_art = function(bitData){
	var output = '<pre>';
	let loopArr = new Array();
	let blankArr = new Array();
	for(let l=0; l<bitData.length; l++){
		let lastx = bitData[l][bitData[l].length - 1];
		for(let i=0; i<lastx; i++){
			loopArr.push(i);
		}
		blankArr = loopArr.filter(x => !bitData[l].includes(x));
		for(let x=0; x<lastx; x++){
			if(blankArr.includes(x)){
				output += ' ';
			}
			if(bitData[l].includes(x)){
				output += '#';
			}
		}
		output += '<br />';
	}
	output += '</pre>';
	return output;
};
var dataset = new Array();
dataset[0] = new Array(0,6,8,9,10,11,12,13,14,16,24,32,33,34,35,36,37,38,39);
dataset[1] = new Array(0,6,8,16,24,32,38,39);
dataset[2] = new Array(0,6,8,16,24,32,38,39);
dataset[3] = new Array(0,1,2,3,4,5,6,8,9,10,11,12,16,24,32,38,39);
dataset[4] = new Array(0,6,8,16,24,32,38,39);
dataset[5] = new Array(0,6,8,16,24,32,38,39);
dataset[6] = new Array(0,6,8,9,10,11,12,13,14,16,17,18,19,20,21,22,24,25,26,27,28,29,30,32,33,34,35,36,37,38,39);
document.write(ascii_art(dataset));

 

 

 

 

4. copytoclipboard 함수의 진행프로세스를 단계적으로 설명하기 위해 javascript 주석을 달아 제출해주세요 Please submit a javascript annotation to explain the progress process of the copytoclipboard function step by step 

//모범답안
//함수에 입력값을 넣으면 입력값을 자동으로 클립보드로 복사됩니다.
const copytoclipboard = function(val){ 
	var t = document.createElement("textarea"); //임시로 textarea를 생성한다.
	document.body.appendChild(t); //임시로 생성한 textarea를 본문의 body에 삽입한다.
	t.value = val; //함수에 입력한 값을 textarea에 넣는다.
	t.select(); //textarea를 선택한다.
	document.execCommand('copy'); //브라우저 커멘드를 활용하여 복사를 수행한다.
	document.body.removeChild(t); //임시로 생성한 textarea를 삭제한다.
}

 

 

 

 

5. email_check 함수에서 이메일이 맞으면 true, 이메일이 아니면 false를 반환하는 정규식을 완성하여 제출해주세요 If the email is correct in the email_check function, complete and submit a regular expression that returns true or false if it is not an email 

//모범답안
//이와 유사하게 이메일을 검증할 수 있는 정규식은 모두 정답처리하였습니다.
let email_check = function(email) {
	var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2}\.[a-z]{3})?)$/i;
	return re.test(email);
};

 

 

 

6. whatisme 함수가 하는 역할을 설명해주세요 Describe the role of the whatisme function 

//모범답안
배열의 순서를 랜덤하게 뒤섞는 함수입니다.

함수의 사용예로,
0~9까지 숫자값을 입력할 수 있는 보안키패드를 구현하기 위해, 
숫자값을 배열에 선언하고 해당 함수를 통해 배열을 뒤섞어 
매번 다른 숫자키패드의 배열이 나오게 할 수 있습니다.

 

 

 

7. 아래와 같은 HTML, Javascript, jQuery 로 작성된 코드에서 <input> tag에 오직 숫자만 입력할 수 있도록 하는 기능을 완성하여 제출해주세요 <input> tag에 키보드입력, 붙여놓기 시에도 숫자만 입력되어야 합니다 Please submit a function that allows only numbers to be entered in <input> tag from the code written in HTML and Javascript, jQuery as below 

 When typing or pasting a keyboard into <input> tag, only numbers must be entered

//모범답안
$(document).on(
'keyup keypress keydown input paste',
"input[type='number'], input[type='tel']",
function(){
	var key = event.keyCode;
	if(!(key==8||key==9||key==13||key==46||key==144||(key>=48&&key<=57)||key==110||(key>=96&&key<=105))){
		event.returnValue = false;
	}
	if($(this).attr('type')=='tel'){
		$(this).val( $(this).val().replace(/[^0-9]/g, '').replace(/(^02|^0505|^050|^0502|^0507|^1[0-9]{3}|^0[0-9]{2})([0-9]+)?([0-9]{4})$/,"$1-$2-$3").replace("--", "-") );
		if(this.value.length > 13){
			this.value = this.value.slice(0, 13);
		}
	}else{
		this.value = this.value.replace(/[^0-9]/, '');
	}
});

 

 

8. temp 함수의 역할을 설명하고, 다음의 코드의 문제점을 제시하고 최적화된 리팩토링 코드를 제출해주세요 리팩토링된 최적화 코드는 속도, 보안, 재활용성, 코드의 저용량화가 되어야 합니다 Explain the role of the temp function, suggest the problem of the following code, and submit the optimized refactoring code  Refactored optimization code must be speed, security, recyclability, and code low capacity

//모범답안
특정 값을 사용자의 localStorage에 저장할 수 있도록 하는 함수입니다.

사용예시는 다음과 같습니다.
temp('APPLE',{'iphonex', 'iphone8'});
이런식으로 APPLE이라는 값을 할당하고 {'iphonex', 'iphone8'}를 localStorage에 저장할 수 있습니다.

temp('APPLE')[1];
APPLE에 저장한 2번째 값을 가져올 수 있습니다. (iphone8 이 출력됩니다)

temp('APPLE','null');
APPLE에 저장한 값을 초기화할 수 있습니다.

사용자 브라우저에 쿠키와 같이 저장되는 데이터임으로 Client단의 임시저장값들을 저장하는용도로 사용할 수 있을것 같습니다.
다크모드 브라우징이나 과거에 검색한 데이터값등을 임시저장할때 사용할 수 있습니다.

코드상의 문제점으로는 
1. 로그인세션을 저장하기엔 localStorage가 취약함으로 sessionStorage를 활용하면 
단순히 사용자 브라우저에 임시저장값을 저장하는것에 그치지 않고 세션정보까지 안전하게 저장할 수 있습니다.
2. 웹 스토리지는 String데이터만 지원합니다. 따라서 inputdata에 JOSN형태로 변환하여 사용하는것이 더 좋습니다.

리팩토리코드는 다음과 같습니다.

let temp = function(flag,inputdata){
    if(flag !== undefined){
        if(inputdata !== undefined){
            if(inputdata === 'null'){
                sessionStorage.removeItem(flag);
                return true;
            }else{
                sessionStorage.setItem(flag, JSON.stringify(inputdata));
            }
        }else{
            let temp_array = new Array();
            for(var i=0; i<sessionStorage.length; i++){
                temp_array[sessionStorage.key(i)] = JSON.parse(sessionStorage.getItem(sessionStorage.key(i)));
            }
            if(temp_array.hasOwnProperty(flag)){
                return temp_array[flag];
            }else{
                return null;
            }
        }
    }else{
        var temp_array = new Array();
        for(var i=0; i<sessionStorage.length; i++){
            temp_array[sessionStorage.key(i)] = JSON.parse(sessionStorage.getItem(sessionStorage.key(i)));
        }
        return temp_array;
    }
};

 

 

9. arr_test 와 arr_car 2개의 배열을 서로 비교하여 platecode가 서로 같은 값을 갖는 배열을 출력하는 함수를 작성하여 제출해주세요 Please write and submit a function that compares the two arrays of arr_test and arr_car and outputs an array with the same platecode 

//모범답안
let arr_test = [['Favorite', 'apple'], ['Usually', 'banana'], ['Reluctant', 'watermeleon'],[0, ['platecode','116하6198']],[1,['platecode','101테1234']],[2,['platecode','57구9038']]];
let arr_car = new Array();
arr_car.push(new Array(['platecode','101테1234']));
arr_car.push(new Array(['platecode','57구9037']));
arr_car.push(new Array(['platecode','116하6198']));
arr_car.push(new Array(['platecode','07호6616']));
arr_car.push(new Array(['platecode','106호3084']));

var tranSimpleArray = function(arr){
	let output = '';
	for(let i=0; i<arr.length; i++){
		if(typeof arr[i] == 'object'){
			output += tranSimpleArray(arr[i]);
			output += ',';
		}else{
			output += arr[i];
			output += ',';
		}
	}
	output = output.toString();
	output = output.split(',');
	return output;
};
var compare_multi_array = function(array_x, array_y){
	let trans_x = tranSimpleArray(array_x);
	let trans_y = tranSimpleArray(array_y);
	let diff = trans_x.filter(x => trans_y.includes(x));
	let output = new Array();
	for(let i=0; i<diff.length; i++){
		if(diff[i] != '' && diff[i] != 'platecode'){
			output.push(diff[i]);
		}
	}
	return output;
};
console.log(compare_multi_array(arr_test, arr_car));

 

 

 

10. string 배열의 세로 순서대로 출력하는 함수를 작성하여 제출해주세요 작성되는 함수는 "이문제는정보올림피아드초등부문제입니다"으로 출력되어야 합니다 Write down a function that outputs in the vertical order of the string array and submit it  The function being written is "이문제는정보올림피아드초등부문제입니다" should be printed

//모범답안
let string = new Array();
string[0] = "이 피 입";
string[1] = "문보아등니";
string[2] = "제올 부다";
string[3] = "는 드문";
string[4] = "정림초제";
		
let test = function(input){
	let output = '';
	for(var j=0; j<8; j++ ){	
		for(var i=0; i<input.length; i++){
			if(input.length != null){
				output += input[i].charAt(j).replace(' ', '');
			}	
		}
	}
	return output;
};

console.log(test(string));

 

 

 

11. today 함수는 현재 사용자의 시간정보를 출력하는 함수이다. 이 함수에서 출력되는 String 형태의 시간정보가 30분단위로 가장 가까운 시간정보가 출력되도록 하는 코드를 작성한 뒤 제출해주세요 20220506182254 일때 20220506183054 으로 결과가 나와야하며, 20220506235521 일때 20220507000021 으로 결과가 나와야 합니다. The today function is a function that outputs time information of the current user. Please write a code to print the closest time information in the form of a string output from this function in 30 minutes and submit it   The result should be 20220506183054 when 20220506182254 and 20220507000021 when 20220506235521.

//모범답안
//비트연산을 위한 함수
let bitchange = function(n, digits) {
	var zero = '';
	n = n.toString();
	if(n.length < digits){
		for (var i = 0; i < digits - n.length; i++)
			zero += '0';
	}
	return zero + n;
};
let today = function () {
	let d = new Date();
	let diff = 0;
	if(30 > 60 - d.getMinutes()){
	//00분으로 나와야됨
		diff = 60 - d.getMinutes();
	}else{
	//30분으로 나와야함
		diff = 30 - d.getMinutes();
	}
	//증감되는만큼 현재시간에 반영
	d.setMinutes(d.getMinutes() + diff);
	//최적화 코드로 변경
	let output = bitchange(d.getFullYear(),4);
	output += bitchange(d.getMonth()+1,2);
	output += bitchange(d.getDate(),2);
	output += bitchange(d.getHours(),2);
	output += bitchange(d.getMinutes(),2);
	output += bitchange(d.getSeconds(),2);
	return bitchange(output.substring(0,14),14);
};
console.log(today());

 

 

 

 

12. zip 함수와 unzip 함수는 문자열을 압축하고 압축된 문자열을 원본으로 복원해주는 함수이다. 속도성능과 관계없이 가장 압축률이 높도록 아래의 함수를 완성하여 제출해주세요 극단적인 압축률을 적용하고 압축된 문자열이 정상적으로 복원되어야 합니다. 아래에 주어진 함수내부의 코드는 변경할 수 없습니다. 압축된 데이터는 문자비트 용량을 계산하지 않고 오직 문자길이만을 갖고 판단합니다. The zip function and the unzip function are functions that compress a string and restore the compressed string to its original state. Regardless of speed performance, please complete and submit the following function for the highest compression rate  Extreme compression rates must be applied and compressed strings restored normally. You cannot change the code inside the function given below. Compressed data is judged only by character length, not by character bit capacity.

//모범답안
//압축함수
let zip = function(input){
	let output = '';
	let cnt = 1;
	for(let i=0; i<input.length; i++){
		if(input[i] === input[i+1]){
			cnt++;
		}else{
			output += input[i];
			if(cnt>1){
				output += ':' + cnt.toString();
			}
	  	  cnt = 1;
		}
	}
	return output.toString();
};
//압축복원
let unzip = function(input){
	let output = '';
	let cache = '';
	let trans = input.split('.');
	let zipstring = trans[0];
	for(let i=0; i<zipstring.length; i++){
		if(zipstring[i] == ':'){
			for(let x=1; x<parseInt(zipstring[i+1]); x++){
				output += cache;
			}
			i++;
		}else{
			cache = zipstring[i];
			output += zipstring[i];
		}
	}
	return output.toString();
};

const test = "zz92kkaaaaaakkk00222221aaaaaakkkk2000000";
console.log(test);
console.log(zip(test)); //z:292k:2a:6k:30:22:51a:6k:420:6
console.log(unzip(zip(test)));
if(test === unzip(zip(test))){
	console.log('압축이 정상입니다');
}

 

 


직군성향 적합도 부문

1. 왜 개발자가 되고자 했는지 자유롭게 기술해주세요 Feel free to describe why you wanted to be a developer 

//모범답안
어릴적 우연히 C++을 접하고 다른사람들의 코드를 참조하면서 간단한 프로그래밍을 시작하게 되었습니다.
몇 줄 되지 않는 코드를 통해 선생님들께 반복적인 노가다성 행정업무를 한순간에 처리할 수 있는 매크로 프로그램등을 개발하여 드렸고,
덕분에 선생님들께 많은 부탁을 받고 코드를 짰던 기억이 납니다.

주변 사람이 나의 코드로 인해 말도 안되는 업무가 손쉽게 해결되고 
무엇보다 나의 코드로 인해 주변인에게 긍정적인 에너지를 줄 수 있다는것에 이 직업을 선택하게 된 가장 큰 동기가 되었습니다.

우리가 중세시대를 기반으로 하는 영화등에서 마법을 부리는 마법사를 볼 수 있는데,
개발자야말로 현재시대의 진정한 마법사라고 생각합니다.

우리가 개발하는 코드는 실존하지 않아 만질수도 직접 눈으로 볼 수 없지만,
이 코드는 가상세계에서 마법을 부릴 수 있고, 우리의 생활을 더욱 윤택하고 편리하게 만들어줄 수 있는 기술임에 틀림이 없습니다.

 

 

 

2. 단기적인 목표로 5년 뒤 어떤 개발자가 될 것인지와 그 단기적인 목표를 달성하기 위해 본인에게 어떤 미션들이 현재 있는지를 자유롭게 기술해주세요 Please feel free to describe what kind of developer you will be in five years with short-term goals and what missions you have in order to achieve that short-term goal 

//모범답안
저는 IT분야에도 관심이 많지만, 자동차산업에도 관심이 많습니다.
일을 하다가 중간에 번아웃이 왔을때 잠시동안 1년간 자동차정비소에서 정비사로 일을 하면서 
관심있는 자동차에 대해서도 구체적으로 잘 알게 되었습니다.
현재 잘하고 있는 IT분야와 자동차분야, 2가지 분야를 잘 융합하여 사용할 수 있는 
모빌리티서비스와 관련된 일을 하는것이 목표입니다.

모빌리티서비스를 개발하기 위해서는 IT도 잘 알아야하지만, 자동차도 이에 못지 않게 잘 알아야한다고 생각합니다.
이 목표를 실현시키기 위한 구체적인 방법으로 IT이외에 현재 갖고 있는 차량정비 자격증을 좀더 공부하여 정비산업기사를 취득할 계획을 갖고 있으며,
과거와 마찬가지로 설령 이직을 하게되는 상황에 놓여있을때도 모빌리티 산업과 관련된 회사로의 전직을 지속적으로 할 예정입니다.
과거에는 1가지에 대해서도 특출나면 기술자로써 대우받으며 살수 있다고 했지만,
미래에는 여러가지 일들을 융합하는 복합적인 기술에 대한 수요가 필요하다고 생각합니다.

 

 

3. A라는 개발 프로젝트가 있다고 가정했을 때, A라는 개발 프로젝트를 통해서 10명의 개발자가 고용이 창출된다. 하지만 A라는 개발 프로젝트를 통해서 100명의 실업자가 발생하게 된다면, 이 문제를 어떻게 해결할 것인지 자유롭게 기술해주세요 Assuming that there is a development project called A, 10 developers are hired through the development project called A. However, if there are 100 unemployed people through the development project called A, please feel free to describe how to solve this problem  

//모범답안
버스안내원과 같이 없어지는 직업이 생기는 만큼 새로운 직업이 생겨날것으로 보입니다.
버스카드로 손쉽게 환승도 가능하면서 더이상 버스안내원이 필요가 없어져
단기적으로 봤을때 실업자를 만들어주지만,
장기적으로 봤을때 질 좋은 직업을 더 만들어주는 효과가 있기 때문에
이것은 문제가 되지 않는다고 생각합니다.
해당 프로젝트에 의해 당장의 실업에 내몰리는 사람들은 해당 프로젝트를 위한 또다른 새로운 직업이 창출될 것으로 보입니다.
특히 기존 100명의 실업자들은 해당 분야에 오랜기간 노하우를 갖고 있음으로
이러한 노하우를 활용할 수 있는 프로젝트와 직접적인 관련 업무를 재할당하여
더 가치가 높고 질 좋은 일자리를 창출할 수 있다고 생각합니다.

 

 

4. 인공지능 딥러닝기술이 발전하여 인공지능이 자신의 코드를 지속적으로 보완하고 또 다른 인공지능 코드를 작성할 수 있다고 가정한다. 이 인공지능으로 인한 장점과 단점을 기술하고 개발자로써 이 상황을 어떻게 대처할 것인지 자유롭게 기술해주세요 It is assumed that artificial intelligence deep learning technology develops so that artificial intelligence can continuously supplement its own code and write another artificial intelligence code. Please describe the advantages and disadvantages of this artificial intelligence and feel free to describe how you will deal with this situation as a developer 

//모범답안
완벽하고 인간능력과 비등한 인공지능이 나와 인공지능이 대신 코드를 작성할 수 있다면,

장점으로는
더이상 개발자가 머리아픈일이 없습니다.
기업들은 인건비를 크게 절감하면서 빠르게 서비스를 개발할 수 있습니다.

단점으로는
인공지능의 높은 개발생산성으로 인해 중국게임앱들과 같이 수 많은 정크 서비스들이 출시할 것입니다.
현재 개발직에 종사하고 있는 수 많은 개발자들이 당장의 실업자로 내몰릴 수 있습니다.

개발자로써 이를 대처하는 자세로는
이러한 인공지능을 개발하는 인공지능 개발자로 발전해야합니다.
더이상 개발과 관련된 일을 하지 못하는것을 스스로 수렴하고 위의 단점에서 지적한 바와 같이
정크 서비스 중 고객에게 가장 적합한 서비스를 추천하는 카운슬러와 같은
또다른 창의적인 부가가치를 창출할 수 있는 일을 찾아야 합니다.
강력한 인공지능으로 인해 사람을 헤치는 일이 없도록 
인공지능에 대한 윤리규정과 발생할 수 있는 버그를 최소화 할 수 있도록 개발자로써 노력해야 합니다.

 

 


채용프로세스에 대한 면접관 역평가

1. 우리회사의 채용프로세스에 대해 본인의 의견을 자유롭게 작성해주세요 Please feel free to write your opinion on the recruitment process of our company 

 

 

2. 우리회사의 채용 과정에 학연, 출신, 인종, 나이, 성차별등의 부당한 대우를 경험 하셨습니까? Have you experienced unfair treatment of academic background, origin, race, age, gender discrimination, etc. in our hiring process? 

 

 

3. 부당한 대우를 경험하셨다면, 육하원칙에 따라 구체적으로 설명해주시길 바랍니다. If you have experienced unfair treatment, please explain it in detail according to the principle of land and land. 

 

 

 

2 Comments
댓글쓰기 폼