오늘도 끄적끄적

느리더라도 꾸준하게

과거에는 1byte가 7bit, 9bit 등등이던 시절이 있다고 하지만 현재는 8비트로 거의 표준이 된 것 같다.
왜일까?
이 포스트는 아래 링크를 참조하여 제 머릿 속을 바탕으로 글을 썼기 때문에 틀린 점이 있다면 댓글로 적어주길 바랍니다~

컴퓨터는 미국에서 개발했다.

따라서 미국 특화(+유럽권과의 통신 등등을 고려하여 유렵권까지 특화)해서 만들었다.
따라서 아시아나 아프리카 등등에는 별로 특화돼있지 않았다. (지금은 많이 완화된 것 같지만…)
1byte의 bit 수를 결정 짓는 결정적인 요인은 아마 ASCII라는 문자 인코딩 때문일 것이다.
ASCII는 미국권 문자를 표현하는 문자 인코딩(문자의 집합)인데 통신을 위한 기호와 특수기호 + 숫자 + 알파벳 대소문자를 표현할 수 있다.
당연히 미국에서 개발했으니 미국에서 쓰이는 문자만 표현하면 되는 것이었다.
이 ASCII를 표현하는데는 7bit(128자)로 충분했고, 이 ASCII를 베이스로 byte(하나의 문자를 담는 단위)가 결정된 게 아닐까 싶다.

더 읽어보기 »

큐는 스택과 반대로 선입선출(FIFO, First In First Out)의 구조를 가지는 자료구조이다.
먼저 들어온 놈이 먼저 나가는 구조이니 입력 순서에 따른 처리를 위한 자료에서 많이 사용한다. (OS의 프로세스 스케쥴링)
스택과 비교해보면 push 대신에 offer, pop 대신에 offer를 메소드를 사용한다.

만들어보자!

기본적으로 큐를 만들어보기 전에 먼저 링크드리스트에 대해 알아야한다.
기존에 스택처럼 생각했을 때 두 가지 데이터를 들고 있어야했다.

  1. 인덱스(몇 번째에 데이터를 삽입하고 뽑아낼지)
  2. 실제 데이터 덩어리
    이 경우에는 데이터를 기존의 스택 크기보다 많이 삽입했을 때만 복사가 이루어졌다.
    하지만 큐의 경우에는 스택과 같이 두 개의 데이터만 들고 있다고 가정했을 때
    데이터를 기존의 스택 크기보다 많이 삽입했을 때만 복사가 이루어지는 건 당연하고,
    데이터를 꺼낼 때 처음 인덱스의 데이터를 꺼내야하는데 그렇게 되면 이가 빠진 것처럼 왼쪽이 비기 때문에 전부 한 칸씩 땡겨야한다.
    즉, 데이터를 삽입/삭제(추출?) 할 때 모두 큰 비용을 들이게 된다.
    따라서 큐를 구현할 때는 스택에서 출발할 게 아니라 링크드리스트에서 출발을 해야한다.
    링크드리스트의 구조 대로 구현하면 삽입/삭제가 용이하기 때문이다.
더 읽어보기 »

List는 데이터를 순차적으로 저장하므로 선형 구조(한 줄로 계속 되며, 데이터가 끊어지지 않음)이다.
또한 여기서 말하는 노드는 하나의 데이터 덩어리라고 보면 될 것 같다.

LinkedList란…?

LinkedList는 스택의 다음과 같은 단점을 극복하고자 만들어졌다.

  • 노드의 끝 부분을 제외한 곳에 데이터 삽입
    스택은 끝 부분에만 데이터를 삽입할 수 있으므로 중간에 데이터를 삽입할 방법이 존재하지 않았다.
    LinkedList는 배열의 이러한 단점을 노드(배열의 각 요소)가 다음 주소지를 알게 함으로써 그 단점을 극복하였다.
더 읽어보기 »

List는 데이터를 순차적으로 저장하므로 선형 구조(한 줄로 계속 되며, 데이터가 끊어지지 않음)이다.

스택이란…?

스택은 후입선출(LIFO, Last In First Out)의 구조를 가지는 자료구조이다.
기본적으로 배열이 스택의 구조로 이루어져있고, CPU가 연산을 할 때 연산자에 우선순위 메겨놓고 연산할 때도 스택을 이용하는 것으로 알고 있다.
그리고 프로그래밍을 배우다 보면 콜스택이라고 해서 함수의 실행 컨텍스트(EC, Execution Context)가 계속해서 쌓이는데 그 콜스택도 스택이라는 자료구조를 이용하고 있다.
몇 번째에다가 데이터를 넣어야하고, 몇 번째에서 데이터를 빼야할지에 대한 인덱스(포인터)를 가지고 있어야한다.
데이터 처리를 먼저하고 인덱스를 바꾸는 경우와 인덱스를 바꾸고 데이터를 처리하는 방식이 있다.
기본적으로 push()라는 메소드로 데이터를 넣고 pop()라는 메소드로 데이터를 뺀다.

만들어보자!

더 읽어보기 »

java.util 패키지

Random 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.Random;

class Test {
public static void main(String[] args) {
// 두 코드는 일치
double r = Math.random();
double r2 = new Random().nextDouble();

// 두 코드는 일치
double r3 = (Math.random() * 6) + 1;
double r4 = new Random().nextInt(6) + 1;
}
}

Random 클래스도 내부적으로 Math.random() 메소드를 사용하고 있다.
또 Random 클래스는 seed를 지정해 동일한 난수를 반환받을 수 있다.

더 읽어보기 »

프로그램 오류

  1. 컴파일 에러 - 컴파일 시에 발생하는 에러(오타, 타입 불일치 등등)
  2. 런타임 에러 - 실행 시에 발생되는 에러(파일을 열어야하는데 없는 파일을 인자로 넘겼을 때 등등)
  3. 논리적 에러 - 의도와 다르게 동작하는 것(돈이 음수가 된다거나 적에게 부딪혀도 죽지않는 것 등등)

오류의 두 가지 종류

  1. 에러(Error) - 발생하면 복구할 수 없는 심각한 오류(StackOverflowError, OutOfMemoryError 등등)
  2. 예외(Exception) - 발생하더라도 수습이 가능한 비교적 덜 심각한 오류(NullPointerException 등등)
더 읽어보기 »

드디어 유닛 테스트? 단위 테스트? JUnit을 써봤다~
그럼 시작!

Repository

xBatis(MyBatis, iBatis) 같은 경우에는 DAO(Data Access Object)라는 개념이 있었다는데 나중에 공부해봐야겠다.
여튼 JPA에서는 Repository가 비슷한 거라고 DAO와 비슷하다고 보면 될 거 같다.
JPA에서는 EntityManager를 구성하고, 트랜잭션을 시작하고 종료하는 코드를 만들 수도 있지만…(트랜잭션은 나중에 또 공부하자 ㅠㅠ)
JPA를 쓰기 좋게 구성한 Spring Data JPA 라이브러리를 쓰면 복잡하지 않은 Repository는 간단하게 구성이 가능하다.

Repository<T,ID> <- CrudRepository<T,ID> <- PagingAndSortingRepository<T,ID>
위는 Repository 인터페이스들의 상속 구조를 나타낸 것이다.
<>는 제네릭이고(공부하자 ㅠㅠ), T는 타입(엔티티 타입), ID는 PK를 의미한다.
CRUD(Create(insert), Read(Select), Update, Delete)는 CrudRepository로,
Paiging과 Sorting은 PagingAndSortingRepository로 해주면 된다.
페이징 로직(현재 몇 페이지인지, 데이터 몇 개씩 보여줄 건지, 페이지를 보여주는 블록에 관한 것 등등)을 안 짜도 된다니 혁명 같다 ㅠㅠ

더 읽어보기 »

자알쓰란?

바스크립트 자. (잘 쓰자는 의미도 담겨있다.)
자바스크립트라는 언어 자체는 내 기준에서는 설계 상 미스가 참 많다.
함수 단위의 스코프, 호이스팅, 동적 타입 등등
자바와 같은 깐깐(?)한 언어를 배우고 바라본 자스는 허점 투성이처럼 보였다.
애초에 자바스크립트는 어떠한 프로그램을 만들기 위해서 탄생했다기 보다는
웹 페이지에 입력값에 대한 유효성 검사(데이터가 공란인지 아닌지 등등)와 같은
페이지의 동적 제어가 주된 목적 + 짧은 개발 기간(넷 스케이프 사의 새로운 브라우저에 탑재 예정) 때문에
설계 상에 미스가 있을 수 밖에 없다고 나는 생각된다.
일종의 안전 장치가 없어서 개발자가 일일이 구현해주고, 신경써야 하는 느낌이었다.
그렇다고 해서 자바스크립트를 극혐하거나 그런 것은 아니고 매우 사랑한다.
또한 그 허점을 아는 사람은 허점을 보완해서 요리조리 피해서 잘 쓰겠지만…
잘 모르는 부분들은 잘못 써도 동작이 잘 되기 마련이다.
이는 지금 당장에는 큰 문제가 안 될지 모르겠지만, 추후에 대규모 웹 어플리케이션을 만들거나
직면할 문제로부터 미리 해방시키기 위해 처음부터 좋은 습관을 들여가는 것이 좋다고 생각한다.
그 열 두 번째 시리즈는 번외편 격으로 디버깅 하는 방법을 주제로 진행하겠다.

디버깅이란…?

우선 디버그란 De Bug, Bug를 제거하는 것이다.
그렇다면 버그란…? 우리가 생각하는 오류를 뜻한다.
그럼 왜 버그가 오류인가…?
과거에 벌레(버그)가 기계 속에 들어가서 프로그램이 오류가 난 적이 있다.
그래서 해당 벌레를 제거(디버그)했더니 프로그램이 정상적으로 실행됐다는 사례 때문에 붙여진 이름이라고 한다.
디버깅은 디버그 하는 것, 즉 버그를 제거하는 것, 오류를 고치는 행위를 말한다.

더 읽어보기 »
0%