CSS / JavaScript 심화 예상 면접 질문 리스트

나는야 토마토·2022년 3월 7일
14

취업🧑‍💻

목록 보기
4/4
post-thumbnail

CSS

CSS보다 SCSS/SASS가 가진 장점에 대해 설명하세요.

SCSS와 SASS는 CSS의 Preprocessor(전처리기)입니다. CSS보다 쉬우면서, 추가 기능이 있는 CSS의 확장판 같은 역할을 하기에 크게 4가지의 장점이 있습니다. 첫번째로는 코드의 중복을 줄일 수 있습니다. CSS의 특성상, 셀럭터를 중복해서 사용해야하는 경우가 많습니다. SASS의 Nesting을 이용해 코드의 양을 줄이고, 연관된 코드를 그룹화할 수 있습니다. 두번째로는 변수, 함수, 연산자를 만들어 사용할 수 있습니다. 번수는 $ 달러 기호 모양으로 시작하는 변수를 지정해, 크기나 색상과 같은 값으로 일관적으로 변경할 수 있게 해줍니다. 세번째로는 mixin을 사용해 사이트 전체적으로 자주 쓰이는 CSS그룹을 만들고 재사용할 수 있습니다. 마지막으로 extend를 사용해 특정 셀렉터를 상속할 수 있게 하여, 셀렉터에 정의된 값을 한 곳에서 관리할 수 있게 합니다. 이러한 scss와 sass의 장점은 코드를 쉽게 관리할 수 있게 하여 유지보수성을 극대화시킵니다.

CSS와 SASS/SCSS의 차이점

  • SASS/SCSS에서는 Nesting을 이용해 연관된 코드를 그룹화 할 수 있다.
  • SASS/SCSS에서는 변수, 함수, 연산자를 만들어 사용할 수 있다.
  • SASS/SCSS에서는 mixin을 이용해 CSS 그룹을 만들고, 재사용할 수 있다.
  • SASS/SCSS에서는 extend를 사용해 특정 셀렉터를 상속할 수 있다.

CSS, SCSS, SASS의 차이점과 리액트와 사용할 거면 무엇을 쓸 건지 설명하세요.

저는 이 세가지 중에서 SCSS를 주로 사용해왔습니다. 왜냐하면 SCSS는 CSS의 문법을 그대로 사용하기에 호환성이 좋기 때문입니다. CSS에서는 셀렉터를 중복해서 사용하는 경우가 많았습니다. 그렇기 때문에 변수, 함수, 연산자를 만들어서 사용할 수 있는 SCSS와 SASS 중에서 고민하였습니다. SCSS와 SASS의 차이점에는{}(중괄호)와 ; (세미콜론)의 유무라고 말씀드릴 수 있습니다. 이 점에서는 생략되어지는 SASS가 편리할 수 있지만 mixin문법에서는 +와 -로 표시하기 때문에 직관적으로 코드가 보이지 않는 불편함이 있었습니다. 그렇기 때문에 저는 익숙한 CSS 문법을 사용하는 SCSS를 사용할 것입니다.

id와 class 셀렉터의 차이점에 대해 설명하세요.

id는 문서 안의 유일한 요소를 식별하고 싶을 때 사용하며, class는 공통점이 있는 여러 요소들을 그룹화하여 식별하고 싶을 때 사용합니다. CSS에서 id는 #(샾)을 붙이며, class는 .(피리어드)를 붙여서 구별합니다. 또한 id는 class의 속성보다 우선순위가 높으며, id의 속성은 해당 요소에 부여된 class의 속성과 관계없이 작동합니다.

CSS 박스 모델에 대해서 설명하세요.

모든 HTML요소는 박스 모양으로 구성되기 때문에, 이를 박스 모델이라고 합니다.박스 모델에서는 각 HTML 요소들에 padding, border, margin, content가 있습니다. content는 박스의 실질적 내용으로, 텍스트나 이미지 등 요소의 실제 내용이 들어갑니다. padding은 content와 border사이에 있는 안쪽의 여백입니다. border는 content와 padding을 감싸는 테두리입니다. 마지막으로 margin은 border를 기준으로 이웃하는 요소 사이의 간격입니다.

  • content: 박스의 실질적 내용으로, 텍스트나 이미지 등 요소의 실제 내용이 들어간다.
  • padding: content와 border 사이에 있는 안쪽 여백이다.
  • border: content와 padding을 감싸는 테두리이다.
  • margin: border를 기준으로 이웃하는 요소 사이의 간격이다.

CSS에서 px, em, rem, vh, vw 단위들의 차이점은 무엇인가요?

절대 길이 단위와 상대 길이 단위로 나누게 됩니다. 절대 길이 단위는 물리적인 측정 거리를 의미합니다. px은 절대길이 단위로, 일반적인 모니터 디스플레이의 1픽셀을 의미합니다. 나머지 단위들은 상대길이 단위입니다. 상대 길이 단위는 다시 글꼴 상대 길이와 뷰포트 백분율 길이로 나뉘게 됩니다. 글꼴 상대 길이는 길이값을 특정 문자나 현재 사용하는 폰트를 기준으로 설정하는 반면에 뷰포트 백분율 길이는 길이 값을 뷰포느 기준으로 설정합니다. emrem은 글꼴 상대 길이이며, vhvw는 뷰포트 상대 길이 입니다. em은 부모 요소의 폰트 사이즈를 기준으로 하는 반면에 rem은 루트요소 즉, 일반적으로 <html>요소의 폰트 사이즈를 기준으로 합니다. 그리고 vh는 뷰포트의 초기 컨테이너 블록의 높이 1%를 기준으로 하는 반면, vw는 뷰포트의 초기 컨테이너 블록의 너비 1%를 기준으로 합니다.

CSS 레이아웃 기법의 종류와 특징에 대해서 설명하세요. (grid, flexbox)

CSS 레이아웃 기법에는 크게 Flexbox와 grid 두 가지가 있습니다. flexbox는 인터페이스 내 아이템 간 공간 배분과 정렬 기능을 제공하기 위한 1차원 레이아웃 모델로 설계되었습니다. X축 또는 Y축 방향으로 요소를 배치, 정렬할 수 있어서 각 요소의 순서를 변경할 수 있습니다. 그렇기 때문에 기존 CSS 레이아웃 기술에 비교했을 때 손쉽게 멀티스크린에 대응할 수 있습니다. grid는 테이블처럼 세로 열과 가로 행을 기준으로 요소를 정렬합니다. 그러나 테이블에 비해 grid는 더 다양한 레이아웃을 구현할 수 있습니다. 행과 열 격자 구조에 요소를 자유롭게 배치할 수 있고, HTML 문서 위계 구조와 무관하게, grid 인터페이스 내부에 포함된 자식 아이템을 Grid 내부에 자유롭게 위치시킬 수 있습니다.

  • 1차원 레이아웃과 2차원 레이아웃은 무슨 차이가 있나요?

    flexbox는 레이아웃을 다룰 때 한 번에 하나의 차원(행이나 열)만 다루기 때문에 1차원이라 부른다. 반면, grid 레이아웃은 행과 열을 함께 조절하기 때문에 2차원 모델이라 부른다.

CSS in JS(styled component)의 장단점에 대해서 설명하세요.

css in JS를 사용하면 class 명이 빌드 시 유니크한 해시 값으로 변경되기 때문에 기존의 복잡한 class 명명 규칙을 해결해줍니다. 또한 컴포넌트 단위로 추상화 되기 때문에 css 파일 간에 의존성을 신경쓰지 않아도 되고, 컴포넌트와 CSS가 동일한 구조로 관리되기 때문에 불필요해진 CSS를 관리하기 위해서 별도의 리소스를 투입할 필요가 없습니다. 또한 CSS가 컴포넌트 스코프에서만 적용되기 때문에 우선순위 문제가 발생하지 않습니다. 하지만 번들의 크기가 커진다는 단점이 있습니다. CSS in JS를 사용하기 위해서는 여러 라이브러리를 사용하게 됩니다. 라이브러리의 추가는 곧 번들 사이즈가 증가함을 의미합니다. 번들 사이즈가 커지게 되면, 다운로드 시간도 오래 걸리기 때문에 사용자 경험에 치명적이게 됩니다. 특히나 CSS in JS는 자바스크립트가 모두 로딩 된 후 CSS 코드가 생성되기 때문에 더 느려집니다. 그렇기 때문에 인터렉션이 비교적 늦다는 단점도 있습니다.

position 속성과 z-index의 연관성에 대해 설명하세요.

이 둘은 먼저 나온 태그를 더 위에 배치시키고 싶다면 사용하는 속성들입니다. z-index는 position이 relative거나 absolute여야 동작합니다. 먼저 postion이 static 태그들이 나오는 순서대로 쌓이고, 그 위에 relative나 absolute인 태그들이 나오는 순서대로 쌓입니다. 흔히 이 둘은 웹이나 앱의 메뉴를 만들 때 가장 최 상단에 쌓여야하므로 그 때 주로 사용되어집니다.


JavaScript 심화

event loop에 대해서 설명하세요

자바스크립트는 단일 스레드 기반의 언어로 한 번에 하나의 작업만 처리할 수 있습니다. 그렇기 때문에 자바스크립트 엔진은 어떤 작업을 하면 중간에 어떤 함수도 실행될 수 없습니다. 하지만 그렇게 작업을 하게 되면 너무 많은 시간을 사용자는 기다려야합니다. 이러한 문제점을 해결하고자 함수 호출을 관리하는 call stack과 비동기 작업 처리를 위해 Web API가 함께 작업을 처리하게 됩니다. Web API는 작업 완료에 시간이 오래 걸리는 작업을 처리하게 되는데 이 결과값을 처리할 수 있는 callback 함수를 task queue에 쌓습니다. 이 때 작업이 다 완료가 되어서 call stack이 비어있게 되면 task queue의 담겨 있는 callback 함수를 다시 call stack으로 담아서 callback을 실행시키게 됩니다. 이 작업이 event loop입니다.

JavaScript event loop는 call stack이 비어있는 경우, task queue에서 대기하던 callback을 call stack으로 옮겨서 callback을 실행시켜주는 역할을 합니다.

callback, promise, async/await 의 특징과 차이점에 대해서 설명하세요.

일반적으로 다른 함수의 인자로 전달되는 함수를 callback이라고 합니다. 비동기 작업을 해결하기엔 충분했지만 함수에 담아서 사용해야하기 때문에 코드가 직관적이지 않아서 "callback hell"현상이 일어났습니다. 이 문제를 해결하고자 promise가 탄생하게되었습니다. promise는 성공과 실패라는 executor을 전달해주어야합니다. 이때 작업에 성공했을 경우는 resolve, 실패했을 경우는 reject라고 합니다.그래서 성공 시에는 resolve함수에서 전달된 인자가 인스턴스의 결과값으로 나오게 됩니다. 프로미스 인스턴스는 대기상태인 pending, 성공인 fulfilled, 실패한rejected 3가지 중 하나의 상태를 가집니다. promise는 then과 catch메소드로 프로미스를 리턴하기에 promise chaining이 가능합니다. 하지만 연속되는 비동기 작업이 순서대로 작동되어야하는 경우 콜백지옥처럼 프로미스 지옥이 발생하였습니다. 그래서 async/await가 발생하게 되었습니다. async/await는 동기적으로 작동하는 것처럼 Promise를 조금 더 쉽게 다룰 수 있게 만들어진 문법적 설탕이라고 불립니다. async/await 키워드만 적절히 사용하면 기존 함수를 작성하는 문법을 그대로 살릴 수 있습니다. async 함수를 실행하면 함수 내 리턴값 여부에 상관없이 Promise가 리턴되며, 함수 내의 리턴 값은 Promise result 값으로 전달되어집니다. await 키워드는 async 함수 내에서만 사용이 가능하며 응답이 올때까지 코드 읽기를 멈췄다가 요청이 오고나서야 다음코드를 실행하는 문법입니다. 이때 await로 실행된 코드는 Promise가 아닌 Promise의 result 값을 반환합니다.

Blocking과 Non-Blocking의 차이점은 무엇인가요?

Blocking은 호출된 함수가 자신이 할 일을 모두 마칠 때까지 제어권을 계속 가지고 호출한 함수가 대기하도록 하는 것입니다. 예를 들어 실행하는 데 10초가 걸리는 A라는 함수가 실행되면 B라는 함수가 실행되기까지 10초간 대기해야합니다. 반면에 Non-Blocking은 호출된 함수가 할일을 마치지 않았더라고 제어권을 내주어 호출한 함수가 다른 일을 진행할 수 있는 것입니다. 예를 들어 A함수가 종료되지 않은 상태여도 바로 B함수를 실행할 수 있습니다.

Synchronous execution과 Asynchronous execution의 차이점은 무엇인가요?

동기 실행은 한 작업이 끝남과 동시에 다음 작업이 실행되는 실행방식을 의미합니다. 예를 들어 함수 A가 실행이 완료되자마자 함수 B가 연속적으로 실행되었다면 이것은 동기적 실행입니다. 싱글 스레드에서 synchronous execution은 한 번에 하나씩 작업을 하게 됩니다. 멀티 스레드인 경우에도 동기적으로 실행된다면 A작업이 끝날 때까지 B작업은 기다려야합니다. 비동기 실행은 한 작업이 끝나기 전에 다른 작업을 수행할 수 있습니다. 예를 들어 함수 A가 실행 중인데, 함수 B가 실행되었다면 이는 비동기적 실행입니다. 싱글 스레드에서 Asynchronous execution은 한 스레드에서 여러 작업을 수행할 수는 있지만, 결국 한 번에 여러 작업을 수행할 수는 없습니다. 반면에 멀티스레드인 경우는 여러 작업이 비동기로 실행되는 경우 여러 스레드가 동시에 작업할 수 있습니다.

nodejs는 싱글쓰레드인가요?

node.js는 싱글 스레드 방식이 아닙니다. 싱글 스레드 방식으로 동작하는 것은 브라우저에 내장된 자바스크립트 엔진입니다. 만약 모든 자바스크립트 코드가 자바스크립트 엔진에서 싱글 스레드 방식으로만 동작한다면 비동기적으로 동작할 수 없을 것입니다. 즉, 자바스크립트 엔진은 싱글 스레드로 동작하지만 브라우저나 Node.js는 멀티 스레드로 동작하는 것입니다.

nodejs는 event-driven architecture 인가요?

우선 event-driven architecture에 대해 설명 드리겠습니다. 이벤트 기반 아키텍처는 애플리케이션 설계를 위한 소프트웨어 아키텍처 및 모델입니다. 예를 들어 판매 중인 컴퓨터를 사용자가 구매하여 판매된 상태로 바뀌게 되었을 때 컴퓨터이 상태 변화를 감지한 시스템에서 이벤트가 발생하게 되어서 관련 부서 시스템에 자동으로 상태가 변경됨을 전송합니다. 이후 전송된 이벤트는 각 시스템의 요구에 따라 적절한 처리 과정을 거치게 됩니다. 끊임없이 변화하며 상호작용하는 데이터 간 흐름에서 사용자가 일으긴 동작을 event라고 합니다. 즉 키보드와 마우스의 조작으로 상황에 따라 그에 반응하는 코드로 인해 새로운 현상이 일어나는 것을 예로 들 수 있습니다. Node.js엔ㄴ HTML 요소가 없기 때문에 대부분의 event는 프로세스, 네트워크 파일 과의 상호작용 등에서 비롯됩니다. 따라서 Node.js는 event-driven atchitecture라고 할 수 있습니다.

this와 dynamic scoping

this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기참조 변수를 뜻합니다. this는 지역변수처럼 사용될 수 있으며, 함수가 호출되는 시점에 의해 동적으로 결정되는 dynamic scope입니다. dynamic scope는 함수를 호출한 위치가 아닌 어디서 호출했는지에 따라 동적으로 상위 스코프를 결정하는 것을 뜻합니다. 그러므로 this는 함수가 호출되는 시점에 의해 동적으로 결정되기 때문에 dynamic scope를 따르게 됩니다.

객체 지향 프로그래밍이란 무엇인가요?

객체 지향 프로그래밍은 서로 연관된 변수와 함수를 그룹핑해서 소프트웨어를 조금 더 쉽고 명확하게 관리할 수 있도록 해주는 것을 뜻합니다. 예를 들어 옷정리를 할 때 겨울옷과 여름옷으로 구분하여 정리를 할 때처럼 서로 연관되어 있는 것들은 기능별로 그룹화해서 이름을 붙여서 프로그래밍을 할 수 있습니다. 이 객체 지향을 사용한다면 유지보수가 쉽고 프로그램의 생산성을 높일 수 있습니다.

Prototype Chaining

prototype chaining은 기존에 존재하는 객체를 기반으로 새로운 객체를 생성할 때 사용됩니다. 만약 객체의 프로퍼티에 접근하려고 할 때, 프로퍼티가 없다면 _proto__ 접근자 프로퍼티를 따라서 본인의 부모 역할을 하는 객체를 순차적으로 돌아다니며 검색합니다. Prototype Chaning의 최상위 객체는 Object.prototype이며, 해당 객체의 프로퍼티, 메소드는 모든 객체에게 상속됩니다.

IIFE

IIFE는 함수 정의와 동시에 즉시 호출되는 즉시 실행함수를 의미합니다. 즉시실행함수는 단 한번만 호출이 되며 다시 사용할 수 없는 특성이 있습니다. 예를 들어 어떠한 버튼을 클릭할 때마다 카운트를 올려주고, 해당 클릭 수를 alert창으로 띄워준다고 가정해보겠습니다. 'count'라는 전역변수를 선언한 후 해당 변수를 계속해서 참조할 수도 있겠지만, click하는 event handler 자체에 해당 데이터를 넣는 방법이 더 좋을 것 같습니다. 그렇게 되면 추가적인 변수로 global scope를 더럽히지 않고, IIFE를 적용해 closure를 조정하여 'count'변수를 외부에서 참조하지 못하도록 보호 할 수 있게 됩니다. 이러한 상황에서 IIFE가 사용되어지기에 'count'에 담겨있는 데이터의 부작용을 사전에 방지시킬 수 있습니다.

setTimeout 에서 this는 왜 전역을 가리키는지 설명하세요.

setTimeOut()에 의해 실행된 코드는 별도의 실행 컨텍스트에서 setTimeOut이 호출된 함수로 호출되어집니다. this는 함수의 호출 방식에 의해서 결정되기에 this를 호출된 함수에서 설정 혹은 할당하지 않는 경우, non-strice모드에서는 전역(혹은 window) 객체, strict 모드에서는 undefined를 기본 값으로 합니다. 그렇기에 setTimeOut함수를 이용해서 window객체나 undefined가 출력되는 에러를 볼 수 있습니다. 이 방법을 해결하기 위해서는 3가지 해결책이 있습니다. 첫번째로는 this 설정이 필요한 곳을 함수로 감싸주고, 두번째는 화살표 함수로 작성하는 방법입니다. 마지막인 세번째는 bind를 활용해서 this를 지정해주면 됩니다.

setTimeout()에 의해 실행된 코드는 별도의 실행 컨텍스트에서 setTimeout이 호출된 함수로 호출됩니다. 호출된 함수에 대해서는 this 키워드를 설정하는 일반적인 규칙이 적용되며, this를 설정 혹은 할당하지 않은 경우, non-strict 모드에서 전역(혹은 window) 객체, strict모드에서 undefined를 기본 값으로 합니다. 다음 예제를 봐주세요.

myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
    alert(arguments.length > 0 ? this[sProperty] : this);
};

myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"

위와 같이 동작하는 이유는 myMethod 호출될 때, this는 myArray로 설정되므로, 함수 내에서의 this[속성]은 myArray[속성]와 같습니다. 하지만, 다음 예제를 보면:

setTimeout(myArray.myMethod, 1000); // 1초 뒤 "[Window 객체]" 출력
setTimeout(myArray.myMethod, 1500, "1"); // 1.5초 뒤 "undefined" 출력

myArray.myMethod 함수는 setTimeout에 전달되고, 호출될 때 this는 설정되어 있지 않아 window 객체를 기본값으로 합니다. forEach, reduce 등 Array 메서드 같이 this를 매개변수로 넘길 수 있는 옵션 또한 없습니다. 그리고 아래에서 보다시피, call을 사용해 this를 설정하는 것도 동작하지 않습니다.

setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

그렇다면 해결책은 무엇일까요?

  • this 설정이 필요한 곳을 함수로 감싸는 것(Wrapper Function) 입니다.
setTimeout(function(){myArray.myMethod()}, 2000); // 2초 뒤"zero,one,two" 출력
setTimeout(function(){myArray.myMethod('1')}, 2500); // 2.5초 뒤"one" 출력
  • 화살표 함수(Arrow Function) 역시 가능한 대안입니다.
setTimeout(() => {myArray.myMethod()}, 2000); // 2초 뒤 "zero,one,two" 출력
setTimeout(() => {myArray.myMethod('1')}, 2500); // 2.5초 뒤 "one" after 2.5 출력
  • bind를 활용해서 this를 지정해주는 방법도 있습니다.
var healthObj = {
	name : "달리기",
	lastTime : "PM10:12",
	showHealth : function() {
        setTimeout(function(){
            console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
        }.bind(this), 500);
    }
}

스택과 힙의 차이에 대해서 설명하세요.

자바스크립트는 콜 스택과 메모리 힙이라는 메모리 구조를 통해 데이터 및 코드를 실행관리합니다. 여기서 콜 스택은 원시타입 즉, 숫자, 문자와 같은 데이터가 저장되는 공간이고, 메모리 힙은 참조타입인 배열, 객체 함수 같은 데이터가 저장됩니다. 즉, 참조타입 데이터를 선언하게 되면 해당 주소값만 콜 스택에 저장되고 주소값에 따른 value는 힘에 저장되어집니다.

call-by-value에 대해서 설명하세요.

call-by-value는 함수 호출 방식 중 하나입니다. 값에 의한 호출이라고 불러집니다. 기본적으로 자바스크립트는 원시값을 argument로 넘겨주면 call-by-value의 형태로 작동합니다. 더 자세히 설명드리자면 함수를 호출하면 argument로 값이 넘어오게 됩니다. 여기서 argument는 함수의 변수에 집어넣는 값을 의미합니다. 그 값은 복사된 값으로 넘어오게 되고 복사되었기에 해당 인자를 변형시켜도 영향을 받지 않습니다. 그렇기에 기존 정의 된 인자를 출력한다면 값이 바뀌지 않다는 것을 확인할 수 있습니다.

call-by-value

  1. 함수를 호출하게 되면 arguments로 값이 넘어옵니다.
  2. 그 값은 복사된 값으로 넘어옵니다.
  3. caller가 인자를 복사해서 넘겨줬으므로 callee에서 해당 인자를 변형시켜도 caller는 영향을 받지 않습니다.
var a = 1;
var func = function(b) { // callee
  b = b + 1;
	console.log(b) // 2
}
func(a); // caller
console.log(a); // 1

call-by-reference

  1. arguments로 reference(값에 대한 참조 주소, 메모리 주소를 담고있는 변수) 주소값을 넘겨줍니다.
  2. reference가 가리키는 주소값을 얕은 복사로 넘겨주게 됩니다.
  3. caller가 인자를 주소값만을 복사했기 때문에 callee에서 해당 인자를 변경하면 caller는 영향을 받습니다.
var a = {};
var func = function(b) { // callee
  b.a = 1;
}
func(a); // caller
console.log(a.a); // 1
profile
토마토마토

0개의 댓글