Skip to content

개발 상식

A-by-alimelon edited this page Dec 26, 2020 · 3 revisions

개발 상식

JaeYeopHan/Interview_Question_for_Beginner

  • 좋은 코드란 무엇인가?

    좋은 코드란 무엇일까?

    • 읽기 쉬운 코드

      → 왜 읽기 쉬운 코드가 좋은 코드인가?

      → 읽기 쉽도록 작성하려면 어떻게 해야하지?

      와 같은 물음들로 좋은 코드에 대한 근본적인 정의를 찾아 갈 수 있다.

    • 중복이 없는 코드

      동일한 로직을 수행하는 코드는 별도의 함수로 빼두고 재사용해야 하나의 코드에 변경 사항이 있을 때도 버그의 발생 확률을 줄일 수 있다.

      그러나 그 땐 같았지만 지금은 같지 않는 코드가 생기면 변경 사항을 반영하는데 또 다른 비용이 들어간다.

      그렇다면 추출(extraction)은 어떤 기준으로 해야할까?

    • 테스트가 용이한 코드

      → 테스트가 용이하다는 것은 무엇을 의미하는 것일까?

    • 좋지 않은 코드가 생기는 시점

      • 쓰이지 않는 코드

        쓰지 않는 코드지만 어딘가에서 쓰일지도 모른다는 불안감이 생겨버린다. 이 불안감이 생기는 이유는 무엇일까?

        1. 거리

          코드가 정의된 곳과 쓰이는 곳이 멀게 되면 그 코드의 사용 범위를 확인하기 힘들어지고 결과적으로 코드를 지워도 될지 안될지 확신이 서지 않는다.

        2. 순수하지 않은 함수

          함수 외부의 어떤 값에 영향을 받는 코드라면 side effect를 제어하기 힘들기 때문에 수정하기 힘들다.

    • 좋은 코드란 좋지 않은 코드가 없는 코드를 말한다 좋지 않은 코드를 줄여보자

    • 추출이 아닌 추상화

      • 여러 로직이 얽혀있을 때 서로 의존 관계에 있는 것들을 추출해낸다. 추상화 된 함수는 하나의 목적(역할)을 갖게 되고 의미 있는 추출(추상화)이 이루어진다.
      • 어쩔 수 없이 좋지 않게 작성되는 코드들은 주석과 함께 격리시켜 관리 할 수 있다.
    • 일관성 있는 코드

      1. naming
      2. directory
    • 확장성 있는 코드

    • 결론 : 의존성, 일관성, 확장, 격리

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

    인간 중심적 프로그래밍 패러다임, 현실 세계의 사물들을 객체라고 보고 그 객체로부터 개발하고자 하는 애플리케이션에 필요한 특징들을 뽑아와 프로그래밍 하는 것이다. 이것을 추상화라 한다.

    추상: 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용.

    재사용성 / 내부적으로 어떻게 동작하는지 몰라도 라이브러리가 제공하는 기능을 사용할 수 있어 생산성이 높아진다.

    디버깅이 쉽고 유지보수에 용이하다. 데이터 모델링 과정에서 객체와 매핑하는것이 수월

    객체 간 정보 교환이 모두 메세지 교환을 통해 일어나 overhead가 발생하지만 하드웨어의 발전으로 많은 부분 보완.

    객체가 상태를 갖는다는 것이 단점. 변수가 존재하고 변수로 인해 객체의 상태를 예측할 수 없어 버그를 발생

    • 객체 지향의 개념들

      객체의 핵심은 기능이며, 이 기능을 오퍼레이션이라고 부른다.

      객체가 제공하는 모든 오퍼레이션 집합을 객체의 인터페이스라고 한다.

      오퍼레이션의 실행을 요청하는 것을 메세지를 보낸다 라고 표현. 메서드를 호출하는 것이 메세지를 보내는 과정에 해당.

      객체를 정의할 때 사용하는 것은 객체가 제공해야할 기능이며 이 기능에는 책임이 있다. 객체가 가진 책임의 크기는 작을수록 유연해지며, 이것을 단일 책임 원칙(Single Responsibility Principle: SRP) 이라고 한다.

      한 객체가 다른 객체를 이용한다는 것은 한 객체의 코드에서 다른 객체를 생성하거나 다른 객체의 메서드를 호출한다는 것을 의미한다. 그 변경의 여파가 다시 자기 자신까지 변화시킬 수 있는데, 이것을 순환 의존이라고 한다. 이것을 해결하기 위한 방법을 Dependency Inversion Principle(DIP) 라고 한다.

      • 캡슐화

        1. Tell, Don't Ask - 데이터를 숨기고 기능을 실행해 달라고 말하라

        2. 데미테르 법칙

          • 메서드에서 생성한 객체의 메서드만 호출

          • 파라미터로 받은 객체의 메서드만 호출

          • 필드로 참조하는 객체의 메서드만 호출

      • 재사용 - 상속보단 조립! https://koseungbin.gitbook.io/wiki/books/undefined/part-1./undefined-3

        상속은 명확학 IS-A 관계가 성립되어야 한다.

      참고 : https://asfirstalways.tistory.com/177

    • 객체 지향적 설계 원칙 (SOLID)

      1. SRP (Single Responsibility Principle)

      2. OCP (Open-Closed Principle)

      3. LSP (Liskov Substitution Principle) - 자식 클래스가 부모 클래스로 치환가능

      4. ISP ( Interface Segregation Principle) - 클라이언트가 자신이 이용하지 않는 메서드에 의존하면 안된다.

      5. DIP (Dependency Inversion Priciple) - 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.

        https://ktko.tistory.com/entry/자바-객체-지향의-원리-SOLID-DIP-의존-역전-원칙

  • 함수형 프로그래밍이란?

    Function - 함수를 이용해서 No Side-Effect - 사이드 이펙트 없도록 Declarative Programming - 선언형 프로그래밍을 이용

    • immutable data

      -변경 불가능함

    • first-citizen(일급 객체)

      -변수나 데이터 구조안에 함수를 담을 수 있어 함수의 파라미터로 전달 가능, 반환값으로 사용가능

      -고유한 구별이 가능

      -함수를 리터럴로 바로 정의 가능

  • 프로토콜 지향 프로그래밍

    Swift - 프로토콜 지향 프로그래밍 - yagom's blog

    • 익스텐션을 사용한 프로토콜 초기 구현

      protocol Talkable {
          var topic: String { get set }
          func talk(to: Self)
      }
      
      // 익스텐션을 사용한 프로토콜 초기 구현
      extension Talkable {
          func talk(to: Self) {
              print("\(to)! \(topic)")
          }
      }
      
      struct Person: Talkable {
          var topic: String
          var name: String
      }
      
      struct Monkey: Talkable {
          var topic: String
      }
      
      let yagom = Person(topic: "Swift", name: "yagom")
      let hana = Person(topic: "Internet", name: "hana")
      
      yagom.talk(to: hana)
      hana.talk(to: yagom)

      POP의 장점은?

      상속은 클래스 타입만 가능하다. 클래스는 참조 타입이므로 참조 추적에 비용이 많이 발생 → POP는 그 한계를 없앰

      기능의 모듈화가 더욱 명확하다. 다중상속을 지원하는 언어는 많지 않다.

      서브클래싱과 다른게 각각이 독립적이며 그래서 안전하다. 다수의 프로토콜을 따르는 것이 가능하다.

  • RESTFul API 란?

    Rest는 REpresentational State Transfer의 약자로 REST의 기본원칙을 성실히 지킨 서비스 디자인은 RESTful하다고 할 수 있다.

    REST는 하나의 아키텍처 - Resource Oriented Architecture로 API 설계 중심에 자원이 있고 HTTP Method를 통해 자원을 처리하도록 설계

    1. Uniform Interface (통일된 인터페이스)
    2. Stateless (무상태성)
    3. Cacheable (캐시 가능)
    4. Self-descriptiveness (자체 표현 구조)
    5. Client - Server 구조 - 역할 구분
    6. 계층형 구조
    • 디자인 가이드
      1. URI는 정보의 자원을 표현해야 한다.

      2. 자원에 대한 행위는 HTTP Method로 표현한다.

        HTTP METHOD

    URI 통합 자원 식별자(uniform resource identifier)로 URI에는 URL, URN 두가지 형태가 있다

    • CRUD

      Create/Read/Update/Delete

  • TDD 란 무엇이며 어떠한 장점이 있는가?

    Test-Driven Development 매우 짧은 개발 사이클의 반복에 의존

    테스트를 먼저 만들고 테스트를 통과하기 위한 것을 짜는 것. 테스트를 작성하기 위해 해당 기능의 요구사항을 분명히 이해하고 있어야 하며, 사용자 케이스 등으로 이해할 수 있다. 요구사항에 집중할 수 있도록 해준다.

    리팩토링의 속도가 빨라진다. 기존 기능의 오작동을 테스트를 돌려봄으로써 알 수 있다. 다른 사람과의 협력의 측면에서도 이득이다.

    TDD는 불확실성이 높을 때 하면 된다.

  • MVC 패턴이란 무엇인가?

    애플리케이션의 객체를 모델, 뷰, 컨트롤러의 세 가지 역할 중 하나로 할당한다.

    • Model

      앱과 관련된 데이터를 캡슐화하여, 데이터를 조작하고 처리한다.

      사용자 인터페이스나 표시 문제와 관련이 있으면 안된다

    • View

      사용자가 볼 수 있는 객체

      사용자 동작에 응답할 수 있다. 주된 목적은 모델의 데이터를 보여주고 데이터를 편집할 수 있도록 하는 것이다.

    • Controller

      뷰와 모델 객체 사이의 코디네이터 또는 중개자 역할

      뷰 객체에서 이루어진 사용자 동작을 해석하여, 변경된 데이터를 모델 객체에 전달한다.

      Cocoa Touch 프레임워크는 코디네이팅 컨트롤러, 뷰 컨트롤러 두 가지 기본 컨트롤러를 제공한다.

  • Git 과 GitHub 에 대해서

    Version Control System에 대한 기본적인 이해 필요

    • Git 전략들
      1. Git flow

        feature > develop > release > hotfix > master 5개의 브랜치가 있는 일반적으로 많이 사용하는 전략

        feature브런치는 origin에는 반영하지 않고, 개발자의 reop애만 존재하도록 한다.

      2. GitHub flow

        release 브런치가 명확하지 않은 시스템에서 사용에 맞게 되어있다.

        원격 레포에 수시로 자신이 하고 있는 일을 올린다.

        master로 머지되고 푸시되었을 때는 hubot을 이용하여 자동 배포 - 핵심

      3. GitLab flow

        Github에서 말하는 flow는 너무나도 간단하여 배포, 환경 구성, 릴리즈, 통합에 대한 이슈를 남겨둔 것이 많았다. 그것을 보안하기 위해 GitLab에서 관련 내용들을 추가적으로 덧붙여 설명한 것을 일컫는다.