전체 글
Java의 ArrayList에 대해 알아보고 구현하기
Java의 고정된 배열 사이즈 다른 언어에서는 배열에 데이터가 추가되면 자동으로 사이즈가 늘어나는 방식으로 설계가 되어있다. 하지만 Java에서는 배열을 선언할 때 사이즈를 입력해주어야만 한다. ArrayList에 대해서 다른 언어와 마찬가지로 Java에서도 배열의 size를 유동적으로 활용할 수 있게 해준다. 그럼에도 불구하고 ArrayList의 검색 시간은 똑같이 O(1)의 복잡도를 가진다. ArrayList은 공간이 다 차면 공간을 두배로 늘려서 검색할 때는 여전히 고정된 배열에서 검색을 진행한다. 이 때, 사이즈를 두배로 늘린 뒤 기존의 값들을 복사하는 작업을 Doubling이라고 한다. Doubling 작업의 소요 시간은 기존의 데이터를 n이라고 할 때 O(n)의 시간이 소요된다. 이러한 번거로..
Java의 StringBuilder에 대해 알아보고 구현하기
StringBuilder를 사용하지 않았을 때의 문제점 public String joinWords(String[] words) { String sentence = ""; for (String w : words) { sentence += w; } return setence; } 굉장히 단순해보이지만 상당히 무거운 작업이다. 왜냐하면 두개의 문자열을 합칠 때마다 그 크기만큼의 새로운 문자열을 생성하고, 두개의 문자열에서 한 문자씩 복사해서 붙이는 작업을 하게 되기 때문이다. 각 단어의 길이를 x라고 했을 때, x + 2x + 3x + ... + nx의 방식으로 로직이 수행된다. 따라서 O(xn²)으로 표현할 수 있다. StringBuilder 활용하기 public String joinWords(String[..
Merge Sort
기본 원리 우선 2개의 정렬된 배열이 있다고 가정해보자. 이 2개의 배열을 하나의 정렬된 배열로 만들고 싶다면, 두 배열의 첫번째 인덱스를 비교해가면서 더 작은 값을 빼내어 새로 만들 배열에 추가해주면 된다. Merge Sort는 배열을 쪼개는 과정부터 시작한다. 우선 각 배열의 길이가 2가 될 때까지 배열을 계속해서 둘로 나눈다. 다 쪼개졌으면 위에서 살펴본 방식대로 배열 안의 값들을 서로 비교하면서 작은 값을 먼저 삽입한다. 이렇게 각 배열의 길이가 2이고, 그 안에서 정렬된 배열들을 똑같은 방법으로 길이가 4이며, 그 안에서 정렬된 배열로 합쳐준다. 이런 식으로 다시 원본 배열의 전체 길이가 될 때까지 합치면서 돌아온다. 이렇듯 함수가 호출될 때마다 절반씩 잘라서 재귀적으로 함수를 호출하고, 작은 ..
Quick Sort
What is Quick Sort? 배열 안에서 기준점(pivot)을 잡고, 해당 기준점보다 작으면 왼쪽으로, 크면 오른쪽으로 옮긴다. 이 때, 기준점 양 옆으로 배열이 partition 2개로 나뉘는데, 왼쪽 따로 정렬하고 오른쪽 따로 정렬하는 작업을 재귀적으로 반복하면 완전히 정렬된 배열을 얻을 수 있게 된다. Quick Sort의 시간 복잡도 평균적으로 O(n log n)이라고 볼 수 있다. 최악의 경우 O(n²) 복잡도가 나오기는 하지만 보통의 경우에는 O(n log n)의 복잡도를 가진다고 설명한다. 그렇다면 왜 O(n log n)의 복잡도를 가진다고 보는지 그 이유를 살펴보자. 일단 partition을 나누는 횟수는 n번이다. 파티션의 데이터가 낱개가 될 때까지 나누게 되는 것이다. 그런데 한..
데이터 흐름과 비동기 작업
React 데이터 흐름 React 개발 방식의 가장 큰 특징은 페이지 단위가 아닌, 컴포넌트 단위로 시작한다는 점이다. 따라서 먼저 컴포넌트를 만들고, 다시 페이지를 만드는 상향식(bottom-up) 방법을 사용한다. 이것의 가장 큰 장점은 테스트가 쉽고 확장성이 좋다는 점이다. 이러한 컴포넌트를 활용한 설계 방식은 이전 시간에 배웠다. 이제는 데이터를 어디에 둘지 생각해야 한다. 컴포넌트는 바깥에서 props를 이용해서 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달 받을 수 있다. 데이터를 전달하는 주체는 부모 컴포넌트가 된다. 이는 데이터 흐름이 하향식(top-down)임을 뜻한다. 이 원칙은 단방향 데이터 흐름(one-way data flow)라는 키워드로 통한다...
React의 이벤트 처리
React의 이벤트 처리 방식은 DOM의 이벤트 처리 방식과 유사하다. 단, 몇 가지 문법에서의 차이가 있다. React에서 이벤트는 소문자 대신 camelCase를 사용한다. JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수를 전달한다. 이러한 차이점을 뚜렷하게 표현하자면 다음과 같다. //HTML의 이벤트 처리 방식 Event //React의 이벤트 처리 방식 Event onChange input, textarea, select와 같은 Form 엘리먼트는 사용자의 입력값을 제어하는 데 사용된다. React에서는 이러한 변경될 수 있는 입력값을 일반적으로 컴포넌트의 state로 관리하고 업데이트한다. onChange 이벤트가 발생하면 e.target.value를 통해 이벤트 객체에 담겨있는 in..
State & Props
Props props의 특징 컴포넌트의 속성(property)을 의미한다. 성별이나 이름처럼 변하지 않는 외부로부터 전달받은 값으로, 웹 애플리케이션에서 해당 컴포넌트가 가진 속성에 해당한다. 부모 컴포넌트로부터 전달받은 값이다. React 컴포넌트는 JavaScript 함수와 클래스로 props를 함수의 전달인자(argument)처럼 전달받아 이를 기반으로 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다. 따라서, 컴포넌트가 최초 렌더링될 때에 화면에 출력하고자 하는 데이터를 담은 초기값으로 사용할 수 있다. 객체 형태이다. props로 어떤 타입의 값이라도 넣어서 전달할 수 있도록 props는 객체의 형태를 가진다. 읽기 전용이다. props는 외부로부터 전달받은 후 변하지 않는 값..
SPA & Router
SPA (Single Page Application) SPA의 등장 배경 전통적인 웹 사이트는 페이지 이동 시 매번 페이지 전체를 불러와야 했다. 하지만 SPA는 업데이트가 필요한 부분만 새로 불러올 수 있다. 웹 사이트가 복잡해지고 애플리케이션의 형태를 가지게 되면서, 사용자와 서비스 사이의 상호작용 증가는 트래픽 증가와 사용자 경험의 저하를 야기했다. 따라서 1990년대 후반에, HTML 문서 전체가 아니라 업데이트에 필요한 데이터만 받아서 JavaScript가 이 데이터를 조작하여 HTML 요소를 생성하고 화면에 보여주는 방식이 개발되었다. SPA의 개념 서버로부터 완전한 새로운 페이지를 대신 갱신에 필요한 데이터만 받아서 이를 기준으로 현재 페이지를 업데이트함으로써 사용자와 소통하는 웹 애플리케이..
React 기본 개념
What is React? 프론트엔드 개발을 위한 JavaScript 오픈소스 라이브러리이다. 리액트는 선언형이고, 컴포넌트 기반이고, 다양한 곳에서 활용할 수 있다는 특징이 있다. 선언형 (Declarative) 리액트는 한 페이지를 보여주기 위해 HTML / CSS / JS 로 나눠서 적기 보다는 하나의 파일에 명시적으로 작성할 수 있게 JSX를 활용한 선언형 프로그래밍을 지향한다. 컴포넌트 기반 (Component-Based) 리액트는 하나의 기능 구현을 위해 여러 종류의 코드를 묶어둔 컴포넌트를 기반으로 개발한다. 컴포넌트로 분리하면 서로 독립적이고 재사용 가능하기 때문에, 기능 자체에 집중하여 개발할 수 있다. 범용성 (Learn Once, Write Anywhere) 리액트는 JavaScrip..