2026년 7월 27일 월요일

명상록-1

 무려 2026년. 어째서인지 이렇게 바쁜 나날을 보내고 있지만 글을 쓰고 싶다는 생각이 들었다. 과거 글들을 가만히 보고있자니 부끄럽다는 생각 보다는 재미있다는 생각이 든다. 과거의 나와 지금의 나는 과연 같은 사람일까? 최근 트레바리를 하며 다양한 책들을 접하다 보니 생각이 많아져 뭐라도 남겨야 겠다는 느낌이 들었다.

그 동안 너무 많은 일들이 있었고 나의 나이는 이제 만 35이 되었다. 회사를 때려치고 사업을 시작한지는 만으로 3년이 가까이 흘렀고, 5년을 사귄 여자친구와의 결별과, 작년 아버님의 죽음을 보았다. 어째서 이 많은 일들이 그 짧은 시기에 다 일어난지 이해할 수 없지만, 삶은 계속 흘러가고 있고 지금도 그러하다. 

요즘 시간의 흐름이 부쩍 빨라진 느낌이다. 예전과는 비교도 안될 정도로 삶은 전쟁에 가까워져 가고 있고, 매일같이 AI 기술발전을 온몸으로 이겨내며 치열한 경쟁의 소용돌이 한복판에서 살아남고자 애쓰고 있다. 과거 삼성전자를 다닐때와 비교해 보면 인생이 참 험해진게 눈에 보인다. 내가 잃은 위 3가지 것들, 안정적인 직장과 여자친구 그리고 비교적 젋었던 부모님을 지니고 있었을 때와 비교하면 분명 착잡한 마음이다.

다만 한 가지 얻은것은 있다. 삶에대한 주도성이다. 매일같이 애쓰고 이겨내며 무언가 나의 이야기를 만들어나간다는 것은 과거에는 그토록 바라 마지않던 것 이었으리라. 인간은 모든 욕구가 채워져도 자아실현의 욕구를 채울 수 없다면 결국 불행하다고 생각한다. 반대로 모든것을 잃어도 자아실현을 통해 성찰하는 인간들도 존재한다. 어쩌면 전자의 인간에서 후자의 인간으로 트랜지션을 하는 과정에서의 고통은 필연적인 것 이리라.

고통은 불쑥 찾아온다. 사실 거의 매일밤 찾아온다. 희망으로 시작했던 아침이 지나고 열정 가득했던 오후시간이 지나면 외로움과 피로감이 함께 저녁에 몰려온다. 나는 일종의 조울증에 해당한다고 생각한다. 그럴때면 사실 죽을맛이다. 친구를 찾고 술을 마시곤 하지만 그 마저도 안되면 정처없이 걷거나 길고 지루한 유튜브를 본다. 술을 아주 많이 먹고 쓰러지지 않는 이상 공허감을 이기지 못해 잘때까지 명상을 하거나 일을 죽어라 하는 등의 하루하루가 반복된다. 주 7일, 365일이 단 하루도 빠지지 않고 반복이다.

나는 두 가지 탈출구가 있다고 생각하며 살고있다. 하나는 내가 하는 일이 다른사람들에게 급격하게 관심을 받으며 크게 성장하여 삶의 구도 자체가 바뀌는 시나리오이고, 둘째는 너무나도 사랑하는 사람을 만나서 지금의 이 삶 조차 행복으로 안분지족 하는 것. 매일같이 이 두 가정을 현실로 만들기 위해 뼈빠지게 일하고 주말이면 시내를 나가 사람을 찾는다. 그렇게 산지가 천 일이 넘어가니 영 힘이 들 수 밖에. 과연 끝은 있는걸까?

최근에 몇가지 책을 읽었는데 무라카미 하루키의 직업으로서의 소설가와 마르쿠스 아우렐리우스의 명상록이다. 각자의 삶에서 끈기있게 살아가며 펼쳐낸 두 책은 사실 어떠한 이론서나 이야기 보다 와닿았다. 어떤것이 와닿았냐면, 어떤 인상적인 인간의 삶과 그를 1:1로 반영하는 정신세계에 대한 글 때문이다. 

장편 소설을 쓰는 장인으로써의 삶은 어딘가 평범하지만 매우 규칙적이고 끈질기며 프로페셔널 하다. 나는 그 반복적인 노력에 찬사를 보낸다. 하루를 열심히 살 수 있어도 40년을 매일같이 그렇게 사는것은 완전히 다른 차원의 이야기이다. 그에 비해 나는 고작 3년 이다. 

또 한명은 로마 황제로써 매우 평탄한 삶을 살았을것으로 보이지만, 알고보면 10년간의 전쟁통에서 끊없는 고난을 겪으며 스스로의 내면을 강하게 단련했던 한 철학적 인간의 일기이다. 나는 꽤나 그 컨택스트에 매료되었다. 고난을 겪었던 리더의 성찰록. 나 또한 현대의 이 격변의 시기에서 수십개의 경쟁사와 치열한 전쟁을 벌이고 있는 비즈니스 세계에서 내면의 중심을 잡기란 쉽지 않았다.

나의 삶도 어쩌면 후대에 읽힐 수 있는 어떤 스토리나 케이스가 될 수 있다는 생각에 가끔 들어와 글을 쓰려 한다. 너무 무겁게 쓰고싶지는 않고, 어떤 일들을 겪었고 어떤 상황이고 어떤 생각을 했는지. 나는 어떤 목적을 가지고 살아가고 있는지 말이다.

2021년 12월 13일 월요일

Javascript 전체내용 From MDN

Javascript 및 웹 개발에서 백과사전과도 같은 MDN을 요약 정리해놓은 문서

Ref

What is Javascript

JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.

JavaScript is a prototype-based, multi-paradigm, single-threaded, dynamic language, supporting object-oriented, imperative, and declarative (e.g. functional programming) styles.

  • Prototype-based programming: Class의 명시적 선언 없이, 인스턴스에 property와 method를 선언하여 class를 만드는 방식

Compiling and Linking

  • Compilation

    Programming Language를 Machine Language로 변환하는 과정

    <filename>.o or <filename>.obj 파일 생성: machine language file

    에러 형식: a missing semicolon, an extra parenthesis

  • Linking

    각각 떨어져 있는 machine language file 을 OS가 실행할 수 있는 하나의 Executable File로 묶는 과정

    에러 형식: missing or multiple definitions

  • Compilation phase와 Linking phase를 분리하는 이유

    파일 변경 시 매번 전체 파일을 Compilation 하는 건 비효율적임. 수정된 파일만 Compilation 혹은 Linking 하여 효율성을 높인다. IDE에서 대체적으로 잘 제공해주는 기능

  • JIT Compilation (Just-in-time)

    compilation during execution of a program (at run time)

    JIT compilation is a combination of the two traditional approaches to translation to machine code—ahead-of-time compilation (AOT), and interpretation - and combines some advantages and drawbacks of both.

    Compiled 코드는 속도가 높다 + interpretation은 유연성이 높다

    JIT compilation is a form of dynamic compilation, and allows adaptive optimization such as dynamic recompilation and microarchitecturespecific speedups.

Fundamental

  • JS를 활용하여 브라우저의 APIs를 활용할 수 있다. APIs

    • DOM API, Geolocation API, Canvas & WebGL, Audio & Video API (HTMLMediaElement & WebRTC)
  • JS의 실행환경은 브라우저의 탭이다 ← Execution environments : 각 탭은 완전히 독립 환경을 가지고 있다. ← 보안에 좋음

  • JS의 실행 순저는 Top-bottom 따라서, 순서가 중요함

  • JS는 Interpreted programming 언어 (the code is run from top to bottom and the result of running the code is immediately returned. You don't have to transform the code into a different form before the browser runs it. The code is received in its programmer-friendly text form and processed directly from that.) 이지만 대부분의 모던 JS 인터프리터는 perfomance를 높이기 위해 just-in-time compiling 테크닉을 활용한다. (JavaScript 소스 코드는 스크립트가 사용되는 동안 더 빠른 바이너리 형식으로 컴파일되어 최대한 빨리 실행할 수 있습니다. 그러나 JavaScript는 컴파일이 미리 처리되지 않고 런타임에 처리되기 때문에 여전히 Interpreted 언어로 간주됩니다.)

  • Dynamic in client-side: 실시간으로 새로운 HTML table이나 서버로 부터 오는 data를 feeded되는 것을 말한. Static과 반대

  • DOM이 Parsing 되기 전 js가 수행되는 오류를 방지하기 위해

    • Internal: document.addEventListener("DOMContentLoaded", function() {..
    • external: <script src="script.js" defer></script>
    • </body> tag 전으로 js코드를 뒤에 배치할 순 있지만, 그 동안 js가 완전히 block 되기 때문에 js의 loading/parsing 측면에서 performance issue 가 있을 수 있다.
  • async & defer

    • async - execution순서를 보장 X. 각 스크립트가 독립적일 경우 / defer - html이 모두 파싱된 이후 ⇒ DOM이나 순서에 영향을 받을 script라면 필요

Basic Syntax

  • var: Back when JavaScript was first created, this was the only way to declare variables. The design of var is confusing and error-prone. So let was created in modern versions of JavaScript, a new keyword for creating variables that works somewhat differently to var, fixing its issues in the process.
    • Hoisting: 모든 선언문을 위로 끌어올리는 행위
    • you can declare the same variable as many times as you like
  • template literal:
    • use backtick characters (```) const greeting =Hello, ${name};
    • Template literals respect the line breaks in the source code. To have the equivalent output using a normal string you'd have to include line break characters (\\n) in the string
  • basic array methods
    • indexOf, push, pop, shift, unshift, splice, filter, map, split, join ..
  • Looping method
  • Function Call
    • btn.onclick = displayMessage; ← 클릭했을 때 함수 호출
    • btn.onclick = displayMessage(); ← 선언시 바로 함수 호출
  • event: 특정 상황에 수행되는 매커니즘 ex) onClick, onLoad
    • When such a block of code is defined to run in response to an event, we say we are registering an event handler. Note: Event handlers are sometimes called event listeners - 사실 js에서 처리하는거이 아니라 브라우저 api에서 처리하는 것 or Nodejs Event Model

    • The modern mechanism for adding event handlers is the [addEventListener()](<https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener>) method. rather then Event handler properties ← bad practice

      • counter part & abort

        • btn.addEventListener('click', bgChange, { signal: controller.signal });
          • controller.abort();
        • btn.removeEventListener('click', bgChange);
      • multi register

        myElement.addEventListener('click', functionA);
        myElement.addEventListener('click', functionB);
        
    • event object

      • function bgChange(e) {e.target.style.backgroundColor = rndCol;}
      • e.target : 이벤트가 발생한 html element를 가리킨다
    • e.preventDefault(): default 이벤트 block - link

    • Bubbling and capturing

      • capturing: onclick 이벤트가 <html> 태그 부터 밖에서 안으로 전부 수행
      • target: 클릭한 해당 element의 onclick만 수행
      • bubbling: 클릭한 target element에서부터 <html> 까지 밖으로 전부 onclick 수행
      • In modern browsers, by default, all event handlers are registered for the bubbling phase.
      • e.stopPropagation();
      • Event delegation
  • arrow functions () => x is valid shorthand for () => { return x; }.

Object

  • object literal — we've literally written out the object contents as we've come to create it. This is in contrast to objects instantiated from classes

    const person = {
    	name: 'Bob',
    	age: 32,
    	greeting: function() {
    		alert('Hi! I\\'m ' + [this.name](<http://this.name/>) + '.');
    		}
    	};
    
  • dot notation === bracket notation →  person.name.first === person['name']['first']

    • bracket notation: dynamic member name → person[myDataName] = myDataValue;
  • this: he this keyword refers to the current object the code is being written inside → context change 에 대응할 수 있음

  • bult-in objects: Array, Math 등.. 그러나 built-in object가 항상 자동으로 instance 를 만드는건 아님. 예를들면, Notification의 경우 필요할때 new object를 만듬

  • constructor function: define and initialize objects and their features - normal function의 shortcut 개념. object를 선언하고 return 할 필요가 없다.

    function Person(name) { // constructor function usually start with Capital letter
    	[this.name](<http://this.name/>) = name;
    	this.greeting = function() {
    	alert('Hi! I\\'m ' + [this.name](<http://this.name/>) + '.');
    	};
    }
    
    const instance = new Person('Paul')
    
  • Object() constructor

    let person1 = new Object({
    	name: 'Chris',
    	age: 38,
    	greeting: function() {
    	alert('Hi! I\\'m ' + [this.name](<http://this.name/>) + '.');
    	}
    });
    
  • create() method: using an existing object as the prototype of the newly created object.

    let person2 = Object.create(person1);Object.getPrototypeOf(obj).
    
  • Prototype

    • Prototypes are the mechanism by which JavaScript objects inherit features from one another. JavaScript is often described as a prototype-based language
    • Prototype chain: 아래에서 부터 해당 property 가 있는지 체크하고 없으면 그 위로, 그 위로

    • access to prototype

      • proto: deprecated before ECMA2015
      • Object.getPrototypeOf(obj): new access
    • property of Object

      • Object.prototype. : inherit 시키려는 property
      • Object. : Object 자체에서만 쓸 수 있는 property
    • create() Object

      • let person2 = Object.create(person1); ← person1을 prototype으로 Object를 생성
      • person2.proto ← return person1 Object
    • constructor property

      • person1.constructor ← return Person()
      • person2.constructor ← return Person()
    • modifying prototypes: methods added to the prototype are then available on all object instances created from the constructor

      Person.prototype.farewell = function() {
      	alert(this.name.first + ' has left the building. Bye for now!');
      };
      
      • performing delete person1.__proto__.farewell or delete Person.prototype.farewell would remove the farewell() method from all Person instances.
  • Inheritance

    • call function: This function basically allows you to call a function defined somewhere else, but in the current context
    function Teacher(first, last, age, gender, interests, subject) {
    	Person.call(this, first, last, age, gender, interests);
    	this.subject = subject;
    }
    
  • using JSON: js object와 형식이 유사하나, string의 경우 큰 따옴표로 써야함. 네트워크 통신에 유리한 구조. JSON.parse , JSON.stringify 활용

    request.open('GET', requestURL);
    request.responseType = 'text'; // now we're getting a string!
    request.send();
    
    request.onload = function() {
    var superHeroesText = request.response; // get the string from the response
    var superHeroes = JSON.parse(superHeroesText); // convert it to an object
    populateHeader(superHeroes);
    showHeroes(superHeroes);
    }
    
  • Object.assign(): Object.assign() 메서드는 출처 객체들의 모든 열거 가능한 자체 속성을 복사해 대상 객체에 붙여넣습니다. 그 후 대상 객체를 반환합니다.

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
  • Object.call():call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출합니다
function Product(name, price) {
	[this.name](<http://this.name/>) = name;
	this.price = price;
}
function Food(name, price) {
	Product.call(this, name, price);
	this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// expected output: "cheese"

Async

The answer is because JavaScript, generally speaking, is single-threaded

  • Thread: Each thread can only do a single task at once

    • javascript는 main thread 하나로만 구성될 수 있음, 하지만 Web worker 등의 툴을 통해서 worker thread를 활용할 수 있음
      Main thread: Task A --> Task C
    Worker thread: Expensive task B
    
    • 하지만 web worker는 두가지 문제점이 존재
      • DOM에 직접 접근할 수 없음
      • 언제 끝나는지 정확한 시점을 알 수 없음
  • There are two main types of asynchronous code style you'll come across in JavaScript code, old-style callbacks and newer promise-style code

    • Async callback: call back function을 argument로 넘겨주는 것
    • Promises: Promises are the new style of async code that you'll see used in modern Web APIs
        • chain으로 연결 가능, 순서 보장, 에러 핸들링
  • event queue: async operation이 호출되면 곧바로 event queue로 넘어가서 main thread가 끝난 후에 실행되어, 결과를 js에 다시 넘겨준다

  • Promise

    let timeoutPromise = new Promise((resolve, reject) => {
    	setTimeout(() => {
    		resolve('Success!');
    	}, 2000);
    });
    
  • Async: Invoking the async function now returns a promise

    • let hello = async function() { return "Hello" };
  • Await: await only works inside async functions

    • await can be put in front of any async promise-based function to pause your code on that line until the promise fulfills, then return the resulting value.
    • error handling: You can use a synchronous [try...catch](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch>) structure with async/await

중급

고급

프로토타입 메소드 상속

  • prototype chain: 속성이나 메소드를 해당 instance에서 못찾으면 prototype에서 찾고 없으면 다시 그 prototype에서 찾는다.window.Object.prototype까지 찾았는데도 없다면 undefined를 출력
var o = {
  a: 2,
  m: function(b){
    return this.a + 1;
  }
};

console.log(o.m()); // 3
// o.m을 호출하면 'this' 는 o를 가리킨다.

var p = Object.create(o);
// p 는 프로토타입을 o로 가지는 오브젝트이다.

p.a = 12; // p 에 'a'라는 새로운 속성을 만들었다.
console.log(p.m()); // 13
// p.m이 호출 될 때 'this' 는 'p'를 가리킨다.

객체 생성 방법

var o = {a: 1};
// o 객체는 프로토타입으로 Object.prototype 을 가진다.
// 이로 인해 o.hasOwnProperty('a') 같은 코드를 사용할 수 있다.
// hasOwnProperty 라는 속성은 Object.prototype 의 속성이다.
// Object.prototype 의 프로토타입은 null 이다.
// o ---> Object.prototype ---> null
var a = ["yo", "whadup", "?"];
// Array.prototype을 상속받은 배열도 마찬가지다.
// (이번에는 indexOf, forEach 등의 메소드를 가진다)
// 프로토타입 체인은 다음과 같다.
// a ---> Array.prototype ---> Object.prototype ---> null
function f(){
	return 2;
}
// 함수는 Function.prototype 을 상속받는다.
// (이 프로토타입은 call, bind 같은 메소드를 가진다)
// f ---> Function.prototype ---> Object.prototype ---> null
var b = Object.create(a); // only for ECMAScript 2015
// b ---> a ---> Object.prototype ---> null

Class 키워드 - only for ECMAScript 2015

'use strict';

class Polygon {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

class Square extends Polygon {
  constructor(sideLength) {
    super(sideLength, sideLength);
  }
  get area() {
    return this.height * this.width;
  }
  set sideLength(newLength) {
    this.height = newLength;
    this.width = newLength;
  }
}

var square = new Square(2);
// square ---> Square ----> Polygon ----> Object.prototype ---> null

프로토타입 상속의 종류

  • 위임형 상속: 메소드를 위임 상속할 경우 모든 객체가 각 메소드에에 대해 하나의 코드를 공유하므로 메모리를 절약할 수 있다. 일반적 상속
class Greeter {
	constructor (name) {
	[this.name](<http://this.name/>) = name || 'John Doe';
}
hello () {
	return Hello, my name is ${ this.name };
}
const george = new Greeter('George');
const msg = george.hello();
console.log(msg); // Hello, my name is George
  • 연결형 상속: 연결형 상속은 한 객체의 속성을 다른 객체에 모두 복사함으로써 상속을 구현하는 방법이다.이 상속법은 Javascript 객체의 동적 확장성을 이용한 방법이다. 객체 복사는 속성의 초기값을 저장하기 위한 좋은 방법이다.
const proto = {
	hello: function hello() {
		return Hello, my name is ${ this.name };
	}
};
const george = Object.assign({}, proto, {name: 'George'});
const msg = george.hello();
console.log(msg); // Hello, my name is George

엄격모드 'use strict'

엄격 모드는 평범한 JavaScript 시멘틱스에 몇가지 변경이 일어나게 합니다.

  1. 기존에는 조용히 무시되던 에러들을 throwing합니다.
  2. JavaScript 엔진의 최적화 작업을 어렵게 만드는 실수들을 바로잡습니다. 가끔씩 엄격 모드의 코드는 비-엄격 모드의 동일한 코드보다 더 빨리 작동하도록 만들어집니다.
  3. 엄격 모드는 ECMAScript의 차기 버전들에서 정의 될 문법을 금지합니다.

Typed Array

빠르고 쉽게 형식화 배열의 원시 이진 데이터를 조작할 수 있게 하는 것

메모리 관리

Concurrency model & Event Loop

  • Stack: 함수 호출 코드실행 스택
function foo(b) {
	var a = 10;
	return a + b + 11;
}
function bar(x) {
	var y = 3;
	return foo(x * y);
}
console.log(bar(7)); //returns 42
  • Heap: 객체들이 저장되는 영역. 구조화되지 않은 넓은 영역
  • Queue: JavaScript 런타임은 처리 할 메시지 목록 인 메시지 대기열을 사용합니다. 각 메시지에는 메시지를 처리하기 위해 호출되는 관련 함수가 있습니다. 런타임은 대기열에서 가장 오래된 메시지부터 처리하기 시작합니다. 그렇게하기 위해, 메시지는 큐에서 제거되고 해당 기능이 메시지를 입력 매개 변수로 호출됩니다. 언제나 그렇듯이, 함수를 호출하면 그 함수의 사용을위한 새로운 스택 프레임이 생성됩니다.
  • Event Loop: 웹 브라우저에서 이벤트 리스너가 부착된 이벤트가 발생할 때마다 메시지가 추가됩니다. 리스너가 없으면 이벤트는 손실됩니다. 클릭 이벤트 핸들러가 있는 요소를 클릭하면 다른 이벤트와 마찬가지로 메시지가 추가됩니다.
while(queue.waitForMessage()){
	queue.processNextMessage();
}

2021년 11월 25일 목요일

재림 # 1

인생의 가장 큰 수수깨끼는 자신이 가진 프레임으로 세상을 바라볼 때 불현듯 찾아온다.

기적은 마치 유성처럼 부지불식간에 우리 옆을 아무 일 없다는 듯 비켜지나갈때도 있지만

그 반대의 경우를 생각할 수 없을 만큼 인간의 삶은 너무나도 짧고 허망할 뿐이다.


"두.. 두줄. 어째서..?"

지원은 두 눈을 의심했다. 하늘이 무너지는 기분을 느끼며 차가운 바닥에 쓰러졌다. 

"이럴 수 없어.. 이럴 수 .."

꽃다운 나이 스무살, 연애경험도 없는 지원에게 동정임신이란 형언할 수 없는 끔직한 기적이었다.


"그래. 예수가 어떤 존재였을지 한번 상상해보세요."

나이가 지긋해 보이는 흰 머리의 교수는 교단을 이리저리 돌아다니며 졸고있는 학생들 앞에서 혼잣말 처럼 중얼거리는 듯 강의를 이어나갔다.

"예수라는 한 사람은 말이죠, 사실은 그렇게 처음부터 밝은사람이 아니었을지도 몰라요"

"싱글맘의 품에서 자라며 온갖 굳은일을 하며 자라났죠. 어찌보면 약간의 애정결핍과 세상에 대한 분노 또한 마음속에 있었을지도 모릅니다."

고산대 신학대학 교수 곽철호는 그렇게 혼잣말 같은 강의를 마치고 너저분한 랩실로 돌아왔다.  랩실에는 젊어보이지만 어딘지 모르게 추레한 이미지의 대학원생 경표가 맨 바닥에 늘어지듯 누워있었다.

"얌마 경표야! 그렇게 맨바닥에 누워있지 말라고 해도!"

"어엇..! 교수님 일찍오셨네요"

경표는 슬그머니 상체를 일으켰지만 아직 엉덩이는 바닥에 대고 다시 늘어지게 하품했다.

"그 지난번에 말씀하신 자료들은 일단 몇개 찾아서 웹하드에 저장해두었는데요. 이게 뭐 워낙 드문 케이스다 보니 사실 자료 찾기가 쉽지 않네요."

교수는 혀를 끌끌 차며 의자에 털썩 앉았다.

"그래 뭐. 그렇게 드문 일이니 사람들이 기적 기적 하는거지.. 자주 일어났으면 기적이라고 하겠어? 일단 지난번 자료도 한번씩 다시 스크랩 해서 정리좀 하자."

교수는 무심히 웹하드를 뒤져보며 파일을 하나씩 열어본다.

경표는 간신히 바닥에서 일어나며 혼잣말을 했다.

"에휴.. 말이 안되는 일이니까.."


2024년 10월 6일 서울 밤10시. 초등학교 고학년 쯤 되보이는 학생이 검은 후드를 눌러쓴 채 다 쓰러져가는 빌라의 공동 쓰레기통을 비우고 있다.

"후우 .. 하아"

각종 더러운 쓰레기들. 비닐과 비닐 안에 쌓여있는 음식물 쓰레기들을 다 튿어진 장갑으로 하나씩 가져온 쓰레기통에 담는다. 

"에이 씨발! 정말 못해먹겠네"

어린아이의 입에서 나왔다고 하긴 어려울 찰진 발성의 육두문자가 허공을 갈랐다.

삑-삑-삑

공동 현관 문을 열며 누군가 걸쭉하게 취해서 들어온다. 남자가 비틀비틀 대며 학생에게 불안하게 다가갔다.

"이새끼 너 .. 누구야?"

취한 남자는 초면에 반말을 시전하며 아이의 후드티를 뒤집어 깠다. 

어린아이의 얼굴 이라고는 믿기 힘들정도로 세상의 풍파를 다 맞은 듯한 표정과 눈 밑에 자그마한 상처. 액면가는 중학생은 되어보이지만 영양 부족 탓인지 골격과 키는 아직 초등학생 수준에 머물러 있는듯한 체구. 

16살 진호는 화들짝 놀라며 다시 후드를 뒤집어 썼다.

"아니.. 저 그냥 청소하러.."

"이새끼가 말 똑바로 안해?"

착!

다짜고자 진호의 뺨을 때리는 취한남성

털썩

진호는 성인 남성의 힘을 버티지 못하고 다리에 힘이 풀려 주저앉았다.

"후.. 씨발"

주저앉은 채로 주머니에서 뭔가를 꺼내는 진호.

진호는 다시 일어서며 작은 주머니칼을 꺼내 남자앞에 들이밀었다.

"이 씨발새끼야. 내가 쓰레기 치우러 왔지 뺨맞으려고 온줄알아?"

남자는 슬슬 뒷걸음질 치더니 계단위로 휙 올라가버렸다.

"하아.. 저 개같은"

한참을 그렇게 덩그러니 떨리는 손으로 주머니칼을 쥔채 서 있었다. 옆은 눈물이 앞을 가렸지만 진호는 분노를 꾸역꾸역 누르며 하던일을 마저 해나갔다.

2021년 1월 10일 일요일

프론트경험 없는 개발자가, React Native로 앱 만든 후기

대기업 프로그래머 6년차. 하지만 앱개발 및 프론트앤드 경험은 거의 없음.

참고로 안드로이드 IOS 개발경험은 전무하였고, 실제 업무는 데이터 처리 및 클라우드쪽.


사실 프론트앤드 개발하면서 가장 어려웠던 부분은, Javascript 진영을(landscape) 이해하는 것 이었다.

볼륨이 워낙 커서 어떤 순서로 어떻게 이해해야 할지 상당히 난감했던 기억이 있었다.

 * 추천드리는 순서: ES3~ES7까지의 히스토리와 문법 이해 -> Javascript 내부구조(이벤트루프, 비동기) + Nodejs이해 -> BOM, DOM 조작 관련 커멘드 -> Webpack 들 모듈러에 대한 이해


사실 안드로이드나 IOS 도메인의 내부 구조에 대해서는 잘 몰랐고 지금도 잘 모른다. 이미 RN이 상당한 수준으로 감싸고 있기 때문에 많은경우 신경 쓸 필요가 없다. (과거에는 manual install 이나 linking 등등 떄문에 android를 너무 모르면 개발하기 쉽지 않았다.)

ReactJS 와 React Native는 웹과 앱이라는 도메인이 다르지만 구조적 개념은 비슷하다. 따라서 둘 중 하나만 배우면 둘다(웹과 앱) 잘할 수 있다.

--

React Native를 사용하며 느꼈던 점

1. UI 조작이 직관적이다: DOM 을 직접 조작하는건 매우 고통스러운 일이며, 직관적이지 않다. React는 각 UI 요소를 전부 컴포넌트로 관리하여 살제로 우리에게 보이는 UI묶음이 하나의 객체처럼 여겨진다. 즉, UI와 실제 코드의 괴리감이 적은편


2. 맨바닥부터 시작하지 말라: 물론 React Native 도 미리 제공하는 예쁜 컴포넌트들을 다수 가지고있지만,  그런 기본 컴포넌트보다 디자인이 들어간 컴포넌트를 원할것이다. 필자는 Kitten UI 를 사용하였고, 일종의 Wrapper로써, 꽤나 전문적이어 보이는 디자인을 활용할 수 있었다.


3. 찾아보면 다 있다: 내가 필요한 기능을 집어넣고 싶을때 가장 먼저 해야할것은 구글링. 리액트 네이티브의 써드파티들은 생각보다 엄청나게 일을 열심히한다. 예를들면 카메라 조작이 필요하다면 검색을 잘 해서 가장 최근까지 활발히 개발되어있는 컴포넌트를 사용하면 된다. 


4. 설치하면서 자주 막힌다: 이게 특히나 안드로이드쪽 번들링할때 문제가 많이 발생하는데 왠만하면 gradle 떄문인 경우가 많다. 설치가 좀 꼬였을 경우 왕왕 cd ./android & ./gradlew clean 으로 해결되는 경우가 꽤 많다. 그 외에도 자잘하게 이슈들이 계속 발생한하는데 무었이 문제인지 알기 어려운 부분이 너무 많다. 이떄는 그냥 'what went wrong' 부분을 카피해서 구글링하면 대체로 해결법을 찾을 수 있다. 


5. 될수있으면 서버리스로: firebase를 일정부분 무료로 사용할 수 있기때문에, 구태여 백엔드를 만들지 않아도 서버리스로 쉽게 무료로 앱을 만들 수 있다. 또한 Invertes라는 회사가 firebase에 대해 react native 에서 조작할 수 있도록 패키지를 만들었고 문서도 상당히 잘 되어있기 때문에 활용도가 높다.


6. 상태에 대한 이해가 필수: 다음과 같은 키워드에 대해 잘 이해해야 한다. Redux, Hook, useEffect, useStatue, Subecribe. 리액트는 무조건 상태값 조정으로 모든 동작이 이루어진다. 리액트의 정적구조는 JSX 가 책임지고 동적구조는 function 과 status가 책임진다. 처음 앱을 설계할 때 이 상태값을 어떻게 관리하고 조작할 것인지 미리 생각해두는게 스파게티코드를 막는 매우 중요한 부분이다.


7. 성능에 대해서 신경써야한다: 컴포넌트 상태가 자주 바뀌고 그에따라 자주 랜더링될수록 사용자는 버벅거림을 느낄 수 있다. 개발할 떄 항상 이점을 염두해두고 같은 동작이라면 최대한 랜더링이 자주 되지 않는 방향으로 설계해야한다.


8. IOS 개발하려면 어쨌든 맥이 필수: 아무리 하이브리드용 언어라지만 Xcode와 에뮬레이터가 있어야 앱을 번들링해서 앱스토어에 등록할 수 있다. 또한 실물 아이폰이 없으면 아무리 에뮬레이터에서 잘 돌아가도 실제 기기에서의 동작을 보장할 수 없다. 개발 자체도 맥에서 하는게 더 편한 이유는, 리액트네이티브 코드가 안드로이드 에뮬레이터에서 썩 좋은 성능올 돌아가지 않는다.


--


결과물 : 여기저기 다니면서 맛집이나 카페 등등 기록하려고 만든 앱입니다. 친구들끼리 팔로잉 할수도 있고. 이웃들끼리 소통할 수 있는 플랫폼 입니다.


온더랜드 - 지역기반 SNS

Android: https://play.google.com/store/apps/details?id=com.duddlsdbql.ontheland

Ios: https://apps.apple.com/us/app/id1518369229#

원문: https://www.clien.net/service/board/lecture/15783611

2020년 11월 10일 화요일

경력직 컴퓨터공학 지식

웹 개발 (프론트/백) 경력직 프로그래머 면접에 도움이 될 만한 내용으로 Index 형식 구성중. 

내가 무얼 모르는지 아는게 중요하다. 

신입 프로그래머 컴퓨터공학 지식: https://softwarepatrasche.blogspot.com/2016/04/blog-post.html?showComment=1606787920137#c9214959261385290037


작은 돌

작은 돌 표면에 아주 미세하게 껌딱지처럼 붙어서 평생을 사는 미생물들이 있다. 그들에겐 아주 작은 습기와 햇빛만 비춰주면 돌을 다 덮을 것 처럼 증식했다가 자기들끼리 싸우고 죽이며 다시 개체수가 줄어든다. 이 작은 돌에는 다른 미생물들도 많이 사는데 이 개체는 자신들이 이 돌의 주인인양 다른 개체들을 사정없이 먹어치운다. 빛이 없는곳엔 작은 반디불이가 무리짓는다. 본성이 잔인한 존재이지만 아름다움을 추구하는듯 돌은 반짝이게 한다.

어느 날 아주 작은 모래알갱이가 이 돌에 부딧쳤다. 돌에 비해 아주 작았지만 속도가 빨라서 많은 파편이 튀었다. 돌은 움푹 패이고 갈라졌다. 돌에살던 미생물들은 대략 3할정도 남았다. 서로 잡아먹던 이들이지만 멸종의 위기에선 어떻게든 살아보려 갈라진 곳의 반대편으로 모인다. 습기와 햇빛을 주지만 더이상 증식하지 않는다. 돌을 전부 뒤엎을 것 같던 이 개체들의 자신감도 풀이 꺽인듯 주변 미생물들과 그저 어울어진다.

2019년 9월 11일 수요일

어느 밤

추석 연휴. 밤이 너무 깊지 않은 통에 도통 잠이 들지 않았다. 친구들에게 연락해 볼까 했지만 이내 관두었다. 애매한 거리감의 여사친에게 보낸 메시지에 결국 삭제 버튼을 누르었다. 밖에 나가볼까 했지만 술을 한잔 마신 덕에 차를 끌고 나가 긴 글렀고 버스를 타자니 택시로 돌아올 것 같았다. 중심가에서 꽤나 떨어진 외진 위치의 평범한 아파트에 자리 잡은 부모님의 거처는 야경이 정말로 아름다웠다. 수평선 끝에서 끝까지 출처모를 빛무리들이 매일 밤 반짝였다. 야경에 사로잡힌 아버님은 단박에 구매를 결정하였고 덕분에 생각지 못한 심각한 층간소음에 골머리를 앓았다. 



"띠링" 울리는 전화. 삭제한 메시지에 무심한 질문이 돌아온다. 잠시 고민 후 집을 나선다. 어차피 이렇게 보내기엔 너무 아까운 시간이다. 가을장마가 끝난 직후라 그런지 밤바람은 스산했다. 한적한 버스에 몸을 실어 가만히 기대어간다. 요즘 들어 자주 기댄다. 기댈 곳 없는 세상에 홀로 우뚝 서 있노라면 썩은 나무처럼 밑동이 부서져 어디로든 나뒹굴 것 같았다. "어디야?" 집 앞까지 찾아가도 하염없이 늦는 그녀는 미안한 기색 없이 항상 쾌활하다. "가던 데로 가자" 잠시 고민하는 척했지만 행선지는 몇 년째 변하지 않았다. 뜨거운 국물에 소주 한잔 할 수 있는 곳. 갖은 걱정들과 욕망들이 어깨 위에서 머리 위에서 살그머니 내려온다. 



"요즘 뭐하고 지내길래 소식이 없냐" "코타키나발루 다녀왔어" "남자 친구랑?" "아니~ 가족이랑 다녀왔지" "너는 어떻게 매주 여행을 가니. 돈도 많이 못 벌면서. 누가 보면 재벌인 줄 알겠어~" "인생 즐기는 거지 뭐 있니. 그리고 나 그렇게 많이 안가~" "너 지난번에도 어디 다녀왔잖아" "언제?" "지난주엔가? 인스타에 사진 올렸던데". 한잔. 두 잔. "사는 게 지겹고 의미가 없는 것 같아" "넌 항상 그래. 뭔가 새로운 일을 시작해봐" "난 나를 위해 일을 하고 싶어. 뭔가 인생의 주인공이 내가 아닌 것 같아" "넌 사업을 해야 하는 것 같아. 그래야 좀 행복할 것 같아" "음. 글쎄 꼭 사업이라기 보단 뭔가 주도적인 일을 해야 행복을 느낄 것 같아" "돈 많이 벌면 나 잊지 말구~" "그래. 너 아들 낳으면 내가 꼭 챙길게"



특별한 일이 없기에, 특별한 얘기는 나누지 않았다. 그저 뿌리 깊이 자리 잡은 외로움을 조금 덜어내어 술잔에 섞어본다. 스무 살 때부터 부모와 떨어져 지낸 지 9년. 길지 않은 시간이었지만 여전히 멀리 떨어져 있으면 왠지 모를 불안감이 나를 다시 이따금씩 고향으로 이끈다. 천성이 새로운 환경에 적응을 못하는 기질이라 유치원 저학년 때에는 일 년 내내 계단에 앉아 홀로 지냈다. 그런 꼬맹이가 스스로의 텃밭을 일구기 위해 꽤나 오래도록 나와있었지만, 자연스레 생긴 향수병을 관계로써 해소하기보단 혼자라는 것을 받아들이는 방향으로 자라게 되었다. 관계에 대한 기대감이 실망으로 변하면서 방어태세에 본격적으로 돌입한다. 말수는 더욱 줄고 생각은 더 많아졌다.



새벽 1시가 넘은 시간. 쉼터였던 술집은 근처에 위치한 성인나이트의 2차 전쟁터로 변했다. 40대가 넘어 보이는 아저씨와 아줌마들이 나름의 멋으로 한껏 꾸미고 치근덕거리고 교태를 부린다. "저것 봐 저것 봐. 엄청 늙어 보이는 남자가 저 여자한테 말 걸고 있잖아" 그녀는 인상을 찌푸리면서도 호기심에 눈이 반짝인다. 심각한 인지부조화의 장이 등 뒤에서 시작되기에 그녀가 가리키는 방향으로 고개를 돌리지 않는다. 결혼과 사랑은 나에게 아직 불가침의 영역이지만 이들을 달리 어떻게 설명할 수 있을까. 난 그들과 다르고 또 부모님은 다를까. 



"잘 가" 총총 멀어져 가는 뒷모습을 본다. 외로움은 또다시 사냥감을 발견한 맹수들처럼 나를 에워싸고 천천히 기다린다. 취기가 가시고 정신이 멀쩡해지면 득달같이 달려들어 내 뒷목, 어깨, 허벅지, 발꿈치, 무릎, 팔꿈치를 문다. 그리고 그들은 천천히 나를 움직인다. 말과 행동을 일반인들보다 느려지고 눈에는 생기가 사라진다. '그으으으' 입에서는 맹수의 그것과 비슷한 소리가 흘러나온다. 한 걸음씩 발을 뗼 때마다 썩은 내가 진동한다. 추한 모습을 보이기 싫어 사람이 적은 곳으로 자연스럽게 걸음을 옮긴다. "깔깔깔" "그랬고 그랬잖아" "진짜?" 왁자지껄 나누는 이야기들에 더욱더 몸을 피한다. 더욱더 숨어 들어간다. 깊을 굴 속으로 기어들어간다. 지렁이처럼 몸을 움직여 간신히 남은 틈을 메운다. 그러곤 눈을 감는다.

2019년 8월 29일 목요일

외제차를 샀다

외제차를 샀다. 에스토리칼 블루의 17년식 BMW는 5월의 햇살을 받으며 따사롭게 반짝였다. 살만해서 산 외제차는 아니었다. 하루 8시간 노동에 자유를 박탈당한 나의 꿈과, 결국 이뤄지지 못한 사랑이 나를 현실에 발 디딜 곳 없게 만들었다. 결국 이놈도 다른 놈들과 마찬가지로 많은 시간을 들여 갚아나가야 할 짐이 될 테지.



들뜬 마음은 4개월 만에 다시 수면 깊이 가라앉았다. 현실로 돌아오는 데에 걸리는 시간은 내어 바친 돈만큼, 딱 그 정도만 유효했다. 노동은 계속되었다. 대기업 프로그래머로 일한 지 만 3년. 입사 전 그토록 좋아 보였고 다다를 수 없어 보였던 이 직함은 이젠 지긋지긋하게 싫고 역겨워졌다. 앞으로 30년 동안 노동과 젊음의 등가교환은 계속될 것이고 늙고 병들은 몸을 이끌고 이 닭장을 벗어나 대략 30평대 수도권 아파트와 대학 졸업한 아들과 딸이 덜렁 생길 테고, 틈만 나면 부동산 얘기, 돈 얘기, 자식 얘기하는 늙은 와이프가 곁에 남겠지. 평범하고 얼핏 보면 부유해 보이는 삶이지만 그 무언가 중요한 것이 빠져 보였다.



돌아보면 삶이라는 건 늘 밀물과 썰물의 반복이었다. 밀어닥칠 땐 정신없이 그 위치 그 자리라도 지켜보려고 발버둥 쳐 보지만, 빠져나갈 땐 영혼이라도 같이 용해되어 나간 듯 끝없는 공허함이 수면 아래 있던 백사장처럼 고개를 내민다. 그럴 때면 가끔 극단적인 생각도 한다. 이대로 끝이면 어떨까. 이 모든 경쟁, 욕망, 거짓말, 노력, 실패, 인간관계, 집착, 희열 그리고 두통이 거대한 피로감이 되어 코끼리의 발처럼 가슴을 짓무른다.



친구가 빌려준 이상 문학상 전집에 이런 재미난 표현을 쓴 글이 문득 기억났다. 작가의 심장 위에는 항상 코끼리의 발이 올려져 있다. 친구를 만날 때나 산책을 할 때나 잠을 잘 때, 불현듯 코끼리는 잠시 고민 후 발에 힘을 준다. 작가는 말할 수 없는 고통을 느끼고 잠을 설치고 길에서 가슴을 부여잡고 고통스러워한다. 고통의 크기는 작은 당구공이었다가 거대한 지구가 되지만, 가장 가까운 친구들도 알 길이 없다.



나에게 고통은 자유의 박탈이고 용기의 부족, 의지의 결여이다. 나로 태어나 나로 죽을 수밖에 없는 운명에 대한 비통함이다. 현실의 지루함이고 예상되는 모든 시나리오가 5지 선다형이었음을 깨달은 순간이다. 이치에 도통 맞지 않는 세상이며, 그 속에서 정답을 찾으려 하는 사람들이 만들어낸 복잡한 핼러윈이다. 버릴 수 없는 몸의 욕망과 속 깊은 부도덕함과 거짓말들이다. 그럼에도 쓰레기 같은 욕망을 애써 감추려는 시도이며 멀쩡한 척 살아가는 내 사지이다.



에스토리칼 블루의 17년식 BMW는 4개월이 지나도 여전히 잘 나가지만 왠지 모르게 뒷자리에 덜그럭거리는 잡소리가 가끔 나기 시작했다. 애써 외면하지만 고요한 밤 심하게 덜컹이는 지면을 지날 때면 어김없이 내 귀를 간지럽힌다. 울화통이 터지 지기보단 잘 못 들은 걸로 치고 넘어간다. 매번 그렇게 넘어간다.

2019년 8월 18일 일요일

들판


어렸을 땐 고독과 슬픔에 대한 남모를 호기심이 있었다. 나이가 들며 불현듯 생각만 해도 가슴이 얼얼한 그런 기억들이 이따금씩 찾아왔고 힘차게 앞으로 나아갔던 하루하루를 다시 무의 공간으로 만들어버렸다. 아무것도 없는 공간에서 앞으로 계속 나아가도 결국 다시 무의 공간으로 돌아온다. 그저 발에 닿는 감촉만으로 내가 앞으로 가고있다고 인지 할 뿐, 스쳐가는 바람 한점 느껴지지 않는 이 곳에서 그저 묵묵히 고통을 견디어 낸다. 인간은 나약하고 어리석기 때문에 고통은 필연적이다. 어째서 이렇게 불완전한 존재로 만드셨나요. 누군가 그랬다. 즐겁게 살지 않는 것은 죄다. 맞다. 따라서 즐겁게 살기 위해, 고통을 줄이기 위해 또다른 고통을 견디며 산다. 고통 끝에 잠시 행복이 찾아왔지만, 그 행복은 더 큰 고통을 남기고 떠나간다. 행복이 떠난 자리에서 벗어나기 위해 앞으로 나아간다. 한치 앞도 보이지 않는 너른 광야에서 벗어나기란 불가능해보이는 듯 하다. 바로 여기서 실존에 대한 고민이 시작된다. 우린 누구이며 대체 무엇때문에 이런 즐거움과 고통을 느끼며 살아가야 하는가. 목적론에 입각한 이러한 생각은 결론에 도달 할 수 없다는 것을 잘 알고있다. 하지만 여전히 인간은 어리석고 나약하기 때문에 지혜롭고 강인한 것, 바로 목적과 타당성에 손쉽게 이끌린다. 또 그것에 유혹당한다. 결국 아무것도 얻지 못한 채 인생의 결론에 다다른다. 수조의 인간들은 무상하다는 말만 남기고 사라져갔다. 그것을 잘 아는 어리석고 나약한 인간은 다시 글을 쓴다. 현실의 고통과 그것의 타당성을 찾기 위해. 스스로 정리하기 위해. 결국 글은 아무것도 이뤄 주지도 알려주지도 않았다. 한 줄로 주욱 늘여 쓴 글은 행복이 떠나간 너른 광야를 벗어나려는 어리석은 자의 발자국과 같다. 결국 고통은 현실을 있는 그대로 직시하기 위해 사용되었다. 어렸을 적 느끼지 못했던 실존의 고민은 그녀가 떠나간 자리를 실마리 삼아 모락모락 피어 올랐다. 깊어지는 내면에는 썩은 물이 고이기 시작했다. 한동안 그 냄새가 역겨웠지만 조금씩 익숙해져 갔다.

2019년 1월 20일 일요일

자유의지


잠이 오지 않는 밤이다.


서른을 목전에 두고 시간은 쏜살같이 흘러간다. 잘 살고 있는건지, 나는 과연 괜찮은 건지 물어볼 새도 없이 그저 그렇게 흘러간다. 가만히 있으면 괜스레 괴로워서 일부러 더 쉴틈없이 주변을 만든다. 매 순간 욕망에 충실하게 그렇게 허망한 시간을 견디어 낸다. 자아가 생기고부터 알 수 없는 삶의 이유라는 것 때문에 결국 다시 또 밑바닥까지 내려앉는다.


가끔 삶의 이유가 있었던 적이 있었다. 성공 혹은 사랑. 조금 더 지나면 아이와 건강을 걱정하겠지. 수 만년 전 부터 우리의 DNA에 적혀 있는 무언가를 추구하기 위해 하루하루 살아왔다. 단 하루도 그 룰에 벗어난 적 없이 여태 살아왔다. 내게 대체 무엇이 결핍되었길래 이런 삶에 끊임없이 의문을 품는 걸까. 몸은 그저 생물적 안위를 위해 끊도없이 움직이는데 마음은 그것에 대한 벗어남을 갈망한다. 이런 모순 또한 인간종이 가지는 특징인가?


주변인들은 그런 의문을 많이들 품지 않아 보인다. 그저 생물의 본성이 시키는 대로 움직이고 생각하는 듯 보인다. 그래서 다들 목적이 아주 명확해 보인다. 그들에게 의문을 품는건 사치이고 쓸데없는 일이다. 그들의 의문은 결국 바운더리를 벗어나지 않는다.


내가 사색형 인간임을 처음 깨달은 것은 중학교때이다. 전교 성격검사때 밝혀졌는데 아주 드물게 나타나는 성격 유형인지 선생님은 이런 유형을 처음 봤다고 한다. 유형의 이름과 걸맞게 생각을 참 많이 하는 편이다. 아주 여러가지 생각을 하고 나름대로의 가설도 혼자 세우는 편이다. 그 중 하나는 자유의지에 관한 가설인데, 자유의지는 말 그대로 어떤 타율에 의하지 않은 스스로 발현되는 의지이다. 근데 이 타율이라는 게 참 애매한데, 학계에서는 이것을 앞서말한 생물학적 안위로 본다. 무슨 말이나 하면 우리가 추구하는 성공, 이성관계, 안전, 권력 등의 모든 욕망은 결국 타율이다. 내가 선택한 것이 아니라는 얘기다. 그럼 과연 내가 선택한 건 뭘까.


뇌의 시작은 파충류의 뇌로부터 시작한다. 파충류의 뇌를 보면 아주 얇고 작은데, 그 역학은 특별한 것 없이 생명 유지이다. 숨쉬는 것부터 시작해서 체온 유지 등 생명을 유지하는데에 아주 기본적인 역할만을 담당한다. 생물은 수십만년간 진화하면서 그 뇌에 기능들을 추가하기 시작했다. 진화는 그런 식으로 이루어진다. 기능은 이전 기능을 Base로 그저 추가된다. 그 예로는 눈의 기능을 볼 수 있다. 우리의 눈은 물속에서 진화하여 육지로 올라왔지만 그 때문에 정말 많은 비효율을 가지고 있다. 마찬가지로 뇌도 그런 식으로 진화해 왔기 때문에 수많은 모순적 결함을 가지고 있다. 인간 종이 호모 사피엔스의 시대로 들어서면서 대뇌가 급격하게 성장했다. 대뇌는 추상적인 생각을 하는 기능을 한다. 우리가 종교, 회사, 화폐와 같이 거짓인 것을 그토록 잘 믿을 수 있는 이유중 하나이다. 이러한 능력 때문에 우리는 대규모 협력이 가능해지며 결국 지구의 주인이 되었다.


이제부터는 내 가설인데, 문제는 결국 여기에 있다. 우리가 사피엔스 시대로 접어들며 뇌를 전부 재설계했다면 현재의 자가당착적인 인간의 모습은 없을 것이다. 하지만 어디까지나 인간 뇌의 Base는 파충류의 뇌이다. 그렇기 때문에 모든 추상적인 생각들의 Base는 결국 생존의 문제에서부터 시작될 수밖에 없다. 이게 문제가 되는가? 앞서 말했듯이 모순이 생긴다. 대뇌의 기능은 생존이라는 Base를 벗어나려 함으로써 오히려 생존력을 극대화했다. 하지만 결국 벗어나지 못하기 때문에 모든 추상적 사고의 뿌리는 생존이다. 예를 들면 내가 지금 이 글을 쓰고 있는 뿌리깊은 이유 중 하나는 관심을 받기 위해서이다. 몇 번이나 생각을 해봐도 결론은 같았다. 물론 내 생각을 글로 정리하고 싶기 때문이지만 좀더 깊이 생각해보면 누군가에게 관심을 받고 싶어하는 아주 유약하고 어리석은 아이의 욕망이다. 이건 나의 예시이지만 자신을 돌아보라. 당신이 하는 모든 말과 생각들의 좀 더 근원적인 목적은 무엇인가? 당신이 시기질투하는 누군가를 언짢게 생각하는 근본적인 이유는 무엇인가? 그토록 어떤 신념을 따르는 이유는? 결국 우리는 우리 안에 작은 아이에게서 벗어날 수 없는 것 인가?


어려운 문제이다. 내 가설을 입증하기 위해선 대조군이 필요하다. 내 가설은 뇌의 생물적 한계 때문에 오는 필연적인 자유의지의 부재이다. 모든 원인은 대뇌 피질을 제외한 모든 뇌의 구성원들이다. 대조군은 결국 대뇌의 피질만이 정상 동작하는 인간일 것이다. 그는 어떤 말과 행동을 하게 될까? 그의 말과 행동, 그가 추구하는 것들은 정말 인간적 욕망이 배제된 추상적 사고들일까? 그는 인간의 모든 어리석음을 극복한 현자가 될까? 혹은 피도 눈물도 없는 사이코패스가 될까?

2018년 11월 2일 금요일

어느 이별

이별은 생각보다 견디기 쉽지 않았다.

저 만치 멀어져 가는 듯 싶다가도 어느새 다시 눈앞에 들이닥쳐 내 마음을 긁고 간다. 가끔 음악을 듣다가 불현듯 떠오르기도 하면 다시 마음 속 가장 깊은 곳으로 빠져들어가, 너의 행동 말투 하나하나가 생각나버린다. 좋았던 감정과 슬픈 감정들이 한데 뒤엉켜 달콤 씁쓸한 색으로 변해간다.

일부로 기억을 닳게 하려 평소보다 더 정신없이 살아간다. 그 때문에 벌써 오래된 추억과도 같이 느껴지지만, 감정은 내 의도만큼 흐려지지 않는다. 이런 괴리감이 더욱더 현실을 비현실적으로 만들어낸다.

많이도 울었다. 살면서 이렇게나 많은 눈물을 흘릴까 싶었는데, 너를 만나며 단숨에 모두 쏟아냈다. 어른이 되어가면서 많은 게 무뎌지고 더렵혀질 것 이라 생각했는데, 순수한 부위는 마음 어딘가에 남아있어 너를 통해 발견되었다.

기억과 감정들, 밤새도록 나눴던 그 수많은, 기억도 다 나지 않을 대화들이 불현듯 예고도 없이 찾아온다. 그럴 때마다 의도치 않게 슬픔이 목구멍으로 차오르면 그 순간을 억눌러 참아내기가 쉽지 않다.

살면서 이별은 처음도 아니고 적지도 않았지만, 이 이별은 한 번도 경험해본 적 없는 강렬함으로 다가왔다.

...

서너달이 지났다. 하루의 많은 시간들이 그나마 너를 기억의 저편으로 묻어두고 흘러간다. 감정과 기억의 갑작스런 습격은 그 빈도가 덜해졌다기 보다는 고통 자체가 익숙해졌다. 견디는 자의 하루는 길고 길다.

고독함이 스믈스믈 올라왔다. 너를 만나기 전에는 사실 그 고독함이 오히려 익숙해서 고통으로 느껴지지 않았다. 나에게 찾아온 너는 내 내면의 고독을 모두 삼켜 내 곁에 있다가, 다시 더 큰 고독을 뱉어내고 떠나갔다. 그리고 그 고독은 입으로 신음소리가 삐져나올 정도로 예전의 고독과는 질이 달랐다.

...

시원한 바람을 맞으며 그녀의 집앞 카페에서 기다렸다. 급격히 경사진 그녀가 사는 언덕위 동네는 서울에서 볼 수 없는 호젓한 풍경을 이루었다. 그녀는 내가 눈치채기도 전에 옆으로 다가왔다. 여느때와 다름없었지만 그날따라 더 생기있어보였다. 마치 우리는 그림처럼, 언덕위의 시원한 바람과 햇빛을 맞으며 서로를 비스듬히 바라보고 있었다. 그녀에게 나지막하게 내가 그녀를 기다리며 하고있었던 일들을 설명해준다. 관심은 없지만 서로 오가는 대화와 분위기를 즐겼다. 그리고 오늘의 이야기들을 기대한다.

정막이 감도는 어두운 방. 그녀의 크고 검은 눈동자를 말없이 한참을 바라보았다. 익숙하고 편안했지만 왠지 이상했다. 한번도 우리는 그렇게 아무 말 없이 서로의 눈을 오랬동안 바라본 적이 없었다는 것을 알았다. 그리고 또 다른 사실들을 알게되었다. 나는 지금껏 이 세상에 홀로였다는 것을. 나와 같은 생각을 하는 인격체를 나는 받아들이고 있지 않았다는 것을. 그리고 지금 이 순간 처음으로 누군가를 하나의 인격체로 받아들였고, 세상에 드디어 혼자가 아니라는 것을 알게 된 순간. 그녀의 크고 새까만 눈동자는 나에게 은하수가되어 쏟아졌다.

2016년 4월 25일 월요일

신입 개발자 면접용 컴퓨터공학 기본지식

신입 개발자로서 입사를 준비하기 위해 CS분야의 전반에 걸쳐 기술 면접 시 물어볼 만한 내용을 정리하였습니다.
주제 요약 링크순으로 볼 수 있습니다. 너무 기초적인 부분은 적절히 제외하였습니다.
요약만 보고 내용을 파악하기 어렵습니다. 주제를 자세히 다룬 링크를 타고 들어가 관련 내용을 공부할 필요가 있습니다.

데이터베이스
NoSQL RDBMS 차이 ( NoSQL : Not only SQL )
-      NoSQL등장배경 : SNS 및 아마존 과 같은 비 복잡 단순 데이터가 엄청나게 증가하면서, 기존 오라클과 같은 RDBMS에 대해 용량 부족과 접근의 비효율성 증가
-      목적 : 페타 바이트 급 단순데이터를 다루기 위해 사용.
-      특징 : join 불가, table col의 형식이 제한 되어있지 않음, putget 명령어로만 사용, RDBMS와 혼합하여 사용하는 것을 장려.
ERD ( Entity Relationship Diagram )
-      개요 : 엔티티간의 관계를 나타내는 그림. DFD와 함께 시스템 분석과 설계에서 매우 유용하게 사용. 데이터를 중심으로 데이터간의 관계를 나타내는 그림. 객체지향 프로그래밍에 적함
-      엔티티 : 프로세스 상에 존재하는 모든 데이터 개체. 물리적 추상적 모두 포함. [ 네모 ]
-      릴레이션 : 엔티티간의 연관성을 나타냄. 소유,소속,첨부 등의 의미. 1:1,1:N,N:N [ 마름모 ]
-      어트리뷰트 : 엔티티가 가지고있는 속성 데이터 [ -o ]
-      ERD를 실제 table로 구현하기 위한 세가지 방법 : 링크 참조
데이터베이스 정규화
-      정규화 : 중복을 최소화, 이상현상 제거 ( 삽입, 삭제, 변경 )
-      1단계 : 도메인 원자성
-      2단계 : 모든 비 기본키가 기본키에 완전 함수 종속’ ( 부분함수종속제거 )
-      3단계 : 이행적 함수종속 제거
-      BCNF : 오직 후보키결정자가 되도록 유지
대용량 트랜잭션 처리
-      개요 : 트랜잭션에는 반드시 트랜잭션 로그를 기록하게 되어있음. Full 복구 모드의 대용량 트랜잭션에는 이렇게 행 별 트랜잭션 로그를 기록하는 방식이 용량 문제와 병목현상으로 인한 속도 문제를 야기한다.
-      최소 로깅 작업 : 행 별 변경사항을 로깅할 것이 아니라, table별로 로깅 작업을 진행하여, 테이블 삭제 시 delete가 아니라 truncate를 수행, insert 또한 이와 같은 방식으로 수행.
-      제약 : full 복구모델에선 사용 불가. SIMPLE BULK LOGGED 모델에서만 사용가능. 무결성 제약조건을 따르지 않음.
조인 종류
-      조인의 종류 5가지
n  INNER JOIN
n  OUTER JOIN : Left / Right
n  CROSS JOIN
n  FULL OUTER JOIN
n  SELF JOIN
-      조인 방식 3가지
n  Nested loop join
n  Hash join
n  Merge join
Sql 쿼리 성능 측정
-      쿼리 분석기 사용 : SET STATISTIC IO ON
-      쿼리 수행 시 각 테이블에 대해 -> 스캔, 논리적 읽기 수, 물리적 읽기 수, 미리 읽기 수
-      쿼리 튜닝을 통해 개선시킬 수 있는 부분 : 논리적 읽기 수 ( 버퍼 캐시에 접근하는 횟수 )
대용량 데이터베이스와 쿼리 튜닝
-      대용량 데이터베이스 : 5000만건 이상의 데이터가 적재되는 테이블을 의미.
-      쿼리 튜닝 : 결론적으로 I/O를 줄이기 위한 노력. 꼭 필요한 데이터만을 스캔할 수 있도록 스캔 범위를 조정하는 작업을 포함
-      최적화 : 인덱스를 활용한 것 인가. 병목 구간을 정확히 파악했는가.
그 외
-      데이터 무결성 유형
n  개체 무결성 : 모든 테이블은 기본 키를 가져야 하며 기본 키로 선택된 열은 고유하고, 빈 값은 허용하지 않음.
n  참조 무결성 : 왜래 키 값이 다른 특정 테이블의 기본 키 값을 참조해야만 한다.
n  범위 무결성 ( Domain ) : 해당 속성은 각각의 도메인 집합 안에 존재하는 값만을 취해야 한다.
-      트랜잭션의 특성과 트랜잭션이 깨졌을 때의 복구 방법.
n  ACID : 원자성 부분 실행 X / 일관성 전후 일관된 데이터 / 고립성 다른 작업 끼어들기 X / 지속성 수행된 작업은 영원히 반영
n  ACID transaction 구현 방법 ( 데이터 lock에 의존 )
u   로깅 방식 : 변경사항을 로그에 저장 실패 시 로그를 이용한 롤백
u   새도우 패이징 방식 : 변경사항을 DB복사본에 저장 실패시 DB복사본을 활용한 롤백

운영체제
스레드와 프로세스
-      프로세스 : 프로그램의 인스턴스. 프로세스간 공유부분 ( 프로그램의 코드 및 라이브러리 ), 할당 받는 비 공유부분 ( 변수 할당을 위한 데이터/스택 세그먼트, 실행 위치를 나타내는 PC ),
-      쓰레드 : 한 프로세스의 다양한 실행 흐름. 프로세스 생성 시 Main 쓰레드 하나 생성. 각 쓰레드는 각각의 스택 공간을 제외한 나머지 부분을 공유한다.
-      멀티 쓰레드 장점 : 멀티 프로세스에 비해 메모리 및 시스템 자원 소모 매우 낮음. 쓰레드간 통신 용이 ( 전역 변수로 쉽게 통신 )
-      단점 : 전역변수를 이용한 통신은 충돌 문제를 지니고있다. 동기화 문제를 해결해야 함.
Fetch Decode Execute Pipeline
-      CPU구성요소 : Decoder, CU, ALU, ACC, PC(program counter), IR(instruction), AR(address), DR(data)
-      CPU가 일하는 순서 : fetch -> decode -> execute
-      Fetch : 메모리로부터 instruction을 가져온다.
-      Decode : instruction을 담은 register를 해석한다.
-      Execute : 각종 read, shift, ALU, write 등을 수행한다.
-      Pipe line : CPU의 다른 부분을 사용하는 fetch/decode/execute를 동시에 수행하기 위한 방법
-      Pipe line control hazard, data hazard에 노출 되어있다.
n  Control Hazard : Branch명령을 받아 jump하게 되면, execute단계에서 이미 fetch해 놓은 놈을 버려야하는 문제
n  Data Hazard : 이미 파이프라인 내에서 조작하고 있는 register 데이터를 바로 다음 프로세스가 조작하려 함
가비지 컬렉션
-      동적 할당된 메모리 영역 가운데 더 이상 사용할 수 없게 된 영역을 탐지하여 자동으로 해제하는 기법.
-      장점 : 비 유효 메모리 접근 차단, 이중 해제 차단, 메모리 누수 차단
-      단점 : 메모리 해제 결정에 따른 비용
-      방법 1. 포인터 추적 방식 : 한 개 이상의 변수가 접근 가능한 메모리는 사용할 수 있는 메모리로 간주, 아닌 경우 해체
n  mark and sweep : 각 메모리 할당 영역에 1비트 메모리를 남겨두고 mark단계에서 변수가 가리키는 메모리를 true로 표시, sweep단계에서 false인 영역을 모두 해제
콜백함수
-      Callback : 어떤 이벤트가 발생했을 때 나에게 알려달라고 핸들러를 등록하는 작업. , 함수call을 하는 주체는 사용자가 아니고, OS이다. 기존의 함수 call과는 제어권의 차이가 존재한다.
-      Ex ) < java script > : > a=[3,1,2]; function b(v1, v2){console.log(‘c’, v1, v2); return 0}; a.sort(b); console.log(a);
n  위 예제의 경우 b함수는 유저가 호출하는 것이 아니라, sort에 주입하여 필요에 따라 sort가 호출하는 함수임으로 이를 callback 함수라고 할 수 있다.
데드락
-      개념 : 동일한 자원을 공유하고 있는 두 개 이상의 컴퓨터 프로그램들이 상대방이 자원에 접근하는 것을 사실상 서로 방해함으로써 두 프로그램 모두 기능이 중지되는 결과를 낳는 상황을 말한다.
-      발생 조건 : 전부다 존재해도 발생하지 않을 수 있고, 하나만 존재해도 발생할 수 있다.
n  Mutual Exclusion : 데이터 접근을 상호 배제
n  Hold and Wait : 한 프로세스가 A자원을 hold한 상태로 B자원을 잡기 위해 Wait
n  No Preemption : 다른 프로세스가 잡고있는 자원을 가로챌 수 없다.
n  Circular Wait : 2개 이상의 프로세스가 서로의 작업이 끝나기를 기다린다.
-      해소방안
n  System Dead Lock 상태에 들어가지 않도록 만든다. ( 발생 조건 차단 )
n  System Dead Lock 상태에 들어갈 경우 recover하도록 만든다. ( 데드락 탐색 필요 )
n  문제를 무시하고 Dead Lock이 발생하지 않은 것처럼 수행한다. ( 리눅스/유닉스 서버에서 주로 수행 )

네크워크
TCP/IP 계층
n  IP : 단말과 단말 간 패킷을 전송하기 위해 각 단말은 4바이트 IP주소가 필요. IP ADRESS <-> DNS
n  TCP : 서버와 클라이언트 간 데이터를 신뢰성있게 전달하기 위해 만들어짐. 패킷의 손실을 교정하고 순서를 재조합 한다. 연결 지향 : 전송측과 수신측의 전송 선로인 Session을 만든다.
-      Layer 4. Application Layer ( OSI : application, presentation / HTTP ) : FTP/Telnet/SMTP등으로 이루어진 응용프로그램
-      Layer 3. Transport Layer ( OSI : session, transport / TCP ) : 각 시스템을 연결하고, TCP 프로토콜을 이용해 데이터를 전송하는 계층.
-      Layer 2. Internet Layer ( OSI : network, datalink / IP ) : 데이터를 정의 및 경로 배정(라우팅). 정확히 라우팅 하기 위해 IP프로토콜을 사용한다.
-      Layer 1. Physical Layer ( OSI : physical / Ethernet ) : 이더넷 카드와 같은 하드웨어를 말함.
OSI 7계층
n  ( 장비 / 데이터 형태 / 프로토콜 )
-      7. 응용 ( 서버 / 데이터 / DHCP, DNS, FTP, HTTP, Telnet, SMTP ) : 사용하고 있는 프로세스를 어떻게 인식할 것인가.
-      6. 표현 ( 서버 / 데이터 / SMB, APP, MPEG, JPEG ) : 데이터의 표현 차이 극복. 정보를 어떻게 부호화 할 것인가 압축, 부호화, 암호화.
-      5. 세션 ( 서버 / 데이터 / SSH, TLS ) : 통신 경로의 확립, 단절, 전송 방식을 어떻게 규정할 것인가. 응용 간 논리적 연결 확립
-      4. 전송 ( L4스위치 / 세그먼트 / TCP, UDP, ARP ) : 정보를 전송할 때 신뢰를 어떻게 확보할 것인가. 연결 지향 서비스 제공.
-      3. 네트워크 ( L3스위치, 라우터 / 패킷 & 데이터그램 / IP, ICMP, IGMP ) : 송신 노드에서 수신 노드로 어떤 경로로 정보를 전달할 것인가.
-      2. 데이터링크 ( 스위치 / 프레임 / MAC, PPP ) : 인접한 기기 사이에서 정보를 어떻게 전송할 것인가.
-      1. 물리 ( 케이블, 허브, 리피터 / 비트 / Ethernet ) : 어떤 신호로 통신할 것인가.
그 외
-      L3스위치와 L4스위치의 차이점
-      세션이란 무엇인가
-      대칭키, 비대칭키(공개키) 방식이란

웹 어플리케이션과 웹 프로그래밍
-      웹 어플리케이션이란 웹을 기반으로 실행되는 프로그램을 의미, 웹 프로그래밍이란 웹 어플리케이션을 구현하는 작업.
-      웹 어플리케이션 구조 : 웹 브라우저 웹 서버 웹 어플리케이션 서버 데이터베이스
-      단계 1. 웹 브라우저가 웹 서버에 페이지 요청 2. 웹 서버는 요청을 받아서 요청된 페이지의 로직 및 데이터베이스 연동을 위해 웹 어플리케이션 서버에 처리를 요청 3. 웹 어플리케이션은 데이터베이스와 연동하여 데이터 작업 수행 4, 처리된 결과를 다시 웹 서버로 돌려보냄 5. 웹 서버는 결과를 웹 브라우저에게 넘겨줌.
-      기존 CGI방식 : 웹 서버에서 각 브라우저의 요청 마다 프로세스를 생성하여 처리 -> 메모리 부하
-      WAS(웹 어플리케이션) 방식 : 웹 서버가 직접 프로그램을 처리하지 않고, 웹 어플리케이션에 넘겨줌. 여러 명의 사용자가 동일한 페이지를 요청할 경우, 오직 하나의 프로세스만 생성 후, 각 사용자에게 쓰레드를 할당. 더 많은 사용자에게 서비스를 할 수 있으며 전체적인 성능향상 도모
GET POST 차이
-      목적의 차이
n  Get : 서버에서 어떤 데이터를 가져와서 보여주는 용도
n  Post : 서버의 값이나 상태를 바꾸기 위해서 사용
-      형태의 차이
n  Get : URL에 이어 붙임 ( 길이 제한 -> 적은 양의 데이터 전송 ) ex, http://url.bbslist.html?id=5&pagenum=2
n  Post : 내용이 body안에 숨겨서 인코딩되어 보내짐. 길이 제한 없음.
-      목적과 혼용하여 사용했을 경우 google accelerator 사건 ( 게시물 삭제 버튼까지도 post가 아닌 get으로 설정해 놓은 웹 페이지 개발자들로 인해 get만 찾아 들어가는 accelerator가 게시물을 마구잡이로 삭제/변경 )
쿠키 vs 웹 스토리지
-      개요 : 웹 환경에서 사용자의 정보를 저장해야 할 필요가 있음 ex) 쇼핑몰의 오늘 보았던 물품, 검색 기록 등
-      쿠키 : 4kb허용, http헤더에 붙여 전송(트래픽 낭비 but 서버 전송 가능), 보안 취약
-      웹 스토리지 : 크기 제한이 없다. 서버로 보내지 않는다. 유효기간이 없다. 자바스크립트 객체 저장 가능. Keyvalue로 구성된다.
n  로컬 스토리지 : 도메인 마다 따로 생성된다. 지속 기간에 제한이 없다. (영구성) 도메인이 다르면 서로의 스토리지에 접근 불가. 사이트 고유 설정 정보 등을 대신하기에 적당.
n  세션 스토리지 : 도메인 별, 윈도우 별 따로 생성된다. 윈도우(세션)와 같은 유효 범위와 생존기간을 가진다.
-      http://croute.me/419
그 외
-      HTTPS란 무엇이고, SSL인증방식에 대해 설명하라 ( 혹은 웹 보안에 대해 설명하라 ) : https://opentutorials.org/course/228/4894

알고리즘/자료구조
맵 리듀스 알고리즘 ( Hadoop관련 추가 조사 )
-      목적 : 빅데이터처리를 위해 기존 하드웨어를 활용한 분산 프로그래밍 모델. 이미 분산 환경에 저장된 대용량 데이터를 다시 중앙에서 처리하는 것이 비효율적임으로, 각 분산시스템에서 데이터를 처리할 수 있도록 하기 위함. 혹은, 대용량 입력 파일을 분산시스템에서 처리하여 효율을 높이는 방안. 크게 맵/리듀스 과정으로 나눔
-      과정
n  Splitting : 입력 받은 대용량 데이터를 적절한 크기로 잘라냄
n  Mapping ( Map ) : key – value 로 맵을 구성함.
n  Shuffling : map 함수의 경과를 취합하기 위해 reduce 함수로 데이터를 전달하는 역할을 함. ( 정합병렬 )
n  Reducing : 결과를 key - value 로 정리하여 final result 로 취합.
트립 ( Treap )
-      정의 : 균형 잡힌 이진탐색트리. BST에서 Skewed Tree가 만들어지는 이유는 데이터가 일정한 순서에 의해 입력되는 이유이다. 이때, 각 들어오는 데이터에 대해 랜덤 하게우선순위를 부여함으로써, Heap처럼 우선순위에 따라 삽입한다.
-      조건
n  부모 노드의 우선순위가 자식 노드의 우선순위보다 커야 한다 ( heap )
n  부모 노드의 왼쪽 자식 노드는 더 작은 key, 오른쪽 자식 노드는 더 큰 key값을 가진다 ( BST )
-      삽입 / 삭제 알고리즘은 기존 BST보다 조금 복잡하다.

디자인 패턴
유스케이스 다이어그램 ( UML관련 추가 조사 필요, 질문 유형 : 너가 한 프로젝트를 UML로 그려봐라 or 클래스 다이어그램으로 표현하라 )
-      사용자와의 의사소통을 위해 만들어짐
-      Actor, use case, association ( include, exclude ) + generalization
싱글톤 패턴
-      개요 : 클래스당 유일한 인스턴스를 제공해야 할 필요가 있을 경우 사용. Ex) word processor의 도구 탭 등..
-      코드
Public class Singleton {
Private static Singleton uniqueInstance; // 유일한 인스턴스를 저장 -> static
Private Singleton() { } // 생성자는 내부에서만 쓰임 -> private
Public static synchronized Singleton getInstance() { // 해당 인스턴스를 리턴, 멀티 쓰레딩에 대비한 동기화 -> synchronized
          If( uniqueInstance == null) { uniqueInstance = new Singleton(); } // 생성된 인스턴스가 없다면 첫 인스턴스 생성
          Return uniqueInstance;
} }
MVC 패턴
-      Model View Controller : 어플리케이션을 세가지 역할로 구분한 개발 방법론
-      Controller : 사용자가 컨트롤러 클래스를 통해 모델 클래스를 조작한다. ( manipulate )
-      Model : 모델 클래스는 데이터베이스나 파일과 같은 데이터 소스를 제어한 후 결과를 리턴한다. ( update )
-      View : 컨트롤러는 모델로부터 리턴받은 결과를 뷰 클래스에 반영한다. ( see )

자바
객제지향
-      Keyword : 추상화, 부품화, 은닉화, 캡슐화, 인터페이스
컬렉션즈 프래임워크
-      개념 : C++STL과 같이 다양한 기능을 가진 자료구조를 담고있는 라이브러리 이다.
-      구성요소
n  Collection
u  SET ( HashSet, LinkedHashSet, TreeSet ) : 중복을 허용하지 않는다. 순서가 없다.
u  LIST ( ArrayList, Vector, LinkedList ) : 중복을 허용한다. 순서가 유지된다.
u  QUEUE ( PriorityQueue ) : 각각의 요소가 우선순위를 가지고 우선순위에 따라 정렬된다.
n  MAP ( SortedMap, Hashtable, .. ) : KeyValue 1:1 대응되어 구성된다. Key의 경우 중복이 없는 Set과 같다.
-      Iterator : Collection interface에 존재하는 자료구조로써, 자료구조를 순회하는 역할을 한다. 3가지 기능이 존재( HasNext, Next, remove )
n  사용방식
Iterator hi = A.iterator( );
While(hi.hasNext( )){
System.out.println(hi.next( ));
}
동기 vs 비동기
-      개념 : 일을 처리하는 방식의 두 종류. Ex) 빨래, 청소, 설거지를 해야하는 상황을 예시로 가정
-      동기 : 일을 순차적으로 처리하는 방식 ex) 빨래 청소 설거지를 순차적으로 처리한 후 다른 일이 가능
-      비동기 : 일을 외부에 모두 맡기고, 처리했다는 신호를 기다림 ex) 빨래를 빨래방에 맡김 청소를 청소 업체에 맡김 설거지를 식기세척기에 맡김 다른 일은 처리 빨래, 청소, 설거지가 다 되었다는 신호를 받음.
n  비동기 방식은 Node.js 처리 방식의 기본 철학이 된다. 수많은 요청을 처리해야 하는 서버의 경우, 동기 방식으로 일하게 되면 사용자 응답성에 치명적일 수 있기 때문.
그 외
-      프레임워크란 무엇인가 : 같은 언어로 개발하더라도 개발 방법은 사람마다 모두 다를 수 있다. 하지만 엔터프라이즈급 프로젝트를 진행할 때 이러한 다양성은 큰 문제가 된다. , 프레임워크란 개발 방법을 강제로 고정시키기 위해 아키텍터가 프로젝트 초기에 결정하는 사항 중 하나로써, 프로젝트 특성에 맞게 설정한다.
-      스프링 프레임워크는 왜 쓰는가
-      동시성은 어떻게 확보할 수 있는가 : http://mar7r.blogspot.kr/2013/08/1.html

안드로이드
-      개론 : 안드로이드 응용 프로그램은 적절한 권한만 있으면 언제든지 인스턴스화할 수 있는 4개의 주요 컴포넌트로 구성된다. 그래서 main 같은 유일한 진입점이 따로 없으며 처음 생성되는 인스턴스의 생성자가 실질적인 진입점이다.
-      4개의 컴포넌트
n  액티비티 : 사용자 인터페이스를 구성하는 기본단위. 윈도우와 유사하나 보다 큰 개념. 화면 하나가 액티비티이며 여러 개의 뷰나 프래그먼트로 구성된다. 응용 프로그램은 필요한 만큼의 액티비티를 가질 수 있다.
n  서비스 : UI가 없으며, 백그라운드에서 무한히 실행되는 컴포넌트. UI가 없음으로 사용자의 명령을 받아들일 수 있는 액티비티와 연결해서 사용. Ex) 노래 재생, 네트워크 감시, 백그라운드 계산
n  방송 수신자 ( broadcast receiver : BR ) : 시스템으로부터 전달되는 방송을 대기하고 신호 전달 시 수신하는 역할. UI를 가지지 않으며 방송 수신 시 방송의 의미를 해석하여 적절한 액티비티나 서비스를 띄우는 역할. 컴포넌트끼리 통신할 수 있는 공식적인 방법. Ex) 배터리가 떨어짐, 사진을 찍음, 네트워크 전송이 완료됨 등의 신호를 수신.
n  콘텐츠 제공자 ( content provider : CP ) : 다른 응용프로그램을 위해 자신의 데이터를 제공. 응용 프로그램 간에 데이터를 공유할 수 있는 유일한 합법적 장치. Ex) 주소록 데이터베이스.
-      인텐트 : 액티비티에서 다른 액티비티를 호출하는 주 목적은 뭔가 작업을 시키기 위해서이다. 액티비티끼리 서로 호출하려면 통신을 위한 장치가 필요한데 이 장치가 바로 Intent이다. 인텐트는 액티비티 뿐만 아니라 서비스,BR 등의 컴포넌트가 수행해야 할 작업에 대한 정보를 가지며 작업 결과를 돌려 주기 위해서도 사용된다. 즉 인텐트는 액티비티간에 인수와 리턴값을 전달하는 도구로 사용된다.
-      액티비티 생명주기 : 안드로이드는 멀티 태스킹을 지원하며 여러 개의 응용 프로그램을 동시에 실행할 수 있지만, 데스크톱 환경과는 달리 자원이 넉넉하지 않음으로 여러가지 제약이 따른다. 메모리와 화면의 제약 때문이다. , 여러개의 응용프로그램을 실행할 수 있지만 직접 사용하는 프로그램은 하나밖에 되지 않으니, 대신 사용자는 배경의 프로그램을 활성화 함으로써 교대로 실행한다. 시스템은 태스크의 실행 중인 액티비티를 스택으로 관리한다. 새로 생성된 액티비티는 스택의 최상단에 위치하며, 스택 제일 위의 액티비티가 종료되면 바로 아래쪽에 있는 액티비티가 자연스럽게 활성화된다. 스택상의 액티비티는 다음 세 가지 상태중의 하나이다.
n  Active, running : 사용자가 직접 사용하는 상태. 스택 제일 위에 존재. 포커스를 가지며 사용자의 입력을 직접 처리한다.
n  Stopped : 다른 액티비티에 의해서 완전히 가려진 상태. 눈에 보이지 않는다. 그러나 모든 정보를 유지하고 있음으로 언제든지 다시 활성화될 수 있다. 메모리가 부족하면 언제든지 강제 종료할 수 있다. ( killable )
n  Pause : 포커스는 잃었지만 사용자에게 보이는 상태. 위쪽의 다른 액티비티가 완전히 가리지 않았거나, 반투명한 상태. 살아있는 상태이지만 강제종료 가능하다. ( killable )

임베디드
-      개론 : PC는 여러 목적을 가진 범용적인 시스템이다. 문서작업 뿐 아니라 그래픽이나 멀티미디어 작업까지 가능하다. 하지만 임베디드 시스템은 특수한 목적을 가진 컴퓨터이다. 예를 들어 전자레인지는 음식을 데우기 위한 용도로만 사용되고, 입력은 몇가지 버튼을 통해, 출력은 LED를 통해 이루어진다. 범용의 목적이 아니기떄문에 각 시스템을 구성하는 장치나 소프트웨어가 제한적이다.
-      구현 : 임베디드는 하드웨어 구현과 소프트웨어 구현으로 나눌 수 있다. 하드웨어 구현은 속도는 빠르지만, 확장성이 부족하다. 기능을 확장하기 위해서는 하드웨어를 새로 설계해야 하기 때문이다. 하지만 소프트웨어 설계와 병행한다면, 기능 구현이나 확장이 용이해진다. 소프트웨어 실행을 위해 다양한 임베디드용 프로세스를 사용한다( ARM, MIPS … ). 임베디드 개발 환경은 구성에 따라 모두 달라서 개발자가 직접 컴파일러에 필요한 정보를 입력해 주거나 프로그램에서 직접 처리해야 한다.
-      소프트웨어 개발방법 : 기존 PC는 개발 환경과 실행 환경이 동일하다. 하지만, 임베디드 시스템은 키보드와 마우스가 없음으로 입출력장치가 있는 개발 환경과 테스트를 위한 실행 환경이 다르다. , 개발은 PC에서 수행을 하고 특별한 케이블을 통해 임베디드 시스템에 소프트웨어를 다운로드 시킨 후 테스트를 해볼 수 있다. , 다른 프로세스 환경에서 개발을 해야한다는 것을 의미하여 이를 크로스 개발환경이라 한다. 또한 컴파일러 또한 실행 환경에서 이해할 수 있는 컴파일을 진행해야 함으로 크로스 컴파일러를 사용해야 한다.
-      입출력 : 대체로 memory mapped i/o 방식을 차용한다. , 입출력과 메모리의 주소 공간을 분리하지 않고 하나의 메모리 공간에 취급하여 배치하는 방식이다. , 특정 LED에 해당하는 메모리 주소 공간에 비트를 갱신 시키면 LED가 점등되는 방식이다.

기술면접 문제 형식
: 총 네 가지 영역에서 질문을 합니다. 다만 회사의 특성에 따라 질문하는 비중이 모두 다를 수 있습니다.
1.     지식기반 질문 ( 필기시험 뿐만 아니라 기술 면접에서도 전반적으로 물어보는 추세입니다. )
: 기본 자질을 알아보기 위함. 때로는 경험한 프로젝트 관련 심층 지식을 물어보는 경우도 존재. 임계치를 넘지 못하면 좋은 결과를 기대할 수 없습니다.
n  브라우저애서 주소를 요청해서 결과를 받을 때까지의 과정
n  자신 있는 기술
n  OSI 7 계층에 대한 질문
n  싱글 톤 패턴을 화이트보드에 구현하기
n  안드로이드 액티비티 생명주기
n  스레드와 프로세스의 차이
n  데이터베이스 정규화
n  해시 테이블
n  TDD
n  대용량 트랜잭션 처리에 대한 문제
n  지원한 분야의 가장 기본이 되는 몇가지 API에 대해 어떻게 만들어졌고, 어떻게 구현할 것이고, 어떤 구조인지
n  스프링이나 대용량 DB구조, 인덱스
n  Java Java Script차이
n  Linked List Array 차이
2.     알고리즘관련 질문 ( 주로 개발업무를 직접적으로 맡아 하는 회사 및 직무에서 집중적으로 물어봅니다. )
: 실제 코딩 능력 및 문제해결 능력을 가졌는지 알아보기 위함입니다. 이것 하나만으로 당락이 결정되는 기업도 심심치 않게 볼 수 있습니다.
: 손 코딩의 경우 주로 입출력을 직접 받기보다는 메모리에 존재한다고 가정하고, 함수 단위로 작성하는 경우가 많음. 단계별로 진행하게 되는데, ‘아이디어 도출 -> 코드 작성 -> 코드 설명단계로 이루어지며, 감독관은 화이트보드에 적힌 코드를 핸드폰으로 찍는 경우 , 실시간으로 IDE에 따라 작성하여 디버깅하는 경우가 있음.
n  공이 9개 있다. 무게가 가벼운 공 하나를 찾는데 최소한의 횟수.
n  하노이 탑 손 코딩
n  1~1000 까지 숫자가 무작위로 10000 개가 있는데 이에 대한 평균값 가운데 값 을 알아내는 알고리즘 설계
n  디버깅 능력, 오류색출능력
n  토폴로지 소트 관련 손 코딩 : https://algospot.com/judge/problem/read/DICTIONARY
n  다이내믹 프로그래밍 관련 손 코딩 : https://www.acmicpc.net/problem/1912
3.     프로젝트관련 질문 ( 기술면접의 메인 디쉬 )
: 전문성과 협업 능력을 알아보기 위함입니다. 꼬리 물기 질문으로 진위여부를 가장 예민하게 탐색하는 부분입니다.
n  이전에 담당했던 프로젝트에 대한 구조 설명
n  기존 업무를 진행하면서, 디자이너들과 협업해본적은 있는지, 프로젝트 매니지먼트는 어떻게 했는지
n  기억에 남는 trouble shooting.
n  가장 창의적인, 도전적인, 끈기를 다한, 실패한 직무관련경험
4.     인성 질문 ( 기술면접 파트에서도 드물게 물어볼 때가 있습니다. )
: 조직 및 기업 친화적 성향을 가졌는지, 자기자신 및 기업의 미래 청사진은 가지고 있는지 알아보기 위함입니다. 원한다면 프로젝트 관련 답변으로 방향을 돌릴 수 있는 질문도 출제됩니다.
n  자기소개서와 관련된 내용, 앞으로 하고 싶은 일이 무엇인지, 지금까지 무엇을 경험했는지
n  살면서 가장 큰 성공을 거두었던 경험
n  하고 싶은 것 좋아하는 분야가 어떤 분야인가
n  ~ 것들을 했는지
n  최근 사회 이슈 ex) 대기업의 사회적 의무, 정년 연장, 명예퇴직 권고 등에 대한 자신의 견해
5.     기타
: 지원자가 얼마나 공학적으로 현실 문제를 생각할 수 있는지 알아보기 위함입니다. 최대한 SW개발자 답게 문제를 풀어내는 능력을 보이는 것이 좋습니다.
n  창의성 문제 : 경험상 알고리즘 풀이법을 적용해 보는 것이 좋을 듯 하다. 문제는 항상 불완전하다고 가정하고 문제를 논리적으로 재정의해가면서 푸는 능력이 필요하다.
u  문제정의 (problem space n이 몇일까) -> 해결방안 모색 (time complexity는 얼마나 될 것 인가) -> 오차 값 추산(어느 정도의 error rate를 예상할 수 있을까)
n  프로젝트 설계 문제 : 관련 주제에 적합한 지식을 가지고있으면 유용하다. 기술은 항상 trade off 관계가 있기 때문에, 설계한 방식의 장단점을 미리 예측하여 정리하는 것이 필요하다.
u  Ex) 광고성, 악성 블로그 활동을 저지하기 위한 시스템 설계 -> 구글 페이지랭크 알고리즘