80%의 지원자 가 모두 합격 하지 못 한 JS 면접 문제
보 잘 것 없 는 시작
전단 엔지니어,특히 중급 전단 엔 지 니 어 를 모집 하 는 것 은 탄탄 한 JS 기반 이 절대적 으로 필요 한 조건 이 며,기초 가 부실 한 엔 지 니 어 는 전단 개발 의 각종 문제 에 직면 할 때 아마 속수무책 일 것 이다.후보 JS 기반 을 살 펴 볼 때 저 는 다음 코드 를 제공 한 다음 에 후보 에 게 실제 운행 결 과 를 분석 하 게 합 니 다.
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(new Date, i);
}, 1000);
}
console.log(new Date, i);
이 코드 는 매우 짧 고 7 줄 밖 에 없다.나 는 여기까지 읽 을 수 있 는 학우 들 이 내 가 이 코드 가 무엇 을 하고 있 는 지 한 줄 씩 설명 할 필요 가 없 을 것 이 라 고 생각한다.후보 들 이 이 코드 에 직면 했 을 때 내 놓 은 결과 도 다 르 고 다음은 전형 적 인 답 이다.A.20%는 코드 를 빠르게 스 캔 한 다음 에 결 과 를 제시한다.0,1,2,3,4,5.
B.30%는 코드 를 들 고 한 줄 씩 보고 결 과 를 제시한다.5,0,1,2,3,4.
C.50%의 사람들 이 코드 를 가지 고 곰 곰 이 생각해 보고 결 과 를 제시한다.5,5,5,5,5,5.
JS 에서 동기 화 와 비동기 코드 의 차이,변수 역할 영역,폐쇄 등 개념 에 대해 정확 한 이 해 를 가지 면 정 답 은 C 이 고 코드 의 실제 출력 은:
2017-03-18T00:43:45.873Z 5
2017-03-18T00:43:46.866Z 5
2017-03-18T00:43:46.868Z 5
2017-03-18T00:43:46.868Z 5
2017-03-18T00:43:46.868Z 5
2017-03-18T00:43:46.868Z 5
다음 에 저 는 만약 에 우리 가 약속 하면 화살표 로 앞 뒤의 두 번 의 출력 사이 에 1 초의 시간 간격 이 있 음 을 나타 내 고 쉼표 는 앞 뒤의 두 번 의 출력 사이 의 시간 간격 을 무시 할 수 있 음 을 나타 내 며 코드 가 실제 실행 되 는 결 과 는 어떻게 설명 해 야 합 니까?다음 두 가지 답 이 있 습 니 다.A.60%는 5->5->5->5->5->5 로 묘사 합 니 다.즉,5 사이 에 1 초 간격 이 있 습 니 다.
B.40%는 5->5,5,5,5,5,5,5,5,즉 첫 번 째 5 를 직접 출력 하고 1 초 후에 5 개 를 출력 한다.
이 는 후보 들 이 JS타이머 작업 메커니즘에 대해 잘 알 고 순환 집행 과정 에서 거의 동시에 5 개의 타 이 머 를 설치 해 야 한다.일반적인 상황 에서 이 타 이 머 는 1 초 후에 촉발 되 고 순환 이 끝 난 출력 은 바로 실행 되 며 정확 한 설명 은 B 이다.
만약 에 여기까지 합격 한 셈 이 라면 100 명 이 면접 을 보면 20 명 만 합격 할 수 있 습 니 다.여기까지 읽 은 친구 들 은 곰 곰 이 생각해 볼 수 있 습 니 다.당신 은 합 격 했 습 니까?
추궁 1:폐쇄
만약 에 이 문제 가 후보자 가 JS 비동기 코드,변수 역할 영역 에 대한 이 해 를 고찰 하 는 것 이 라면 한계 가 너무 크다.그 다음 에 기대 코드 의 수출 이 5->0,1,2,3,4 로 바 뀌 면 코드 를 어떻게 개조 해 야 하 는 지 물 어 볼 것 이다.폐쇄 에 익숙 한 학우 들 은 곧 다음 과 같은 해결 방법 을 제시 할 수 있다.
for (var i = 0; i < 5; i++) {
(function(j) { // j = i
setTimeout(function() {
console.log(new Date, j);
}, 1000);
})(i);
}
console.log(new Date, i);
IIFE(Immediately Invoked Function Expression:성명 즉 실 행 된 함수 표현 식)를 교묘 하 게 이용 하여 폐쇄 로 인 한 문 제 를 해결 하 는 것 은 좋 은 생각 이지 만 초보 자 들 은 이런 코드 가 잘 이해 되 지 않 을 것 이 라 고 생각 할 수 있 습 니 다.적어도 필자 가 처음 입 문 했 을 때 이 문 제 를 한참 생각 하고 나 서 야 진정 으로 이해 할 수 있 었 습 니 다.더 직관 적 인 방법 이 있 습 니까?정 답 은 있 습 니 다.우 리 는 순환 체 에 대해 조금 만 손 을 써 서 출력 을 담당 하 는 코드 가 매번 순환 하 는 i 값 을 얻 을 수 있 도록 하면 됩 니 다.어떻게 해 야 되 지?JS 의 기본 형식(Primitive Type)의 매개 변 수 를 이용 하여 전달 하 는 것 은 값 에 따라 전달 하 는 것(Pass by Value)의 특징 이 므 로 다음 코드 를 바 꾸 는 것 이 어렵 지 않 습 니 다.
var output = function (i) {
setTimeout(function() {
console.log(new Date, i);
}, 1000);
};
for (var i = 0; i < 5; i++) {
output(i); // i
}
console.log(new Date, i);
이 같은 2 가지 솔 루 션 을 제시 할 수 있 는 후보 들 은 JS 기반 에 대한 이해 와 운용 이 10 점 씩 가산 점 으로 좋다 고 볼 수 있다.물론 실제 면접 에 서 는 다음 과 같은 코드 를 제시 하 는 후보 도 있다.
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(new Date, i);
}, 1000);
}
console.log(new Date, i);
세심 한 동창 회 에 따 르 면 여 기 는 아주 작은 변동 만 있 습 니 다.즉,ES6블록 급 역할 영역(Block Scope)중의 let 를 사용 하여 var 를 대 체 했 지만 코드 가 실제 운행 할 때 잘못 보고 되 었 습 니 다.마지막 으로 그 출력 에 사용 되 는 i 는 그 역할 영역 에 존재 하지 않 고 i 는 순환 내부 에 만 존재 하기 때 문 입 니 다.ES6 의 특성 을 떠 올 리 는 학우 들 은 정 답 을 맞 히 지 못 했 지만 ES6 에 대한 이 해 를 보 여 주 며 5 점 을 더 해 아래 의 추궁 을 이 어 갔다.
추궁 2:ES6
경험 이 있 는 전단 학우 들 이 여기까지 읽 으 면 좀 짜증 이 날 것 이다.이렇게 많은 말 을 했 는데 모두 그 가 아 는 내용 이 니 조급해 하지 마라.도전 의 난이 도 는 계속 증가 할 것 이다.
이 어 상기 에서 계속 추궁 했다.만약 에 기대 코드 의 출력 이 0->1->2->3->4->5 로 변 하면 기 존의 코드 블록 중의 순환 과 두 곳 의 console.log 가 변 하지 않 으 면 코드 를 어떻게 개조 해 야 합 니까?새로운 수 요 는 코드 가 실 행 될 때 바로 0 을 출력 하고 그 다음 에 1 초 마다 1,2,3,4 를 순서대로 출력 한다.순환 이 끝 난 후에 약 5 초 에 5 를 출력 한다.(여기 서 약 을 사용 하 는 것 은 소 뿔 을 뚫 는 학생 들 이 빠 지지 않도록 하 는 것 이다.JS 의 타이머 트리거 시기 가 불확실 할 수 있 기 때문에 구체 적 으로 참고 할 수 있다How Javascript Timers Work.
여기 서 일부 동창 회 는 다음 과 같은 실행 가능 한 해 를 제시한다.
for (var i = 0; i < 5; i++) {
(function(j) {
setTimeout(function() {
console.log(new Date, j);
}, 1000 * j)); // 0~4
})(i);
}
setTimeout(function() { // , 5
console.log(new Date, i);
}, 1000 * i);
이런 방법 은 거 칠 고 효과 가 있 지만 추가 가산 점 을 받 을 수 있 는 방안 은 아니 라 는 것 을 인정 할 수 밖 에 없다.만약 에 이번 수 요 를 일련의 비동기 작업 이 완 성 된 후에 다른 일 을 하면 코드 는 어떻게 조직 해 야 합 니까?똑똑 한 너 뭐 생각 났 지?네,바로Promise입 니 다.콘 솔 에서 몇 개의 숫자 를 출력 하 는 것 이 아니 냐 고 물 을 수도 있 습 니 다.이렇게 닭 잡 는 데 소 칼?면접 관 이 진정 으로 고찰 하고 자 하 는 것 은 후보자 가 어떤 능력 과 소양 을 갖 추고 있 는 지 하 는 것 이다.왜냐하면 현대 의 전단 개발 에서 비동기 적 인 코드 를 처리 하 는 것 을 곳곳에서 볼 수 있 고 비동기 적 인 작업 의 절차 통 제 를 익히 고 파악 하 는 것 이 합격 개발 자가 되 는 기본 적 인 기능 이기 때문이다.
따라서 Promise 기반 솔 루 션 을 제시 하 는 것 은 어렵 지 않 습 니 다.(Promise 가 ES6 의 새로운 기능 이 므 로 새 코드 는 ES6 로 작성 하 는 것 이 좋 지 않 을까요?만약 당신 이 이렇게 썼 다 면 아마도 면접 관 에 게 호감 을 가지 게 될 것 입 니 다):
const tasks = [];
for (var i = 0; i < 5; i++) { // i let, ?
((j) => {
tasks.push(new Promise((resolve) => {
setTimeout(() => {
console.log(new Date, j);
resolve(); // resolve, work
}, 1000 * j); //
}));
})(i);
}
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date, i);
}, 1000); // 1
});
이에 비해 필 자 는 아래 와 같이 더욱 간결 해 보 이 는 코드 를 선 호한 다.프로 그래 밍 스타일 도 많은 면접 관 들 이 중점적으로 고찰 하 는 점 임 을 알 아야 한다.코드 를 읽 을 때 입자 가 더 작고 모듈 화가 더 좋 으 며 가산 점 이 될 것 이다.
const tasks = []; // Promise
const output = (i) => new Promise((resolve) => {
setTimeout(() => {
console.log(new Date, i);
resolve();
}, 1000 * i);
});
//
for (var i = 0; i < 5; i++) {
tasks.push(output(i));
}
// , i
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date, i);
}, 1000);
});
여기까지 읽 은 친구,축하합니다.다음 면접 에서 비슷 한 문 제 를 만나면 적어도 80 점 을 받 을 수 있 습 니 다.Promise 를 사용 하여 비동기 코드 를 처리 하 는 것 이 리 셋 메커니즘 보다 코드 의 가 독성 이 높다 는 것 을 잘 알 고 있 습 니 다.그러나 Promise 를 사용 하 는 문제 도 분명 합 니 다.즉,Promise 의 reject 를 처리 하지 않 으 면 오류 가 발생 할 수 있 습 니 다블랙홀 에 빠뜨리다.다행히 새 버 전의 Chrome 과 Node 7.x 는 처리 되 지 않 은 이상 에 대해Unhandled Rejection Warning을 줄 수 있 습 니 다.이런 오 류 를 조사 하 는 데 는 특별한 기술브 라 우 저,Node.js이 필요 하 다.
3:ES7 추궁
여기까지 봤 으 니 2 분만 더 버 텨 보 세 요.다음 내용 은 당신 의 버 티 는 것 이 가치 가 있다 는 것 을 알 게 해 줄 것 입 니 다.
대부분의 면접 관 들 은 한 후 보 를 채용 하기 로 결정 하기 전에 또 다른 중요 한 능력,즉 기술 자 구력 을 살 펴 봐 야 한다.솔직히 말 하면 후보 들 이 내부 모터 가 그 를 움 직 이 고 공정 분야 의 문 제 를 예 쁜 방식 으로 해결 하 며 업무 와 기술 에 따라 점점 강해 지 는 것 은 무엇 일 까?프로그램 인생분석을 읽 는 것 을 권장 합 니 다.
본론 으로 돌아 가 Promise 가 제거 되 었 으 니 ES7 의 async await 특성 을 어떻게 사용 하여 이 코드 를 더욱 간결 하 게 만 듭 니까?당신 은 현재 파악 하고 있 는 지식 에 근거 하여 답 을 줄 수 있 습 니까?여기 서 1 분만 멈 추고 생각 하 세 요.
다음은 필자 가 제시 한 참고 코드 이다.
// sleep,
const sleep = (timeountMS) => new Promise((resolve) => {
setTimeout(resolve, timeountMS);
});
(async () => { // async
for (var i = 0; i < 5; i++) {
await sleep(1000);
console.log(new Date, i);
}
await sleep(1000);
console.log(new Date, i);
})();
총결산여기까지 읽 어 주 셔 서 감사합니다. JS 로 코드 출력 을 정확하게 제어 하 는 여러 가지 기술 뿐만 아니 라 전단 엔지니어 의 성장 에 대한 기대 도 얻 을 수 있 습 니 다.튼튼한 언어 기반,시대와 함께 발전 하 는 능력,강력 한 기술 자 구력 입 니 다.
더 많은 면접 문제 학습 자 료 는 주제《면접 문제 대전》.에 주목 하 세 요.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JS 판단 수조 네 가지 실현 방법 상세그러면 본고는 주로 몇 가지 판단 방식과 방식 판단의 원리를 바탕으로 문제가 있는지 토론하고자 한다. 예를 들어 html에 여러 개의 iframe 대상이 있으면 instanceof의 검증 결과가 기대에 부합되지 않을...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.