Home

박사란?

그림으로 보는 박사 이야기"인데, 곰곰히 보면 우리에게 주는 교훈은 큰거 같습니다. 가끔 보면서 자신의 위치를 살펴보는 것도 괜찮을 것 같네요.

인류의 모든 지식을 담았다고 생각하는 원을 상상해 보자.



초등학교를 졸업하면 약간의 지식을 얻는다.



고등학교를 졸업할 무렵에는 조금 더 지식을 습득한다.


대학의 학사 학위를 취득하면 전공 분야에서 전문성을 얻을 수 있게 되고



대학원 석사 학위를 취득하면 전문성이 더 깊어진다.



다양한 연구 논문을 읽는다면, 인류 지식의 가장 자리에 다다를 수 있고



가장 자리에 있게 되면 그 부분에 집중하게 된다.



몇 년 동안, 그 경계에서 계속 파게 되고



어느 날, 인류 지식의 경계를 넘어서게 되고



이 홈 부분을 박사라고 부른다.



물론 당시에는 세계가 달라 보인다.



하지만, 큰 그림(전체)을 잊지 마라.



그래서 계속 노력해야 한다.
Tags :

리팩토링이나 코드 리뷰에 사용할 체크리스트


리팩토링이나 코드 리뷰에 사용할 체크리스트로 사용해도 좋을법한 약어들을 공개합니다. 아직 부족하지만 같이 채워나가요. ^^
  • DC(Duplicate Code) - 중복된 코드(중복된 코드나 조건들).
  • BPC(Bad Performance Code) - 성능에 좋지 않는 코드.
  • BN(Bad Name) - 변수나 클래스, 함수 등에 너무 길거나 가독성 떨어지고 일관되지 않은 이름.
  • VS(Violates Specifications) - 가이드나 지침을 따르지 않음.
  • TCL(Too Complicated/Larged) - 불필요하거나 너무 크고 복잡한 함수나 클래스.
  • LP(Long Parameter) - 불필요하거나 너무 긴 인자값들.
  • II(Inconsistent Indentation) - 비일관적인 들여쓰기.
  • NEC(Not Enough Test Cases) - 테스트 케이스가 너무 적음.
  • TMIS(Too Much If/Switch) - 조건 분기가 많음.
  • NC(No Comments) - 주석이 너무 없음.
  • SS(Shotgun Surgery) - 하나의 함수나 클래스를 변경했는데 많은 것들이 영향을 받는다.
  • FE(Feature Envy) - 다른 클래스의 속성과 메소드들을 사용해 다른 클래스와 강한 관계가 성립한다. 모듈(클래스) 독립적이지 못하다.
  • BC(Boilerplate Code) - Getter/Setter 등 맹복적으로 추가되는 반복적인 코드들.
  • TE(Throws Exception) - 예외 처리.
  • NG(Not General) - 너무 범용적이지 않음.
  • DD(Dead Code) - 사용되지 않거나 미리 만들어진, 불필요한 코드들.
  • MN(Magic Number) - 매직 넘버.
  • PD(Platform Dependency) - 플랫폼(언어, 환경 등) 종속성이 있다.
  • AOS(Abuse Open Source) - 오픈 소스 남용.
추가적으로 생각나는 것은 지속적으로 업데이트 하겠습니다. 그리고 여기에 추가할 좋은 약어들이 있으면 코멘트(댓글)나 이메일 남겨주시면 고맙겠습니다. ^^

위임에 관한 70%룰

완벽한 일 마무리와 과로 사이의 균형을 판별하는 공식이 있다네요. 그것이 바로 70%룰이랍니다.

보통 일을 제대로 끝낼려면 다른 사람에게 일을 맡기기보다 자신 스스로가 해야 한다고 생각하는 사람이 많을겁니다. 하지만, 70%룰을 통해 자신의 일을 다른 사람이 해서 70% 정도의 품질만 보장되면 그 사람에게 맡기는 것이 중요하다고 하네요.

모든 일을 혼자 다 할 순 없는 법이니깐요.
CEO가 하는 일을 적어도 자신이 했을때와 비교했을 때 70% 정도의 퀄리티로 할 수있는 사람이 있다면 그 사람에게 일을 맡겨라. 일이 같은 수준의 완성도가 되지 않는다면 좌절하나요? 하지만, 완벽함을 잊으라. 말처럼 쉬운 것은 아니다. 하지만, 맡기는 경우라면 완벽을 요구하는 것은 금물이다. CEO는 작업에 모든 시간을 할애할 필요는 없다. 일에 무한정 시간을 투입할 순 없다. 제때 결과물을 내는 것이 중요하고 거기에 더해 더 영향력이 높은 프로젝트에 투자하는 것이 필요하다.

일을 위임시에 중요한 것은 달성할 목표를 명확히 하고, 그것을 달성하기 위해 무엇이 필요한지를 알고 그것을 팀 구성원에게 전달하는 것이다. 위임에서 가장 어려운 부분은 일을 믿고 기다리는 것이다. 팀의 멤버가 일을 잘 해나갈 것이다라고 믿는 것이다. 위임에서 또 중요한 것은 당신의 팀 구성원이 당신과는 전혀 다른 방법으로 목표를 달성하려고 하는 것을 이해하는 것이다. 그리고 완벽함을 잊기 위해서 무엇을 우선해야 할 것인가를 결정해야 한다. 그 결정할 일은 "완벽함"을 추구 방법이나, 다른 방법도 충분히 결과를 낼 수 있다는 것이다. 팀에 재량권을 주면 과제를 수행하는데 더 새롭고, 좋은 방법을 발견하는 등 더 놀라는 일을 발견하게 될 것이다.
일을 제대로 위임하고 그것을 허용하는 자신의 마음이 중요할거 같네요.

[참조 사이트]
Tags :

Javascript에서 함수형 프로그래밍 맛보기

함수형 프로그래밍을 이해하기 쉽게 설명한 아티클(Don’t Be Scared Of Functional Programming)이 있어서 소개합니다. 정리하면서 느낀점은, 일차적으로 함수형 프로그래밍을 이해하는 것이겠지만, 이차적으로는 코드의 간결성이 좋아지고 리팩토링에서 좋은 사례로 활용할 수 있을 것 같아 좋았습니다. ^^

함수 프로그래밍의 기본 특성

여기서 말하고자 하는 가장 기본적인 함수형 프로그래밍의 특징을 정리하면 아래와 같다.

첫번째, 함수형 프로그래밍에서의 데이터는 Immutable해야 한다. 기존의 데이터를 변경하지 않고 새로운 자료 구조를 만든다. 예를 들어 배열내의 몇몇 데이터에 대해 조작이 필요하다면 원본 배열을 수정하기보다는 업데이트된 값을 가지고 새로운 배열을 만든다.

두번째로 함수형 프로그래밍은 Stateless(상태를 유지하지 않아야)해야 한다. 이것은 프로그램을 수행중에 어떤 일이 일어날지, 아니면 일어나지 않을지에 대해서 모르는 상태로 모든 일을 수행하는 것을 말한다. 즉, 함수 처리에서 다른 무언가에 의존하지 않는다는 것을 말한다. Immutable과 결합해 마치 진공관 속에서 작동하는 것처럼 함수들을 바라볼 것이다. 계산을 수행하면서 외부 값에 영향을 받지 않고 인자로 받은 데이터값에 대한 처리밖에는 하지 않는다.

아래에서 다시 설명하겠지만, 이런 함수형 프로그래밍의 특성을 가지고 구현할 때 모범 사례같은 룰이 있다.
  1. 모든 함수는 최소한 하나의 인자를 수용한다.
  2. 모든 함수는 데이터나 혹은 다른 함수를 반환한다.
  3. 루프는 사용하지 않는다.

실제 함수형 프로그래밍 구현 사례

위의 함수형 프로그래밍의 기본적인 특성을 인지하고 아래의 코드를 보면서 실제 사례를 통해 어떻게 일반 프로그램이 함수형 프로그램으로 변환되는지 보자. 그 예로 인구(population)와 평균 기온(temperature)을 구해서 그래프 즉, 비주얼라이제이션하는 사례를 살펴보는데 여기서는 데이터를 구하는 부분만 어떻게 함수형 프로그래밍 방법이 사용되는지 살펴보자. 먼저 서버의 API에서 응답하는 데이터가 data라는 변수에 저장되고 그 형상은 아래와 같다.
var data = [
  { 
    name: "Jamestown",
    population: 2047,
    temperatures: [-34, 67, 101, 87]
  },
  {
    name: "Awesome Town",
    population: 3568,
    temperatures: [-3, 4, 9, 12]
  }
  {
    name: "Funky Town",
    population: 1000000,
    temperatures: [75, 75, 75, 75, 75]
  }
];

인구(population)와 평균 기온(temperature)을 비교하기 위해 그래프나 차트를 사용하기를 원한다면, 그래프를 그리기 전에 먼저 위의 데이터를 약간 변경해야 한다. 그래프 라이브러리는 다음과 같은 x, y좌표를 원할 것이다.
[
  [x, y],
  [x, y]
  …
]

x는 평균 기온, y는 인구를 나타낸다. 함수형 프로그래밍이라는 관점을 의식하지 않고 구현하면 아래와 같다.
var coords = [],
    totalTemperature = 0,
    averageTemperature = 0;

for (var i=0; i < data.length; i++) {
  totalTemperature = 0;
  
  for (var j=0; j < data[i].temperatures.length; j++) {
    totalTemperature += data[i].temperatures[j];
  }

  averageTemperature = totalTemperature / data[i].temperatures.length;
  coords.push([averageTemperature, data[i].population]);
}

함수형 프로그래밍 방식으로 전환하기 위해서는 위에 설명했듯이 다음과 같은 모범사례를 사용하면 좋다.
  1. 모든 함수는 최소한 하나의 인자를 수용한다.
  2. 모든 함수는 데이터나 혹은 다른 함수를 반환한다.
  3. 루프는 사용하지 않는다.

자 그러면, 위 프로그램을 함수형 언어 방식로 변경해 보자. 우선 배열(온도)의 합계를 내는 함수를 먼저 만들어보자.
function totalForArray(arr) {
  // add everything
  return total;  
}
그런데 3번 룰인 루프 사용 금지에 의거해 루프를 사용하지 않기 위해서는 재귀 방식을 사용하여 구현한다.
// 인자로는 전체 합계와 배열을 가진다.
function totalForArray(currentTotal, arr) {
  
  currentTotal += arr[0]; 

  //Array.shift를 사용하지 않고 Immutable을 보장하기 위해서 배열편집보다는 새로 만든다. 
  var remainingList = arr.slice(1);

  // 재귀처리를 하고 현재 합계와 나머지 배열을 인자로 전달하고 
  if(remainingList.length > 0) {
    return totalForArray(currentTotal, remainingList); 
  }
  
  // 나머지 배열이 없으면 전체 합계을 리턴한다.
  else {
    return currentTotal;
  }
}

주의) 재귀는 가독성을 올려주고 함수형 프로그래밍에서는 필수다. 하지만, Javascript와 같은 싱글 오퍼레이션에서 재귀 호출이 많은 경우는 가끔 문제를 유발하는 경우도 있다.(10,000 calls in Chrome, 50,000 in Firefox and 11,000 in Node.js)

이제 온도의 합은 아래와 같이 호출하면 얻을 수 있게 되었다.
var totalTemp = totalForArray(0, temperatures);
더 분해할 수 있는 부분이 totalForArray함수의 currentTotal을 처리하는 부분이다.
function addNumbers(a, b) {
  return a + b;
}

그래서 결국 아래와 같은 totalForArray 함수를 만들수 있다.
function totalForArray(currentTotal, arr) {
  currentTotal = addNumbers(currentTotal, arr[0]);

  var remainingArr = arr.slice(1);
  
  if(remainingArr.length > 0) {
    return totalForArray(currentTotal, remainingArr);
  }
  else {
    return currentTotal;
  }
}

배열에서 단일값을 반환하는 것은 함수형 프로그래밍에서 매우 일반적인 특징이다. 그래서 Javascript에서는 reduce라는 편리한 함수가 존재한다. 그래서 온도의 합계를 계산하는 reduce 방식은 아래와 같다.
Array.prototype.reduce 사용법은 여기를 참고하자.
var totalTemp = temperatures.reduce(function(previousValue, currentValue){
  return previousValue + currentValue;
});

그리고 덧셈 부분을 조금 전에 만든 덧셈의 함수(addNumbers)를 사용하면 아래와 같이 된다.
var totalTemp = temperatures.reduce(addNumbers);

배열의 합계를 할 경우 재귀나 reduce 사용 판단의 혼란을 가중시키지 않고 일반적인 함수를 만든다면 아래와 같아진다.
function totalForArray(arr) {
  return arr.reduce(addNumbers);
}

var totalTemp = totalForArray(temperatures);

두번째 일로 이제까지 구한 합계에서 평균을 내는 함수를 만든다.
function average(total, count) {
  return total / count;
}

지금 만든 평균과 좀 전에만든 합계 로직을 결합하면 어떻게 될까?
function averageForArray(arr) {
  return average(totalForArray(arr), arr.length);
}

var averageTemp = averageForArray(temperatures);

마지막으로, 객체 배열에서 하나의 속성을 빼내는 함수를 만들어 보자. 재귀함수 대시에 우리는 JavaScript가 가지고 있는 map 내장함수를 사용한다.
var allTemperatures = data.map(function(item) {
  return item.temperatures;
});
이는 위의 data 객체에서 온도만 추출해내는 것으로 결과는 아래와 같이 된다.
var allTemperatures = [-34, 67, 101, 87, -3, 4, 9, 12, 75, 75, 75, 75, 75];

객체 배열에서 속성을 추출하는 것도 일반적인 작업이므로 함수로 만든다.
function getItem(propertyName) {
  return function(item) {
    return item[propertyName];
  }
}

주의할 점은, 이 함수는 함수를 반환한다. 실행 호출자에게 맡기고 있다는 점이다. map과 연동하면 아래와 같이 된다.
var temperatures = data.map(getItem('temperature'));

좀 더 가독성과 범용성을 높이기 위해서 아래와 같은 함수를 만든다.
function pluck(arr, propertyName) {
  return arr.map(getItem(propertyName));
} 

var allTemperatures = pluck(data, 'temperatures');

이제 객체 배열에서 원하는 프로퍼티를 추출할 수 있게 되었다.
자 그럼 위에서 제시했던 문제의 해법을 적용하자면, x는 평균기온, y는 전체 인구를 추출해야한다.
var populations = pluck(data, 'population');
var allTemperatures = pluck(data, 'temperatures');
var averageTemps = allTemperatures.map(averageForArray);

위의 처리결과 다음과 같은 두개의 배열값을 취득하게 되었다.
// populations
[2047, 3568, 1000000]

// averageTemps
[55.25, 5.5, 75]

마지막으로, 2개의 배열을 하나로 통합 함수를 만든다.
function combineArrays(arr1, arr2, finalArr) {
  // 셋째인자의 배열이 널일 경우를 대비하여 초기화해 줌
  finalArr = finalArr || [];

  // 첫번째 배열요소를 추출해 출력 배열에 삽입함
  finalArr.push([arr1[0], arr2[0]]);

  var remainingArr1 = arr1.slice(1),
      remainingArr2 = arr2.slice(1);

  // 남아있는 배열이 비어있는 경우 리턴 
  if(remainingArr1.length === 0 && remainingArr2.length === 0) {
    return finalArr;
  }
  else {
    // Recursion!
    return combineArrays(remainingArr1, remainingArr2, finalArr);
  }
};

var processed = combineArrays(averageTemps, populations);

결국, 결합함수에 의해서 처리되는 결과값은 아래와 같아진다.
var processed = combineArrays(pluck(data, 'temperatures')
.map(averageForArray), pluck(data, 'population'));

// [
//  [ 55.25, 2047 ],
//  [ 5.5, 3568 ],
//  [ 75, 1000000 ]
// ]

결국에는 아래와 같은 코드로 귀결된다.

이것이 함수형 프로그래밍의 전부는 아니겠지만, 이를 활용할 경우 리팩토링이나 코드 작성 지침에 좋은 훈수 역할을 할 수 있을 것으로 생각됩니다.

빌드시스템 Pants에 대해

Foursquare/Twitter/Square에서 사용중인 증분 빌드 시스템인 Pants(오픈소스)에 대해서 정리했습니다. 참고 사이트는 트위터 블로그에 쓰여진 "Hello Pants build"를 참고하였습니다.

큰 프로젝트의 경우 codebases가 커짐으로인해 그에 수반되는 개발 작업의 어려움도 증가하게 된다. 빌드도 느려지고, 또한 현재 존재하는 툴들은 그리 스케일하지도 않다.

그래서 하나의 해결책으로 내놓은 것이 코드를 분리해 여러 저장소에 나누어 관리를 하는 것이다. 그러나 이렇게함으로써 codebases가 수백개로 겉잡을 수 없게 되 종속성 관리도 어렵게 되어버린다. 그래서 결국 개발자의 개발 생산성에 악영향을 준다는 것이다.

다른 해결책의 하나로 Python으로 개발된 Pants를 사용하는 것인데, 이는 커진 코드베이스를 하나의 저장소로 정리해 종속성도 효율적으로 관리되다보니 개발 생산성도 올라간다는 것.

Pants는 Google의 내부 빌드시스템을 참고로 작성되었으며, Foursquare/Twitter/Square에서도 사용중이며, 실제 필요한부분, 즉, 변경된 부분만 컴파일하는 증분 빌드 기법을 적용하고 있다.

주요 강점은 아래와 같다.
  • 현재는 Java/Scala/Python을 지원.
  • 다른 언어를 추가해도 문제가 없음.
  • 코드 생성을 지원 : thrift, protocol buffers, 커스터마이징 가능한 코드 생성기도 지원.
  • 외부 JVM/Python 종속성을 지원함.
  • 테스트 수행함.
  • 배포 가능한 패키지를 만들 수 있음.
  • 스케일 지원.
  • 증분빌드 지원.
  • 스칼라 언어의 빌드는 다른 도구들보다 빠름.
  • 독립형 Python의 executable(PEX 파일)를 빌드함.
  • 로컬/분산 캐시를 지원.
  • Linux와 Mac OSX에서 돌아감.

AngularJS 사용하면서 정리한 것들

작년부터 AngularJS 도입해 사용하면서 도움이 될만한게 뭐있나 고민하다가 초기에 알아두면 좋을법한 내용을 정리해 보려고 합니다. MVW에 대한 고민하면서 코딩을 했는지, 내가 AngularJS를 문제없게 코딩했는지 등에 대한 불안을 어느정도 회피해 줄 수 있는 생각들을 공유합니다.

AngularJS 기반 MVW 이해하기



MV* 패턴 적용의 목적은 프레젠테이션과 도메인을 격리시키는 것이다. 분리의 장점은 아래와 같다.
  • 프리젠테이션 로직과 도메인 로직이 분리되면 이해도가 올라간다.
  • 같은 베이스 프로그램을 중복코드 없이 여러 프리젠테이션에 대응할 수 있다.
  • 사용자 인터페이스는 테스트가 어렵기 때문에 그것을 분리하는 것은 테스트 가능한 로직을 유지할 수 있다.
  • 스크립트에 대한 API나 서비스로 구체화하기 위한 API를 쉽게 추가 할 수 있다.(다른 프리젠테이션 영역에서도 볼 수 있는)
  • 프레젠테이션 부분의 코드는 도메인 부분의 코드와 다른 지식과 기술이 필요하다.
1. Model 역할
데이터 관리, 서버측과 통신 등의 역할을 하며 서비스와 데이터로 나뉘어 지는데 데이터와 관련된 일반적인 작업은 Service, Factory에 위임하는 것이 코드가 깔끔해진다.
  • Service : JavaScript 클래스. 런타임은 new로 인스턴스가 생성된 싱글톤으로 취급된다. 다른 개발에서 만든 JavaScript 클래스 등을 전용할 수 있기 때문에 유연성, 사용 용이성이 좋다.
  • Factory : 실체로는 function(함수 참조). 특성으로는 내부 변수를 사용하면 함수 범위에 숨겨지며 private처럼 취급 된다.(Controller에서 참조 불가).
2. View 역할
레이아웃(HTML)과 프리젠테이션 로직으로 나눌 수 있는데 내부 로직이 복잡해지면 Directive나 Filter를 사용하면 된다. 그런데 코드는 깔끔해지나 제3자가 볼 때 이해도가 확실히 떨어진다는 단점을 가지고 있다.

3. Controller 역할
주로 이벤트 핸들링과 Data Binding에 집중하는 역할을 한다.
  • 이벤트 핸들링(Event -> Model): 이벤트를 Model에 전달해 값 변경 등을 실현한다. 이것은 ng-model에서 직접 실현하거나 ng-click 등으로부터 Model의 function을 부르는 형태로 구현될 수 있어 다양한 방법들이 존재한다.
  • Data Binding(Model -> View): 모델의 변경을 View에 반영한다. 이것은 Angular.js는 의식할 필요가 없다 ($watch 통해 Model의 변경이 감시되고 변경되면 자동으로 업데이트 됨).
다음부터는 AngularJS를 잘 이해하지 못하고 코딩을 하면 돌아는 가는데 문제가 될 여자가 많은 코드를 생산할 수 있어서 이를 도구를 통해 미연에 조금이나마 방지할 수 있는 방법들을 설명한다.

AngularJS Hint 사용하기

AngularJS를 사용하여 개발한 응용 프로그램에 통합 실행하면 오류가 발생 주거나 모범 사례를 준수하는지 여부를 확인하여 준다. 그리고 현재의 angular-hint 프로젝트 상태는 WIP(Work In Progress)라고 써 있는 것으로 보아 아직 개발중인 것 같다.

1. angular-hint 사용 방법
angular-hint를 사용하려면 github에서 소스를 가져 와서 빌드하거나 npm을 통해 가능하다.
$ npm install angular-hint

node_modules/angular-hint/dist/hint.js라는 파일을 찾아서 해당 프로젝트에 카피해서 사용하면 된다. 사용 방법은 아래와 같다.
angular.js 뒤에 hint.js를 읽어들이게 하고
<script type="text/javascript" src="resources/angularjs/hint.js"></script>
ng-app을 지정하는 부분에 ng-hint를 추가하면 된다.
<html lang="ko" data-ng-app="App" ng-hint>

2. angular-hint 표시되는 메세지 정보
1번에서 설명한대로 한 다음 WAS를 구동해서 console 로그를 보면 오류 등의 정보를 확인할 수 있다.


여기서 알려주는 내용은 Modules, Controllers, Directives, DOM, Events, Interpolation의 6 종류의 카테고리로 제공하고 메세지 수준은 오류, 경고 및 제안 등 세가지로 분류되어 표시된다.

AngularJS 성능 관련

AngularJS는 Batarang이란 편리한 도구(Chrome Developer Tools 확장 기능)가 존재한다. 이 도구는 AngularJS의 디버깅이나 성능 메트릭스 등에 참고할만한 정보를 보여줘 개발시에 참고하면 좋다. 그리고 시작은 AngularJS 탭의 Enable 체크만 하면 된다.


AngularJS는 양방향 데이터 바인딩의 구조가 매우 유용하지만 성능에 영향을 줄 수 있는 이슈가 나올 수 있어 성능상의 병목을 짚어보는 것은 중요하지만 먼저 이 구조를 이해하는게 더 중요할 수 있다.

1. 데이터 바인딩 구조 이해
데이터 바인딩 메커니즘의 실현 방법에는 여러 가지 방법이 있지만, 여기서는 두가지정도 언급하고 만다. 첫번째의 경우는 Knockout.js의 경우로 데이터의 값이 변경될 때 이벤트 리스너에서 View에 통지하는 방식을 취하고 있고, 두번째인 AngularJS는 dirty-checking라는 방식으로 구현되어 있는데, 이것은 바인딩 되는 모든 변수에 대해 특정 시간에 이전 값과 현재 값을 비교하고 값에 변화가 있으면 DOM을 갱신하는 구조이다.

이를 순차적으로 기술해 보면
- HTML을 분석하여 지시문(directive)을 컴파일할 때 바인딩되는 변수를 $scope.$watch()로 등록한다.
- $rootScope 자식들의 scope를 차례로 검색해, watch에 등록된 모든 변수의 변경 검사를 수행한다. 이 과정을 $digest 루프라고 부르고, 아래와 같은 타이밍에서 실행된다.(정기적인 폴링은하지 않습니다)
  • $scope.$apply()를 부를 때.
  • DOM 이벤트 (onChange, onClick 등)가 발생한 후.
  • $http와 $resource에서 응답이 돌아왔을 경우.
  • $location에서 URL을 변경한 후.
  • $timeout이벤트가 발생한 후.
- 변경 검사가 완료되면 변경된 부분의 DOM을 다시 시작한다.

2. 개선 포인트는 어떻게
- 불필요한 $scope 변수나 $scope.$apply()를 하지 않는다.
$digest 루프에서는 watch하고 있는 변수의 수와 변수의 비교 처리 시간이 성능에 크게 영향을 준다. 그래서 watch 변수의 수는 가능한 적게, 객체의 비교 처리는 가능한 한 가볍게하는 것이 좋다. watch 변수의 수 기준은 2000개 이하, 비교 처리 시간의 기준은 25μsec라고 알려져 있다.(여기)
Batarang을 사용하면 $scope의 트리 구조를 시각화되므로 watch하고 있는 변수의 수를 확인할 수 있다.

- $watch에서 무겁고 느린 처리를 만들지 말자.
그러면 응용 프로그램 전체가 느려집니다. JavaScript가 단일 스레드인 특성상 $digest 루프는 단일 스레드에서 처리된다.

- 예기치 않는 동작을 방지하도록 될 수 있으면 angularjs 모듈들을 사용하자.
  • setTimeout 대신 $timeout을 사용.(angular의 digest와 apply주기에 따라 setTimeout에서 수행 한 작업이 angular에 반영되지 않는 경우가 있기 때문에, 아래도 비슷한 이유이다.)
  • window 대신 $window를 사용.
  • document 대신 $document를 사용.
  • $.ajax 대신 $http를 사용.

- 다른 콘트롤러와 통신할 때 주의하자.
$emit, $broadcast, $watch를 사용하게 되는데, 일반적으로 $watch는 $emit이나 $broadcast 같은 event 방식에 비해서 성능 소모가 많다고 알려져 있다.(여기)
$rootScope.$broadcast의 경우, AngularJS가 관리하는 모든 scope에 방문해야 하기 때문에 성능 문제가 있을 수 있다. 기본적으로 통신은 줄이데 공유 데이터는 서비스에서 처리하도록 하자.

- ngShow/ngHide/ngIf를 적정한데 사용하자.
ngShow/ngHide는 CSS를 통해 표시를 전환하고 ngIf는 DOM의 추가나 삭제를 할 수 있게 되어 있다. 그래서 ngShow/ngHide는 ngRepeat와 같이 쓸경우 리스트가 많게 되면 초기 로드가 느릴수 있고 화면 전환(보이고/안보이고)은 빠르게 되고 반대로 ngIf는 초기 로드는 빠르지만 화면 전환이 느린 특성이 있으니 잘 활용하자.

- 기타
  • ng-cloak : 페이지 로딩 중 등에서, angular 처리되기 전에 마크업이 보여 버리는 것을 방지한다.
  • 변수나 메서드 이름에 $접두사를 사용하지 않는다. 이 접두사는 AngularJS에서 예약되어 있다.
  • $scope를 더럽 히지 말자. 템플릿에서 사용하는 메소드나 변수만 추가하자.
  • 전역 변수를 사용하지 말자. 의존성 주입을 사용하여 모든 종속성을 해결하자.
  • 콜백 대신 promise($q)를 사용한다. 그러면 코드는 더 우아하고 깨끗한되고 콜백 지옥에서 벗어나게 해준다.
  • 가능할 땐 $http 대신 $resource를 사용. 높은 수준의 추상화는 번잡한 작업으로부터 해방시켜 준다.
  • 될수 있으면 angularjs 내장 함수들을 사용하자. angular.element, angular.forEach 등.

[참조 사이트]

Vim에 대해 점진적으로 학습하기

본 포스트는 "Learn Vim Progressively"라는 아티클을 번역한 것으로 Vim에 대해서 모르시는 분들이나 되새김질을 하고 싶은 분들에게 좋은 글이 될 거 같아 정리해 보았습니다.



TL;DR: 여러분은 vim(인류 역사상 가장 많이 알려져 있는 텍스트 에디터)을 가능한 한 빨리 습득하고 싶을 것이다. 그래서 여기에 그렇게 될 수 있는 방법을 소개한다. 그리고 살아남을 수 있는 최소한의 내용으로 학습을 시작하고 그 뒤에 천천히 트릭 부분을 추가하겠다.

Vim - 60억 달러 텍스트 에디터
더 좋고, 더 강하고, 그리고 더 빠른
vim을 배워라 그러면 당신이 배우는 마지막 텍스트 에디터가 될 것이다. 내가 알고 있는 더 나은 텍스트 에디터는 없다. 배우기는 어렵지만, 사용하기에는 더 없이 좋다.

Vim을 네단계로 배우는 것을 제안한다:

1. 생존하기.
2. 편안함 느끼기.
3. 더 좋고, 더 강하고, 그리고 더 빠름 느끼기.
4. Vim의 막강한 힘 사용하기.

이 여정의 끝에서 당신은 Vim에 대해 슈퍼 스타가 될 것이다.

그러나 시작하기 전에 경고하나 하겠다. Vim 학습은 처음에는 고통스러울 것이다. 시간이 걸리고 많은 악기를 연주하는 것 같을 것이다. 3일보다 더 적은 노력으로 다른 편집기보다 Vim을 더 효율적으로 사용할 수 있다는 기대는 하지 마라. 현실적으로, 실상은 3일은 커녕 거의 2주는 걸릴 것이다.

1. 첫번째 레벨 - 생존하기


1. Vim 을 설치하고
2. Vim 시작시키고
3. 아무것도 하지 마라! 그냥 읽어라.

일반 편집기에서 키보드를 타이핑하는 것만으로도 원가를 쓰고, 화면에서 읽을 수가 있다. 여기 Vim에서는 그렇지가 않다. Vim은 본래 Normal모드이다. 자! Insert 모드로 가보자. i글자를 타이핑해라.

당신은 약간 더 좋은 느낌을 가질것이다. 이제 당신은 일반적인 에디터처럼 문자를 입력할 수 있다. Normal모드로 되돌아가기 위해서는 ESC키를 누르면 된다.

당신은 Insert 모드와 Normal모드 사이의 전환이 어떻게 하는지를 배웠다. 그리고 지금 당신이 Normal모드에서 살아남기 위해 필요한 커맨드 목록은 아래와 같다:
- i → Insert 모드. ESC를 누르면 Normal모드로 되돌아간다.
- x → 커서의 위치해 있는 문자를 지운다.
- :wq → 저장 후 종료(:w 저장 :q 종료).
- dd → 현재 행 삭제(그리고 복사된다)
- p → 붙여 넣기

추천 :

- hjkl (특히 필수는 아니지만 강력 권장) → 기본적인 커서 이동(← ↓ ↑ →). 
힌트 : j 아래쪽 화살표처럼 보인다. - :help <커맨드><커맨드>에 관한 도움말을 표시한다.
<커맨드>없이 :help를 사용하면 일반적인 help 내용을 볼 수 있다.
단지 5개의 커맨드다. 이것이 시작하기 위해 필요한 전부이다. 이 커맨드의 시작한 뒤 자연스럽게 사용할 수 있다면(하루정도가 되겠지만) 당신은 레벨 2로 이동하면 된다.

하지만 우선 조금 더 Normal모드에 대해 이야기하고자 한다. 일반 에디터에서는 복사를 하는데 Ctrl키(Ctrl-c)를 사용한다. 사실, Ctrl을 눌렀을 때, 그것은 키의 의미를 바꾸는 것이 된다. Normal mode로 Vim을 사용하면 에디터에서 Ctrl키를 계속 누르고 편집하는 것과 같다.

표기에 대한 내용 :
- Ctrl-λ대신에 나는 <C-λ>를 쓸 것이다.
- :로 시작하는 커맨드는 <enter>로 끝나야 한다. 예를 들어, :q 라고 썼다면 :q<enter>를 나타낸다.

2. 레벨 2 - 편안함 느끼기


당신은 생존하기 위해 필요한 커맨드를 알고 있다. 몇 가지 더 커맨드를 학습하자. 내가 제시하는 것은 아래와 같다:

1. Insert 모드의 다양성 :
- a → 커서 뒤에 삽입
- o → 현재 행 다음에 새로운 행 삽입
- O → 현재 줄의 앞에 새로운 행 삽입
- cw → 커서의 위치에서 단어의 끝까지 교체

2. 기본적인 이동
- 0 → 행의 시작 부분으로 이동
- ^ → 행의 공백이 아닌 첫 번째 문자로 이동
- $ → 행의 끝으로 이동
- g_ → 행의 공백이 아닌 끝 문자로 이동

- /pattern → pattern 검색

3. 복사/붙여넣기
- P → 커서 전에 붙여 넣고, p는 커서 뒤에 붙여넣기가 된다는 것을 기억하라.
- yy → 현재 행을 복사. 쉽게 말하면 ddP와 같다.

4. 실행 취소/재실행
- u → 실행 취소
- <C-r> → 재실행

5. 로드/저장/종료/파일(버퍼) 변경
- :e <path/to/file> → 파일 열기
- :w → 파일 저장
- :saveas <path/to/file> → <path/to/file>에 저장
- :x, ZZ 혹은 :wq → 저장 후 종료
- :q! → 저장하지 않고 종료. 또한 숨겨진 버퍼에 변경이 있어도 :qa!는 종료.
- :bn (관련 :bp) → 다음(관련 이전) 파일(버퍼)을 표시.

이들 커맨드 모두를 배우는데 시간이 걸린다. 한번 해보면 다른 편집기에서 할 수 있는 모든 것을 할 수 있을 것이다. 당신은 약간 어색함을 느낄수 있을 수도 있다. 그러나 다음 단계를 따라온다면 그 이유를 알 수 있을 것이다.

3. 레벨 3 - 더 좋고, 더 강하고, 그리고 더 빠름 느끼기


여기까지 온 것에 대해 축하합니다! 지금 우리는 더 재미있는 것을 시작할 수 있다. 레벨 3에서는 이전 vi와 호환되는 커맨드에 대해 이야기할 것이다.

3.1 더 좋은 점
Vim은 사용자의 반복 동작에 대해 어떻게 도움 수 있는지를 살펴 보자:

1. . → (도트)는 마지막 명령을 반복하게 할 것이다.
2. N<커맨드> → 커맨드를 N번 반복한다.

다음은 몇가지 예를 나타낸다. 파일을 열고 타이핑하자 :
- 2dd → 2행을 삭제를 할 것이다.
- 3p → 해당 텍스트를 3번 붙여넣기를 할 것이다.
- 100idesu [ESC] → "desudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesudesudesudesudesudesu
desudesudesudesudesudesudesudesudesu"로 100개 desu가 쓰여진다. - . → 방금 전 마지막 명령 "desu" 100개 쓰기가 다시 실행된다. - 3. → 3개의 "desu"를 쓴다.(300개가 아니다.)

3.2 더 강한점
Vim을 사용하여 효율적으로 이동하는 방법을 안다는 것은 매우 중요하다. 이 섹션을 건너 뛰지 마라.

1. NG → N행으로 이동
2. gg → 1G 바로 가기. 파일의 처음으로 이동,
3. G → 마지막 행으로 이동
4. 단어 이동 :
- w → 다음 단어의 시작 부분으로 이동
- e → 낱말의 끝으로 이동합니다.

기본적으로 단어는 문자와 밑줄로 구성되어 있다. WORD는 공백 문자로 구분된 문자 그룹이라고 부르기로 하자.
WORD로 간주하려면 단지 대문자를 사용하자. - W → 다음 WORD의 시작 부분으로 이동 - E → 해당 WORD의 끝으로 이동.

이제부터 매우 효율적인 이동에 대해 설명하자:
- % : (, {, [에 대응하는 곳으로 이동.
- *(관련 : #) : 커서가 위치해 있는 다음 단어(관련 : 이전)로 이동.

저를 믿으세요. 마지막 세 커맨드는 금입니다.

3.3 더 빠른점
vi에서의 이동의 중요성을 기억하라. 여기에는 이유가 있다. 대부분의 커맨드는 다음과 같은 일반적인 형식을 이용하여 사용할 수 있다.
<시작 위치> <명령> <마지막 위치>
예를 들면 : 0y$의 의미는 다음에 기술되어 있다.

- 0 → 이 행의 시작 부분으로 이동
- y → 양크
- $ → 이 행의 끝으로

ye 같은 것을 할 수 있으며, 여기에서 단어의 끝까지를 양크한다. 하지만, y2/foo는 두 번째에 있는 foo까지 양크한다.

하지만, y(양크)뿐만 아니라, d(삭제), v(시각적 선택) gU(대), gu(소문자) 등도 비슷하다.

4. 레벨 4 - Vim의 강력한 힘


앞서 언급한 커맨드를 Vim에서 사용하면 편안함을 느낄것이다. 그러나 다음부턴 킬러 기능들이 소개된다. 이들 기능중의 일부가 내가 Vim을 사용하기 시작한 이유였다.

4.1 현재 행의 이동 : 0 ^ $ g_ f F t T , ;
- 0 → 행의 시작 부분(칼럼 0)으로 이동
- ^ → 행의 첫 글자로 이동
- $ → 행의 마지막 칼럼으로 이동
- g_ → 행의 마지막 문자로 이동
- fa → 행에서 다음 문자 a로 이동. ,(관련 ;)는 다음(관련 : 이전) 발견된 지점까지 이동.
- t, → ,앞으로 이동.
- 3fa → 행에서 3번째로 발견된 a를 찾음.
- FT → F와 t처럼 비슷하지만 반대관계다.


유용한 tip은 : dt""까지 모두 삭제.

4.2 지역 선택 <action>a<object> 또는 <action>i<object>
이 명령은 비주얼 모드에서 연산자 뒤에만​​ 사용할 수가 있다. 그러나 아주 강력하다. 주요 패턴은 다음과 같다.
<action>a<object> and <action>i<object>

액션은 다양한 액션이 될 수 있다. 예를 들어 d(삭제), y(양키), v(비주얼 모드 선택). 그리고 객체는 w 단어, W WORD(확장된 단어) s 문장, p 단락이 될수 있고 아니면. ", ', ), }, ] 같은 자연적인 문자도 될 수 있다.

커서가 (map (+) ("foo")) 의 첫 번째 o에 있다고 가정한다.
- vi"foo를 선택
- va""foo"를 선택
- vi)"foo"를 선택
- va)("foo")를 선택
- v2i)map (+) ("foo")를 선택
- v2a)(map (+) ("foo"))를 선택


4.3 사각형 블록 선택 <C-v>
사각형 블록은 코드의 많은 행을 주석처리하는데 매우 유용하다. 타이핑해보면: 0<C-v> <C-d>I-- [ESC]

- ^ → 행의 공백없는 첫번째 문자로 이동
- <C-v> → 블록 선택 시작
- <C-d> → 아래로 이동 (jjj 와 % 등도 이동항 수 있다)
- I-- [ESC] → 각 라인의 주석처리를 위해 --를 쓴다.


Windows 환경에서는 클립 보드가 비어 있지 않으면 <C-v> 대신 <C-q>를 사용할 수도 있다.

4.4 보완 : <C-n>과 <C-p>
Insert 모드에서는 단어의 시작 부분에 <C-p>를 입력 해 보자. 그러면 마법과 같은 일이...


4.5 매크로: qa는 뭔가 실행해준다. q, @a , @@
qa는 여러분의 액션을 a Register에 기록한다. 그리고 @a는 a 레지스터에 기록된 매크로를 마치 그것을 입력했는것과 같이 재현해준다. @@는 마지막으로 실행된 매크로를 재생하는 단축키이다.
예
숫자 1만 포함한 한 행에서 아래의 것을 타이핑하자:

- qaYp<C-a>q →
  - qa 기록을 시작한다.
  - Yp 행을 복제한다.
  - <C-a> 숫자를 증가시킨다.
  - q 기록 중지한다.
- @a → 1 아래 2를 쓴다
- @@ → 2 아래 3을 쓴다.
- 지금 100@@는 103까지 일련 번호 증기시킨 숫자 리스트를 생성한다.


4.6 비주얼 선택: v, V, <C-v>
<C-v>를 사용한 예를 보았다. 그래서 v와 V이다. 선택 모드가 되면 다음 작업을 수행할 수가 있다:

- J → 모든 행을 조인한다.
- <(관련, >) → 왼쪽으로(관련, 오른쪽으로) 들여 쓰기.
- = → 자동 들여 쓰기


비주얼로 선택한 모든 행의 끝에 무언가를 추가하기:

- <C-v>
- 원하는 행으로 이동하자 (jjj 혹은 <C-d>/pattern 또는 % 등)
- $ 끝으로 이동
- A 텍스트를 작성하고 ESC 누름.


4.7 분할: :split과 vsplit
중요한 명령은 다음과 같으나 :help split으로 찾아보라.
- :split → 분할(:vsplit은 세로 분할) 창을 만듬.
- <C-w><dir> : hjkl이나 혹은 ← ↓ ↑ → 방향으로 분할을 변경
- <C-w>_ (관련 : <C-w>|) : 분할 크기를 확대(관련, vertical split)

- <C-w>+ (관련 : <C-w>-) : 분할 크기를 증가(관련 : shrink)


5. 결론


이것들은 나가 매일 사용하는 명령의 90%이다. 나는 당신이 하루에 하나 혹은 두개 이상의 새로운 커맨드를 학습하지 않도록 권고한다. 2 ~ 3주 후에는 당신의 손이 vim의 파워를 느끼기 시작할 것이다.

Vim의 학습은 단순한의 암기보다 많은 훈련이 더 중요하다. 운좋게도 vim에는 몇가지 유용한 도구가 훌륭한 문서가 포함되어 있다. 가장 기본적인 커맨드에 익숙해 질때까지 vimtutor를 실행하자. 또한 다음 페이지를 주의깊게 읽어야 한다: :help usr_02.txt

그러면!, 폴더, 레지스터, 플러그인 및 기타 많은 기능들에 대해 배울 것이다. vim 학습은 피아노를 배우는 것처럼 멋진 일이다.
Tags :