윈도우 10 ISO 다운받기 (물론 합법)

최근들어 윈도우 10 ISO가 필요하게 되어 링크를 들러봤더니…

ISO 다운로드 선택 박스는 안뜨고 그저 도구 다운로드만 뜰 것이다.
그렇다. 윈도우 운영체제는 막힌 거다.

하지만 불가능하지는 않다. OS를 속이고 들어가면 되는데,
그냥 user agent 를 바꿔주는 확장을 깔면 해결된다.
크롬이나 불여우는 암거나 확장 깔고 OS 바꿔치기 하고 접속하면 되며, (맥~)
IE나 Edge는 확장은 없고 대신 F12 개발자 도구를 통해 바꿀 수 있다.

내가 쓰는 속이는 user agent 문자열 예제는 아래와 같다.
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36

그러하다. 그리고 접속하면 ISO 다운받을 운영체제 선택박스 화면이 뜰 것이다.
그 뭐냐… 누군가가 선택박스 핵 걸어서 하위 버전 다운받는 것도 통하는 지는 안해봤다. 난 그저 윈도 10만 있으면 되니까.

불법은 아니고 합법이다. 어자피 제품 키는 없다. 정당한 제품 키 없이 쓰면 불법이고, 쓰면 합법인 거다.

composite / 2017년 3월 16일 / Piss Development / 0 Comments

프론트엔드에게 setTimeout 함수는 단순한 함수가 아니다!!!

일단, 지금 내가 좆같이 외부망 막힌 프론트엔드 개발짓거리 하고 있는 관계로 블로그질을 잘 못하겠지만,
이런 일을 자주 겪어 존나 머리가 쌓이기만 하기에 내 메모리 릴리즈 하는 개념으로 글 씨지르겠다.

프론트엔드 개발하다 보면 이런 경우를 겪는다. 특히 화면 변경할때 말이지.
화면을 변경하다 보면 갑자기 스크립트 오류가 나거나, 원하는 화면이 안나올 때가 있다.
이것으로 머리 싸매다가, 안되겠다. 지연시켜서 뿌려야겠다는 생각으로 setTimeout 함수를 쓰면
원하는 화면변경이 이루어진다. 이상할 정도로.
더 웃긴 현싱은, 타임아웃 주기를 0으로 해도 잘된다는 것이다. 이게 대체 어떻게 된 거지?

먼저, 자바스크립트는 싱글 쓰레드라는 것. 아주 질리도록 들었을 것이다. 비동기도.

하지만 잊지 말아야 할 점은 이 싱글 쓰레드가 하필 화면을 표현하는 렌더링 시점에도 블로킹 현상이 일어나는 점을 간과해서는 안된다.
즉, 스크립트 실행중인 시점에 DOM에 어떤 변화가 찾아올 지 우린 예상할 수 없다는 것이다. 왜냐? 싱글 쓰레드로 하나씩만 진행하기 때문에.
그럼 왜 setTimeout 함수는 회피할 수 있을까? 간단하다.
위 그림을 보면 setTimeout 블록으로 등록된 timer 스레드는 그저 다음 실행 시점으로 예약만 하고 이 스레드에 도달해야 실행되기 때문이다.
그렇다면 왜 setTimeout은 분명 1초인데 1초 빨리 실행하거나 1초보다 늦게 실행하기도 하는가?
먼저, node.js 개발해본 시람은 알겠지만 거기는 setTimeout 함수는 없고 process.nextTick 함수를 사용한다. 그렇다.
원리는 비슷하다. 빠르게 tick 하면서 스크립트가 실행된다. 게임이나 영상으로 치자면 프레임 단위에 무슨 이벤트가 일어난다는 것이다.
보통 1 tick 하면 1/1백만 초다. 백만분의 1초. 하지만 setTimeout은 아무리 최소값이라도 4/1000초.
클라이언트 스크립트에서 tick 단위를 허용기엔 가뜩이나 렌더링이 스레드 예약하고 블록거는데 무슨 일이 일어날 지 검증이 안 된 상황.
자, 일단 여김가지 갔으면 이제 setTimeout 함수로 예약한 함수 루틴은 나머지 구문을 실행한 후 실행하는 것을 알 수 있다.
즉, 렌더링에 시간을 벌어주어 렌더링 후 화면 변경에 대한 정보를 불러오고 쓰는 데 정확도를 높일 수 있는 그런 트릭인 것이다.
그런 고로 화면을 변경할 때, 특히 DOM 데이터를 주고받거나 다룰 때 setTimeout 함수는 DOM 렌더링 시간을 벌어주어 원하는 사용자 처리를 도와주는 프론트엔드에게 고마운 함수인 것이다. 감사하며 쓰도록 하자.

참고: Why is setTimeout(fn, 0) sometimes useful?

composite / 2017년 1월 9일 / Piss Development / 1 Comment

C# 7.0의 새로운 기능

이번 .NET Core 출시 이례로 C# ~6.0 기반의 모든 것들을 이제 .NET Core에 집중할 예정이라고 한다.
그리고, Roslyn 컴파일러 덕분에 C# 6.0 문법이 C# 5.0 인 닷넷 환경에서도 지원할 수 있도록 어셈블리를 제공하고 있으니,
아마 구버전 문법 환경에서도 사용할 수 있도록 지원되지 않을까 예측을 할려다 말았다. 굳이…

자, 본문으로 들어가서, 차기 닷넷코어에 탑재될 C# 7.0 언어의 새로운 기능을 Araboza.

Tuple

자바에서 걍 값만 쳐넣는 클래스를 POJO라고 한다. 그리고 닷넷에서는 POCO라고 한다.
대충 이런 식이다.

class PropertyBag
{
    public int Id {get; set;}
    public string Name {get; set;}
}
var myObj = new PropertyBag { Id = 1, Name = "test};

C# 3.0부터 지원해서 여러분들도 자주 써왔을 것이다.
닷넷에서는 이런 놈들을 지칭하는 용어가 튜플이다.

out 인자

잘 쓰지는 않지만 out 인자를 통해 메소드에서 여러 인자를 받아낼 수 있다.

public void GetLatLng(string address, out double lat, out double lng) { ... }

double lat, lng;
GetLatLng(myValues, out lat, out lng);
Console.WriteLine($"Lat: {lat}, Long: {lng}"); 

하지만 가장 큰 문제점이 있다면 바로 async 메소드에 쓸 수가 없다는 것.
그리고 코딩하기 참 불편하다. 패턴 참 개같아 보인다.

Tuple<> 클래스

C# 3.0부터 Tuple 이라는 클래스가 생겼는데, POCO 만들기 귀찮을 때 유용하기도 하다.

public Tuple<int, int> GetLatLng(string address) { ... }

var latLng = GetLatLng("some address");
Console.WriteLine($"Lat: {latLng.Item1}, Long: {latLng.Item2}");

근데… 알다시피 프로퍼티 이름 참… 맘대로 못짓는다. 어쩔 수 없다. 제공 클래스의 한계니까.

POCO

가장 많이 쓰는 패턴이다. Value Object 답게 읽거나 쓸 수 있다.

struct LatLng{ public double Lat; public double Lng;}
public LatLng GetLatLng(string address) { ... }

var ll= GetLatLng("some address");
Console.WriteLine($"Lat: {ll.Lat}, Long: {ll.Lng}"); 

근데 코딩 길이 참 길다. 원래 그렇지 뭐.

Tuple 반환 타입

자, 이제 C# 7.0의 튜플 형식에 주목해보자.
먼저, 2개 이상의 원하는 이름으로 반환 타입을 만들 수 있다.

public (string FirstName, string LastName) GetNames(string! fullName) //형식 뒤에 느낌표가 뭔지는 다음에 설명.
{
  string[] names = fullName.Split(" ", 2);
  return (names[0], names[1]);
}

var name = GetNames("john doe"); 
Console.WriteLine($"Name: {name.FirstName} {name.LastName}");

자, 이렇게 하면 out 변수와 같은 효과를 내면서, 심지어 async 메소드에 대응이 가능하다고 한다. 오예.
원리야 Tuple에 네 변수를 대입하는 방식이니 편하게 써주자.

당연히 인라인도 가능하다.

var ll = new (double lat, double lng) { lat = 0, lng = 0 };

이렇게 하면 li 변수에 당신이 정한 tuple 멤버를 속성으로 사용하여 다룰 수 있다.

레코드 형식

별 거 없다. POCO 클래스 작성하기 간결해지는 효과가 있다. 예를 들면,

class MyPoint
{
    int _x;
    int _y;
    int _z;
    MyPoint(int x, int y, int z){
        this._x = x;
        this._y = y;
        this._z = z;
    }
    public int X {get{ return this._x;}}
    public int Y {get{ return this._y;}}
    public int Z {get{ return this._z;}}
}

C# 7.0부터 아래처럼 짜면 위와 비슷한 클래스가 만들어진다.

class Point(int X, int Y, int Z);

이 때, 알아야 할 점이 있다.

  • 레코드 형식도 상속 “된다”.
  • 레코드 형식은 IEquatable<> 인터페이스에 상속된다. 이 덕분에 같거나 틀린 연산자로 비교 시 레퍼런스 비교가 아닌 멤버 값 비교를 통해 비교가 가능하다.
  • ToString() 메소드는 자동으로 오버라이드 되어 레코드 각 멤버와 값을 나열하게 된다.

패턴 매칭

C# 7.0부터 나온 재밌는 기능이다. 이 기능 때문에 switch 문이 재밌어질 것이다.
먼저 예제를 보자.

class Geometry();
class Triangle(int Width, int Height, int Base) : Geometry;
class Rectangle(int Width, int Height) : Geometry;
class Square(int width) : Geometry;

Geometry g = new Square(5);
switch (g)
{
    case Triangle(int Width, int Height, int Base):
        WriteLine($"{Width} {Height} {Base}");
        break;
    case Rectangle(int Width, int Height):
        WriteLine($"{Width} {Height}");
        break;
    case Square(int Width):
        WriteLine($"{Width}");
        break;
    default:
        WriteLine("<other>");
        break;
}

간단히 얘기하자면, 첫번째로 얘기한 튜플 형식의 산출물인 셈인데,
switch 문을 통해 각 상속 된 클래스와 멤버가 맞는지 비교하여 해당될 때 문을 실행할 수 있다.
예를 들면, 사용자가 있고, 사용자가 개인 사용자, 단체 사용자가 있다고 할 때,
switch 문으로 개인 사용자와 단체 사용자에 따라 다른 형식으로 문을 작성한다고 보면 될 것이다.

Non-nullable 참조 형식

참조 형식은 class로 시작하는 것들이다. 자바야 내장 값 형식 말고 죄다 참조이니 뭐.
어쨌든, 참조 형식은 기본적으로 null 이 가능하다. 이제 불가능하도록 설정할 수 있다.
이런 형식을 제안한 사람이 있는데 이 링크로 들어가면 성지순례할 수 있다.무려 5년 전에 제안한 기능이다.

값(struct) 형식은 기본적으로 null 을 가질 수 없다. 반드시 기본값을 가지게 되어 있다.
하지만 Nullable<> 형식이 생겨 값 형식 뒤에 ? 만 붙이면 null을 가질 수 있다.

int a = 1; // 일반 값 형식
int? b = null; //null을 가질 수 잇는 값 형식

이 문법 덕에 DB나 타언어 연동 시 유연하게 대응이 가능할 것이다.
여기서 주의할 점은 null을 가질 수 있을 뿐 절대 참조 형식이 아니라는 점.

자, 이번엔 참조 형식이다. 참조 형식 중 대표적인 string 형식이 있는데,
non-null 처리 하려면 별도의 처리를 해야 한다. 하지만 이제 아래처럼 하면 된다.

string a = null;
string! b = null;

형식 뒤에 느낌표(!)를 붙이면 null이 불가능한 참조 변수를 만들 수 있다.
목적은 컴파일 타임에서 null이 불가능한 참조 변수를 만드는 데 목적이 있기 때문에
위처럼 코딩하면 컴파일 오류가 난다. 당연히 null 이 아닌 값이나 초기화를 해 줘야 한다.
string 뿐만 아니라 당신이 사용하는 클래스에도 당연히 적용 가능하다.

제네릭도 적용 가능하다.

//이렇게 하면 Dictionary 형식만 non-nullable.
Dictionary<string, List<MyClass>>! myDict;

//이런 식으로 원하는 형식 뒤에 non-nullable 참조를 정의할 수 있다.
Dictionary<string!, List<MyClass!>!>! myDict;

//제네릭과 제네렉 하위 모든 형식에 non-nullable 참조를 원할 경우 형식과 제네릭 사이에 ! 붙이면 된다.
Dictionary!<string, List<MyClass>> myDict;

지역 함수

클래스 멤버인 메소드와는 달리 블록 내에 잠깐 처리하고자 할 경우 사용하는 방법이 나같은 경우 람다식이다. 그렇게 가능하다.
하지만 이런 형식도 한계가 있는데,

  • 제네릭 사용 불가
  • refout 사용 불가능
  • 가변 인자 사용 불가

이를 간결하게 대비할 수 있는 지역 함수 기능을 제공한다.
람다식에서 못한 한계를 여기서 해결할 수 있다.

public int Calculate(int someInput)
{
    int Factorial(int i)
    {
        if (i <= 1)
            return 1;
        return i * Factorial(i - 1);
    }
    var input = someInput + ... // Other calcs

    return Factorial(input);
}

Factorial 이란 함수는 Calculate 메소드 문 내에서만 사용할 수 있다는 특징이 있다.
그 외에는 메소드처럼 정의하고 사용하면 된다.

불멸 형식(Immutable Types)

C#이나 자바나 대표적인 불멸 형식은 string 이다.
불멸 형식은 아래와 같은 장점이 있다.

  • 스레드로부터 안전하다.
  • 코드의 목적이 명확하다.
  • 병렬 처리가 쉽다.
  • 참조가 캐쉬되지 않으며 바뀌지도 않는다.

자, 사용법을 알아보자.
일반적인 POCO 클래스이다.

public class Point
{
    public Point(int x, int y)
    {
        x = x;
        Y = y;
    }

    public int X { get; }
    public int Y { get; }
}

초기화 시 좌표값을 받고 써먹는 클래스이다.
하지만 누군가 setter 넣고 중간에 값을 바꿔치기 하면 원치 않는 결과가 나올 텐데,
class 앞에 immutable 키워드만 넣으면 만사 OK.

public immutable class Point
{
    public Point(int x, int y)
    {
        x = x;
        Y = y;
    }

    public int X { get; }
    public int Y { get; }
}

이렇게 하면, string 처럼 중간에 값이 변조될 가능성이 없어지기 때문에, 인스턴스를 사용하는 동안 참조를 보장받을 수 있다.
즉, 메소드가 중간에 변조할 수 없다는 뜻이다. 처음부터 끝까지 초기화한 형식 그대로 갖다 쓸 수 있다는 것.
게다가 이런 형식에 대비해 유용한 문법이 생겼는데, 기존 인스턴스로부터 값을 바꿔 새 인스턴스로 만들 수 있는 문법이 생겼다.

var a = new Point(2, 5);
var b = a with {X = 1}; // {X = 1, Y = 5}

존나좋군.

언제 이런 문법으로 코딩 가능?

.NET 로드맵에 의하면, 올해 가을에 1.1이 나오는데, 안타깝게도 아직은 이 스펙을 못쓴다. 하지만 아직 이게 다가 아니라고 한다.
이 스펙을 사용할 수 있는 시기가 MSDN에 의하면, 차기 비주얼 스튜디오부터 이 스펙을 사용 가능하다고 알려져 있다. 문제는 비주얼 스튜디오가 언제 나올 지 모른다. 내년에 나오겠지 뭐.
Github Roslyn work list of features 에 소개된 기능 외에 고려하고 있는 기능을 볼 수 있으며, 심지어 참여도 가능하니,
관심이 있으면 주저 말고 영어로 의견을 내놓으면 된다.

근데… 자바는 아직도 1.x인데 2.x 버전이 지구 멸망하기 전까지 나올런지 모르겠다.
여담으로, WCF는 닷넷 코어에 채용이 됐지만, WPF는 계획이 없다고 한다. 그걸 기다리느니 차라리 Electron에 닷넷 붙이는 게 크로스 플랫폼에 효율적일 듯 하다. 아님 자마린으로 모바일 개발 하던가.

참고자료

미안. 죄다 영어다. 한글 자료는 아무리 찾아봐도 없더라. 이 글을 쓴 이유이기도 하다.

C# 7: New Features
New features in C# 7, part 2
Essential .NET – Designing C# 7

composite / 2016년 7월 19일 / Piss Development / 1 Comment

골때리는 자바스크립트는 쓰레기 강좌다.

… 라는 소리를 텀블러에서 들었다. 오예. 꽤 오래전 글이다.
뭐 인정한다. 골때리는 자바스크립트 연재 이유는 내가 잘나서도 아니고
내가 자스 고수라서 나의 수준높은 강좌 맛좀 봐라 이 미개한 코더들이 이런 느낌으로 작성하지도 않았다.

순전히 내가 자스를 배우면서 “아, 이건 정말 흥미롭다. 이런 건 공유해야지” 하면서 정리한 게 골때리는 자바스크립트다.
이 강좌를 먼저 PHPSCHOOL 에서 연재를 했는데,
그때는 내가 자바를 했는대도 불구하고 거기서 꽤 많은 커뮤니티 활동을 해서 거기다 올렸을 뿐이다.
그러니까, 편해서 올린 거라고. 물론 그 글 그대로 여기 블로그로 옮기긴 했지만.

좋다. 왜 오류투성이 강좌인지 따져보자고 하는 이들에게 해명의 시간을 가질 기회를 주기 바란다.

1. 전문용어의 부재

나는 작성 당시 스코프와 클로저, 호이스팅이라는 용어도 모른 채, “아 이러면 이렇게 되는구나” 하면서 하나의 이미지로 패턴을 배워가며 익혔다.
물론 지금은 이들의 용어와 목적, 용도를 알고는 있지만, 보면 아직도 모자른 게 많구나 싶기도 하다.
어쨌든, 감수 없이 팁을 연재했기 때문에 초보자들에게 전달이 잘 되는것으로 목표로 하였으나, 전문가들에게는 아무래도 전문용어 부재는
초보자들에게 오히려 혼란만 가중시킬 것으로 보일 것이다.

2. 고증 오류

그렇다. 내 강좌가 가장 많이 욕먹는 이유가 바로 이 고증 오류이다. “이렇게 돌려봤지만, 정작 이렇게 나오더라” 에서 출발해서 그런가,
아니면 테스트 케이스가 부족했는가, 여러 생각이 필요하지만, 팁에서 상당한 오류가 발견되고, 이를 수정하지 않았다.
물론 다른 팁을 통해 수정을 했지만, 역시 이미 엎질러진 물을 보고 손가락질 하는 건 어쩔 수 없나보다.
물론 수정하지 않은 오류가 있을 것이다. 근데 이미 다들 교정해 줬으니… 내가 낄 틈이 없다.

3. 선동

또한가지 재밌는 의견도 나왔는데, 바로 하나의 패턴만을 추구하도록 선동한다는 의견이었다. 여기서부터 난해해지기 시작한다.
사실 이건 “문과”적으로 따지면 한도끝도 없는 해명이 될 것이다. 왜냐면 기본적으로 내가 하는 패턴을 강요하지 않았기 때문에.
물론 몇몇 팁 중에 “그냥 따라해” 라던가 “걍 내가 하는 대로 해” 라는 문구가 들어간 강좌도 있지만,
그건 “웹 표준”에 근거하기 때문인데 그 강좌는 골때리는 자바스크립트 강좌와 무관한 강좌다.
어쨌든, 선동이라면… 이건 분명 오해다. 2메가 오해처럼 들릴 지 모르겠지만 나에게 이건 상당히 엉뚱하게 받아들일 수밖에 없다.
내 패턴에 예제를 들었을 뿐이지, 내가 뭘 알고 내 패턴을 요구하는지, 게다가 그런 문구를 적은 적도 없고, 의도하지도 않았다.

마치며

골때리는 자바스크립트는 오래된 강좌다. 그리고 초보자를 위한 강좌다. 자바스크립트 겪으면서 이건 왜이러지 하는 부분을 긁어주려 만든 강좌였다.
지금 보면 ECMA 2016도 나오는 판에 이제 점점 무쓸모 강좌가 됐는데, 제작년에 오류 투성이라는 의견에 대해 2년만에 이를 해명하다니…
나란 놈 참 한심한 놈이다. ㅋㅋ…

composite / 2016년 7월 13일 / Dog's bullshit, Piss Development / 2 Comments

뛰어난 개발자를 찾는가? 오픈소스 개발자가 있다.

비개발자나 개발 경험이 있는 인사들이 착각하는 게 있다.
내가 여러 클라 만나 개발하면서 제일 답답하고 일하기 싫은 유형 중 하나인데,
바로 오픈소스 개발자를 보안에 안좋은 개발자로 본다는 것이다.
그들이 주장하는 이유는 이러하다.

오픈소스 개발자는 뭐든 오픈하기 때문에 우리 회사의 민감한 산출물도 공개할 것이다.

하지만 증거도, 물증도 없는 추측성 개소리에 불과하다.
특히 그렇다가 아니고 그럴 것이다그렇다더라 로 끝나는 게 그들이 주장하는 이유의 특징이다.

좋아. 그럼 오픈소스를 많이 공개하는 다음카카오나 쿠팡, 네이버 등에게 한번 먼저 물어보고 와라.
만약 저 이유가 사실이라면, 나는 이미 개발 일 못했을 테니까. 집에서 밤이나 까고 앉아있겠지.

자, 이제 주목.
소프트웨어는 자산인가? 그렇다. 그렇다면 소스코드도 자산인가? 당연하다.
그렇다면 이런 자산을 보호할 줄 아는 개발자를 찾는가? 그렇다면 오픈소스 경험이 있는 개발자를 추천한다.
추천하는 이유는 이렇다.

개발에 있어서 공과 사를 구분하는 능력이 뛰어나다.

그들은 아무리 자기가 만든 산출물이라도, 그 내용이 회사에 중요한 정보가 있는지, 없는지 파악할 수 있다.
물론 처음에는 이를 구분할 수 있도록 선배나 상사가 도와주지만, 자신의 능력을 뽐내려면, 보안 문제도 피할 수 없다.
하나의 사례로, 개발자라면 천국으로 유명한 회사, 제니퍼가 있다.
제니퍼는 로깅분석 솔루션을 정부에 납품하고 세계를 넘나들 정도로 기술경쟁력이 뛰어난 회사로 알려져 있다.
그들은 자체 솔루션인 제니퍼의 파기 버전을 만들면서, 그들이 만든 UI 컴포넌트를 아예 무료로 공개했다.
아니, 대체 그들은 아무리 UI 컴포넌트라도 그들의 자산일텐데 개발자가 미친거 아니냐고 생각할 텐데, 만약 그랬으면 위에서 짤랐지.
제니퍼의 핵심 기술은 따로 있다. 당연히 미치지 않고서야 공개하지 않는 건 당연한 이치.
또한, UI 컴포넌트 자체에는 회사의 보안 내용이 없는 것으로 판단했을 것이다. 그리고 이들의 소스를 공개해 버렸다.
그리고 공개하면서 사용자들의 참여를 기다린다, 개선의 여지를 회사 뿐 만 아니라 사용자에게도 기회를 부여하려 회사의 솔루션을 강화하는 취지이기도 하다.
이처럼 비즈니스적 이득이 있는 전략인 것이다. 누가 주체가 되어 오픈했는지는 내가 저기 근무 안해봐서 모르겠지만,
개발자가 개발하고 임직원들 간의 의견 수렴을 통해 충분히 공개해도 무방하기에 오픈한 것이다.
이게 주장하는 바와 다르다고 생각한다면, 당신은 여태까지 오픈소스 개발자를 보안에 안좋은 개발자로 착각해서 그렇다.
이를 경험한 개발자는, 회사에서 자신의 능력을 보여줄 때 필요한 것과 해선 안되는 것의 차이를 잘 안다.
오픈소스는 그저 개발자들의 취미생활이 아니라는 것이다. 그렇기에, 이를 경험한 개발자는 공과 사가를 구분하는 능력이 있다.
굳이 제니퍼 사례에서 제니퍼가 공개하지 말아야 할 것이 있다면, 바로 UI 컴포넌트를 어떻게 제니퍼 솔루션에 활용했냐일 것이다.

오픈소스와 상용 솔루션 사이의 좋은 조언자이다.

만약 회사 솔루션이나 제품을 만들 때, 무엇을 활용하여 생산성을 극대화 하느냐에 가장 고민이 많이 쏠려 있을 것이다.
오픈소스와 상용 솔루션, 이 둘을 잘 알고 활용한다면, 개발 생산성에 날개를 달아줄 것이다.

  • 오픈소스
    • 장점: 일부 AGPL 및 GPL 소스를 제외하면 무료로 자유롭게 사용 가능하고, 확장이 필요할 경우 수정하여 해결 가능하다.
    • 단점: 일부 소스는 사후관리를 지원하지 않으며, 일부 검증된 소스나 업체 외에는 안정성을 보장받기 힘들고, 문제 발생 시 알아서 소스를 뜯어 문제를 해결해야 할 수 있다.
  • 상용
    • 장점: 해당 개발 업체를 통해 안정성을 보장받을 수 있고, 검증되어 안정된 제품이나 솔루션 개발이 가능하다.
    • 단점: 비용이 발생하며, 해당 솔루션에 한계 발생 시 대응할 방법이 없다. (필요한 기능이 지원이 안 될 수 있다.)

오픈소스 개발자가 이를 잘 구분하는 이유는 간단하다. 자신이 다른 오픈소스를 경험하면서 사용 가능한지 미리 알고 있거나, 아니면 알 수 있도록 도와주기 때문이다.
예를 들면, UI 컴포넌트가 필요할 때, 오픈소스도 있고 상용도 있다. 만약 해당 소스가 특정 검증 기업의 지원을 받거나, 많은 커뮤니티가 활성화되어 빠른 검증이 가능하다면 주저없이 오픈소스를 선택하여 비용 절약에 도움을 줄 수 있고, 아니면 미션 크리티컬에 대응 가능성이 불투명한 경우 가능한 비용을 들여서라도 안정된 상용 솔루션을 제안할 수 있다.
만약 비용 한계가 발생하여 오픈소스를 사용해야 하는 상황이 발생 시, 적절한 용도의 오픈소스를 찾도록 도와줄 것이고,
비용이 넉넉하여 상용 써도 가능한 상황이라면, 무작정 한계 가능성이 있는 상용을 사용하는 것보다 더 나은 오픈소스를 찾아 비용 조절을 할 수 있도록 제안할 수 있다.
명심하라. 정답은 없다. 최종 결정은 결정권자가 내려야 한다. 그리고 오픈소스 개발자라고 모든 오픈소스를 섭렵할 수 있는 건 아니다.
오픈소스 양은 너무나 방대하고, 같은 기능의 오픈소스가 수십 수백 많으면 수천개가 있으며, 이 중에 적당한 솔루션을 찾는 일은 엄청 버거운 일이다.
오픈소스 개발자는 이런 상황에 숙련된 인물이지 만능은 아니기 때문에 당신도 잘 고려해야 한다는 점 잊지 말길 바란다.

자, 이 외에도 나열하고자 하는 이유는 많지만, 시간 관계상 여기까지 적겠다.
인터넷 전문기업은 오픈소스 경험자를 선호한다. 내가 말하지 않는 잠재능력과 상황판단 능력은 오픈소스에 참여한 적 없는 개발자보다는 월등히 뛰어남을 알고 있기 때문이다.
물론 실수로 개발자가 보안에 민감한 자료까지 오픈하는 경우는 있을 수 있다. 드물지만. 그 개발자를 문책하기 전에 먼저 조치를 하면 된다. 최대한 빨리.
만약 그런 개발자가 있다면, 상황에 따라 알아서 회사 방침이나 사칙에 따라 판단해라. 거기까진 내가 뭐라 할 수 없다.

개발자 여러분들도 오픈소스를 많이 경험해야 한다. 오픈소스는 그저 무료로 활용하는 도구에 불과하지 않는다. 오픈소스 개발자는 그걸 안다.
그런 상황을 인지하고 숙달하며, 회사에 필요한 기술과 솔루션을 제안받을 때, 이 능력이 빛을 발하기 때문이다.

결정적으로, 길안내를 하는 표지판을 만든다고 할 때, 오픈소스는 표지판을 만드는 방법을 공개할 뿐, 표지판 자체가 아니라는 점 명심하라.

composite / 2016년 7월 7일 / Dog's bullshit, Piss Development / 0 Comments

.NET Core RC2 to RTM 마이그레이션

존나 쉽다. 걍 날 따라해라. 공통사항이다.

project.json 파일 아래 부분 수정

{ //...
    "Microsoft.NETCore.App": "1.0.0"
}

위 부분을 아래처럼 수정.

{ //...
    "Microsoft.NETCore.App": {
        "version": "1.0.0",
        "type": "platform"
    },
}

(만약 위처럼 안써있는 사용자 한정.)

그리고 다시 project.json 에서 모든 패키지 버전을 1.0.0-rc2-final 에서 1.0.0 로 수정.
대상: Microsoft.AspNetCore.*Microsoft.Extensions.* 여튼 저런 식으로 써있는 패키지 다.

비주얼 스튜디오 2015 사용자라면 닥치고 아래 절차에 따르면 된다.

  • Update 3 로 업데이트.
  • Tools Preview 2 설치. (뻘짓만 안하면 이전버전 언인스톨 안해도 됨)
  • .NET Core RC2 프로젝트 연다.
  • 프로젝트 컨텍스트 메뉴에서 Nuget 패키지 관리… 클릭.
  • 업데이트 탭 클릭.
  • 닥치고 모두 체크하고 업데이트 버튼 클릭.
  • 안심하고 화장실 갔다와.

끗. 이제 dotnet run 치고 ENTER 치면 언제 한듯 안한듯 깔끔하게 앱이 실행될 것이다.

composite / 2016년 6월 28일 / Piss Development / 0 Comments

.NET Core 1.0 RC2 to 1.0 RTM Migration

yeah, that’s quiet simple.

project.json

{ //...
    "Microsoft.NETCore.App": "1.0.0"
}

to,

{ //...
    "Microsoft.NETCore.App": {
        "version": "1.0.0",
        "type": "platform"
    },
}

and, change all ASP.NET and Core package version 1.0.0-rc2-final to 1.0.0.
affects: Microsoft.AspNetCore.* and Microsoft.Extensions.* for plain ASP.NET webapps or console app.

If you’re Visual Studio 2015 user, following this step:

  • Update to Update 3.
  • Install Tools Preview 2 (No uninstall required if not tuned.)
  • Open any .NET Core RC2 Project.
  • Click Manage NuGet packges... on project context menu.
  • click Updates Tab.
  • Check all and click Update.
  • have a tea time.

that’s all. just dotnet run and ENTER. hooray~

composite / 2016년 6월 28일 / Piss Development / 0 Comments

.NET Core RC2 Tools preview 1 Offline Installer

전에 비주얼 스튜디오 도구를 RC1에서 R2로 올리는 삽질기를 올렸었다.
그리고 RC2는 치사하게 오프라인 설치 파일을 제공하지 않는 것도 알려줬었다.

하지만 오프라인 설치하도록 하는 방법은 있다. 다행히도.
출처는 여기니 영어 좀 알면 정확한 사용법을 익히도록 한다.
아님 걍 날 따라해.

준비물

일반 사용자(또는 귀차니어)
* 비주얼 스튜디오 업데이트 2 (Express 제외한 모든 에디션)
* DotNetCore.1.0.0.RC2-VS2015Tools.Preview1.exe

고급 사용자
* 7집이나 반디집 등 CAB 파일 보거나 풀 수 있는 압축 프로그램 아무거나.

일반 사용자

  1. 받으라는 준비물을 받았으면 적당한 폴더에 옮긴다. 아님 말고.
  2. 설치 파일이 있는 폴더에 packages 폴더를 만든다.
  3. 설치 파일 목록이 든 텍스트 파일을 받아 packages 폴더에 놓는다.
  4. 목록을 urls.txt 등 편한 파일로 저장한다.
  5. packages 폴더에 powershell Get-Content urls.txt | ForEach-Object {Invoke-WebRequest $_ -OutFile $(Split-Path $_ -Leaf)} 스크립트 실행.
  6. 다 받았으면 압축하여 배포하던 공유하던 니맘대로 한다. 참고로 전체 크기는 거의 500MB에 육박한다.

고급 사용자

일반 사용자 2번까지 한 다음 아래 절차를 따른다.

  1. 압축 프로그램으로 설치 파일을 연다.
  2. 0이라는 파일이 있는데 실제 다운로드 설치파일 목록이 있는 XML 파일이다. 그걸 연다.
  3. 아무 에디터 열고 “찾기” 한 다음 정규식 체크하고 DownloadUrl="(.*?)" 입력한다. (Subline Text나 Atom 추천)
  4. 모두 선택 후 거기 나온 모든 URL을 추출한다. (선택하지 말고 다 받아야 한다. 한개라도 빠지면 온라인으로 받으려 나댈 것이다.)
  5. URL 목록을 만들었으면 일반 사용자 4번부터 따르면 된다.

이렇게 하고 압축하여 인터넷이 막힌 환경에서도 ASP.NET Core RC2 개발환경을 설치할 수는 있다.
근데… 문제는 ASP.NET Core 개발하려면 아직 인터넷 없이는 힘들긴 하지만,
나처럼 설치 더럽게 안되는 환경에서는 더없이 좋은 환경이 될 것이다.

아, 사족으로 나는 이것도 실패에서 결국 Github Issue 올렸다. 시발.

2016-06-24 업데이트:
Issue 원인은 DRM으로 인한 리소스 접근 실패. 문서보안이 화근이었다.
결국 포기. 다른컴 테스트해보니 존나게 잘 깔림. 시발 안해.

composite / 2016년 6월 23일 / Piss Development / 0 Comments

[딥빡] ASP.NET Core RC1 -> RC2 Tools

ASP.NET Core RC2가 나왔고, 비주얼 스튜디오 도구가 나왔다.
하지만 언제나 그랬듯이 Beta 에서 RC1 로 순탄하게 업그레이드 될 리 없었는데,
그때는 걍 베타 삭제하고 RC1 설치하면 바로 해결됐다.
하지만 RC1 지우려고 했는데 이번엔 뜬금없이 설치 파일을 요구한다.
설치 파일명은 AspNet5.ENU.RC1_Update1_KB3137909.exe 이다.
만약 취소하면 삭제가 취소된다.

마소 이 개생퀴들아!

RC2 나오자마자 파일 지워버렸잖아!

이 파일 어떻게 구해 썅것들아!!!!!

그래서 구글링 했는데 다행히도 쉽게 찾을 수 있었다.
필요한 사람 다운받아라. 그리고 설치하지 마라. 안될 거다.
AspNet5.ENU.RC1_Update1_KB3137909.exe
그리고 삭제 시 파일 요구할때 이 파일을 선택하면 속 시원히 지워질 것이다.

그리고 RC2 설치하면 된다. 속 시원히 설치될 것이다.

만약 파이프니 알 수 없는 오류니 안되는 경우가 있는데,
일단 안타깝게도 오프라인 설치가를 제공하지 않고 있다.
온라인 설치 파일을 다운받고,
다운 폴더를 콘솔 창에 열어
DotNetCore.1.0.0.RC2-VS2015Tools.Preview1.exe /layout
치면 원만하게 설치가 완료된다.
그리고 깔아주시면 된다.
그리고 어디 백업하던지 해서 남겨라. RTM 나오면 삭제할 때 필요하게 될 지도 모른다.

참고(영문)
ASP.NET 5 RC 1 Update 1 Offline Installer

추가 업데이트

나처럼 재수없게 새 프로젝트 생성하거나 웹 프로젝트가 안열릴때
RC1 삭제 시 웹개발 도구가 덩덜아 날아간 경우가 있다.
에휴… 프로그램 및 기능에서 비주얼 스튜디오 변경 클릭 후 웹 개발 도구 체크해주자.

composite / 2016년 5월 27일 / Piss Development / 0 Comments

From node-webkit to Electron 1.0

이 글은 Github 소속 Electron의 메인 개발자인 Cheng Zhao(@zcbenz)의 기고글을 번역한 글이다.
원문: From node-webkit to Electron 1.0
시간에 쫓기고 작성하다 보니 오역이 있을 수 있다. 오역 교정 환영한다.

아니 프리랜서가 시간관리도 못하고 왜 시간에 쫓겨다녀?

한국 프리랜서는 용병이 아니라 그냥 사업자를 빙자한 근로자거든요 ㅋ


이 글을 통해 내가 node-webkit를 재구성하다가 Electron 프로젝트를 시작하게 된 내역을 기고한다. 내역을 좋아하는 애들을 위해 커밋 내역과 관련 링크를 달아주었다.

DOM에서 node.js 모듈 불러오기

모든 것의 시작은 2011년 @rogerwang 이 만든 마법의 모듈 node-webkit이었다.
이 node.js 모듈은 웹킷으로 하나의 브라우저 창을 띄워주는 것도 모자라, node.js 모듈까지 사용하는 마술까지 부렸다.

Node.js 코드 단은 이랬고,

var nwebkit = require('nwebkit')
nwebkit.init({'url' : 'index.html'}, function () {
  nwebkit.context.runScript('')
})

그리고 index.html 내용은 이랬다.

<html><body>
<p id="output"></p>
<script>
require('fs').readdir('.', function (err, files) {
  var result = ''
  files.forEach(function (filename) { result += filename + '<br/>' } )
  document.getElementById('output').innerHTML = result
});
</script>
</body></html>

이 데모로는 아직 시판하기엔 부족한 점이 많았지만, 충분히 성공 가능성이 있었다.

크롬 임베디드 엔진을 사용하다.

그 당시 node-webkit 에서 가장 큰 문제였던 게 있는데, 웹킷 라이브러리 기능을 리눅스 외에 사용하기엔 너무나 버거웠다.
그래서 @rogerwang 은 이 모듈을 웹킷에서 크로미움을 애플리케이션에 넣는 인터페이스를 제공하는 크롬 임베디드 프레임워크로 바꿔 해결했다.

당신은 그 CEF를 사용하여 개발한 node-webkit 코드를 볼 수 있다. node.js 비동기 기능을 수행하도록 만들기 위해, 거기에는 크로미움 메시지를 node.js 입출력 라이브러리인 libuv로 대체하는 패치가 있었다. 그러나 이제 그 패치는 더이상 찾을 수 없었다. 왜냐하면 NW.js 의 Chromium fork 저장소가 이미 오래전에 rebase 해버렸기 때문에. 이제 그 당시 커밋 내역으로 돌아갈 수 없게 됐다.

인턴으로 취직

당신은 @rogerwang 오랫동안 오픈 소스를 지원했던 인텔에 일하고 있다는 사실을 알고 있는가? 놀랍게도 인텔이 오픈소스를 위한 인턴을 구했다. 이보다 더 좋은 인턴쉽이 있었던가?

Intel OTC

2012년 여름, 나는 한참 졸업을 앞둔 대학생이었을 때 여름 인턴쉽을 찾으러 다녔다. 그 때 바로 인텔의 구인란이 눈에 보였는데, 인텔은 node.js의 오픈소스 프로젝트 node-webkit 개발자가 필요하다고 했다. 나는 이때다 싶어서 지원했고 운좋게 붙었다.

그리하여 나는 그 node-webkit 를 개발하기 시작했다.

컨텐트 쉘

첫번째로 내가 했던 업무는 node-webkit의 CEF 브랜치 개선이었다. 그리고 개발하면서 정말 어렵게 해냈다.
node.js가 V8 API를 직접 호출하면서 CEF는 크로미움의 컨텐트 모듈을 입히는 자체 API를 연동한다.
당신이 크로미움과 node.js를 연동하고 싶다면 중간에 CEF를 엮이지 않게 달아야 할 것이다.

그래서 기존 코드를 향상시키는 대신 아예 컨텐트 쉘을 재구성하는 쪽을 택했다. 크로미움을 최소한으로 사용한 가벼운 브라우저를 구현하기 위해.

결과는 꽤 좋았고 node.js 통합이 가능한 작은 브라우저를 획득했다. 그리고 난 그 node-webkit 0.2.1 버전으로 릴리스를 배포했다.

node-webkit를 프레임워크로

node-webkit는 node.js 모듈이기 이전 독립적인 브라우저였었다. 왜 여태까지 이 프레임워크로 HTML과 자바스크립트로 데스크탑 앱을 만들지 않았지? 나는 그 때 몇 개월간 그 아이디어를 행동에 옮겼다.

먼저 나는 node-webkit의 패키징 시스템을 추가했다. 아이디어는 게임 프레임워크인 LÖVE framework 를 슬쩍했다. 그 아이디어는 앱을 ZIP 아카이브로 만들고 node-webkit 실행 파일을 합치면, node-webkit 실행 시 그 아카이브를 풀고 아카이브에 포함된 앱을 실행하는 식이었다.

Packaging node-webkit

몇가지 구현 항목이 있다면, package.json 에 윈도우 속성을 넣거나, DOM 요소 확장, 브라우저 보안 모델 삭제, DOM 요소에 네이티브 파일시스템 도입, 그리고 끝없는 버그 수정 등이다.

한가지 재밌는게 가장 어려운 도전이 있다면 아무래도 node.js 네이티브 모듈 도입이었다. 나는 V8에 OpenSSL을 도입하기 위해 따로 기호(Symbols)를 추가해 크로미움에 패치하고, NSS와 OpenSSL 사이에 충돌이 일어나는 node.js 기호도 수정해 패치했다. 이렇게 윈도우용 원시 코드 node.lib 커스텀 패치를 제공하여 node-webkit에 네이티브 모듈이 돌아가도록 했다.

이리하여 node-webkit v0.2.5 배포 후, 왠지 안정된 느낌을 받았다.

자체 API 추가

이번엔 API 제공하는 데 DOM을 여전히 격리되고 있고, DOM 제공이 너무 제한적인 부분인 현실에 내 생각을 말해본다.
예를 들면 네이티브 메뉴와 여타 텍스트가 들어간 메시지박스 등.

그때 나는 자체 API를 제공하는 제공할 수 있는 걸 생각해 냈다. 바로 require('nw.gui') 같은 빌트인 모듈. NW.js 써봤다면 알 것이다. 그때 나는 메뉴를 생성하거나, 트레이, 메시지 창 등을 API에 넣었다. 지금 NW.js의 원형인 셈이다.

내가 새 릴리스를 배포할 때마다 이런 아이디어를 유지했고, node-webkit v0.3.6 버전으로 피날레를 장식했다.

다른 GUI 프레임워크와는 달리 크로미움의 특별한 점 하나가 있는데, 바로 멀티 프로세스 아키텍쳐라는 점이다. 크로미움 브라우저는 웹 페이지를 실행하고 GUI를 띄우면서 응답해야 하기에 웹 페이지에 GUI 모듈 제공은 너무나 힘들었다.

이렇게 해서 웹 페이지 내에 브라우저 처리를 하기 위한 내 첫번째 시도는 이랬다.
먼저 크로미움을 싱글 프로세스로 돌린다. 허나 이건 너무나도 불안정하게 돌아간다.
이번엔 그냥 네이티브 GUI API를 렌더러 프로세스에 호출하도록 해봤다.
하지만 몇몇 플랫폼에서 GUI 요소와 프로세스를 직접 핸들링할 수가 없었다.
그래서 찾은 마지막 방법은 IPC 메시지를 통해 GUI 모듈을 node-webkit에 입혔다.
이렇게 해서 렌더러 프로세스 중에도 상시 행동이 가능했고,
브라우저 프로세스 간이나 주어진 일을 완료하면 메시지를 보낼 수 있게 됐다.

node-webkit 홍보

node-webkit 같은 프레임워크는 사용자가 가장 중요하다. 많은 사용자를 가지고 만드는 데 있어서 가장 중요한 것들도.

그래서 내가 node-webkit를 개발하는 동안 최대한 홍보도 해왔다. node.js 메일링 리스트에 소개글도 올렸고, 답글도 달아줬다.
node-webkit 게시들을 달며 node-webkit 발표도 했고, node-webkit 샘플 앱도 제작했다.
이렇게 나는 전 세계에 내 힘으로 node-webkit를 알리는 계기를 만들었다.

그리고 node-webkit 개발을 중단하기 전에 Github 별을 천여개 씩이나 받았다. Github에 상위 C++ 프로젝트 10위 안에도 들었다.

첫 사용자

내게 node-webkit 첫 사용자는 정말 중요한 순간이었다. @ibdknoxLight Table editor 을 node-webkit 를 통한 웹 기술로 다시 탄생시켰다. 이후 많은 이들이 node-webkit 에 주목받고 많은 도움이 들어왔다. 이렇게 기쁜 순간을 만들어준 @ibdknox 에게 감사의 말을 전한다.

그 다음 해에 Light Table는 node-webkit 에서 Electron 으로 자리를 옮겼다. 왠지 오랜 친구가 돌아온 것 같았다.

GitHub으로 이동

어느날 Github 에서 비밀리에 Atom 에디터를 시작하면서, @nathansobo 가 node.js로 데스크탑 앱을 개발하는 사람을 구하고 있었다.
나는 Atom을 node-webkit에 마이그레이션하기 위해 필요할 때마다 node-webkit를 개선하는 조건으로 그와 계약했다.

이렇게 반년동안 node-webkit를 개발하다가 인텔 인턴쉽은 이렇게 끝났다. 바로 나는 Github 고객지원부로 일하기 시작했다. 그리고 동시에 node-webkit 개발을 중지하고 뒷일은 @rogerwang 이 모두 맡게 됐다.

Contribution Graph

왜 이렇게 뜨거운 감자인 node-webkit 개발을 중단했을까? 어자피 내가 Github으로 이동하는데 전혀 영향도 없었고, 누가 프로젝트를 운영하는데 나는 상관이 없으니까.

아시다시피, 난 인텔에서 다른 사람의 프로젝트를 진행하고, 프로젝트의 결정권을 가질 수도 없었다. 아무렴 어떤가.
그냥 난 누구의 방해도 없이 node-webkit을 재구성할 수 있고 기능을 추가하면서 장난감 조립하듯이 일하는 게 좋았으니까.
어느날 node-webkit 오픈 소스 규모 커지기 시작했고 말 나오기 무섭게 나의 node-webkit의 권한은 상실됐다.
새 버전을 배포하는 데 있어서 책임이 상급 엔지니어에게 이관되어
내가 일할 수 있는 범위가 사실상 줄어들었고, 내가 좋아하는 기능을 넣을 수 없었다.

비난할 이유가 없다. 인텔 말고도 다른 회사도 그러니. 하지만 단도직입적으로, 더이상 참을 수 없었다.

더 나은 데스크탑 프레임워크 제작

내가 Atom 개발에 참여했을 때, Atom은 CEF에 파일시스템을 운영하기 위한 자바스크립트 바인딩으로 이루어져 있었다. 이게 Atom이 node-webkit로 마이그레이션한 계기가 됐지만, node-webkit가 그때당시 결함이 많다 보니 앞길이 순탄치 않았다.

그래서 난 결국 자체 네이티브 쉘을 만들어 해결하기로 했다. 새로운 쉘은 node-webkit를 개선하는 대신 몇가지 근본적 구조를 바꾸는 방향으로 재구성했다.

이리하여 이 쉘에게 atom-shell 이라고 이름 지었다.

node-webkit 에서 Electron 1.0 까지

그 이후 Electron과 NW.js 에 무슨 일이 일어났는지 내역을 정리했다. Atom과 Atom-shell 은 오픈 소스로 배포했고 그 atom-shell은 Electron으로 개명했고, node-webkit는 NW.js 로 이름을 바꿨다.

그리고 저번 주말에 드디어 Electron 1.0 을 배포했다.

Contribution Graph

Electron은 NW.js의 파생인가?

아마 내가 받은 질문 중 가장 많이 받은 질문이고, 내가 이 글을 쓴 이유이기도 하다. 기술적으로는 Electron은 node-webkit 0.3.6을 재구성했다. 내가 마지막으로 배포한 버전이고 이걸 끝으로 node-webkit 개발을 중단했으니. 그러고 보니 Electron은 원래 node-webkit와 아주 다른 노선을 밟았다.

그러니까 재대로 얘기 좀 하자면, NW.js는 내가 node-webkit 개발한 걸로 시작했고, Electron은 내가 다시한번 node-webkit에 파고든 작품이다.


복터진 개발자네. 군기잡힌 인턴 개발자에서 Electon 메인 개발자가 되기까지…

composite / 2016년 5월 25일 / Piss Development, Waldo Translation / 2 Comments

1 2 3 5