Windows Nano Server 는 이제 안녕.

2016년 5월 나노 서버 라이선스 FAQ

14. How do I license Nano Server?
Nano Server is a deployment option within Windows Server 2016. It is included as part of the licensing of the edition from which it is deployed. Further specifics on Nano licensing will be shared in the future.

즉, 에디션 포함. 끝. 하지만 심상치 않은 “그 외 조건은 다음에 공유 드리겠습니다.”

그리고 본성을 드러낸 나노 서버 라이선스 모델.

Windows Server 2016 new Current Branch for Business servicing option

Software Assurance is also required to deploy and operate Nano Server in production.

“나노 서버를 실서비스 하려면 ‘소프트웨어 보험’ 라이선스가 필요하다.”

복잡한 MS 라이선스, 이것만은 알아두자

라이선스가 해당 SW 버전에 대한 영구적 소유권이라면, SA는 SW 버전 업데이트 권한으로 보면 된다.

먼저, MS가 공식 블로그에 밝힌 내용에 따르면, 나노 서버는 비즈니스용 현 브랜치(Current Branch for Business, CBB)로 서비스를 한다. 이 브랜치를 사용할 수 있는 소프트웨어는 윈도우 10 프로, 엔터, 에듀 버전이다. 엔터 및 에듀는 지연 서비스 랜치(Long Term Servicing Branch, LTSB) 로 서비스한다. 이는 모든 윈도우 서버 2016에서도 적용된다. 나노만 빼고. 윈도우 서버는 윈도우 10과 달리 업데이트 브랜치 모델을 선택할 수 없이 강제 적용된다.
윈도우 2016 서버의 경우 SA는 선택사항이다. 있어도 되고 없어도 된다. 단, SA는 대신 차기 메이저 업데이트나 소프트웨어 업그레이드, 기술 지원이 필요하여 적용코자 한다면 반드시 유지해야 하는 골치아픈 라이선스 모델이다.
한국의 경우 서버 호스팅이나 클라우드 등 플랫폼 서비스를 하지 않고서야 대체적으로 SA까지 가입하지 않을 것이다.
윈도우 나노 서버는 엄밀히 말하면 SA는 선택사항이다. 단, 이는 실서비스를 하지 않는 범위 내에서만 인정된다. SA 없이 나노 서버로 실서비스를 한다면, 라이선스 위반 사유가 되는 것이다.
이리하여, 중소기업은 2016 나오면 여태까지 그래왔듯이 그냥 파운데이션이나 스탠다드만 딸~랑 써야 한다. 나노 서버로 서비스는 커녕 배포는 꿈도 못꾸는 것이다. 비슷한 서비스 하려면 도커 써야지 뭐.

윈도우 서버 나노는 애져에서 어떤 형식으로 나타날 지는 지켜봐야 알겠지만, 윈도우 나노 서버로 열광하던 내 자신이 후회된다. 끗.
이리하여 ASP.NET Core는 리눅스에 도커는 선택사항으로 돌려야 할 것이다. 윈도우 라이선스는 참 살인적이라 느낀다. 그리고 나노 서버를 통해 잔인하다고 느끼기까지 했다.

composite / 2016년 9월 26일 / Piss Development / 0 Comments

[Java vs .NET] void

Java

void 라는 타입이 있다.
심지어는 Void 클래스까지 있다. java.lang.Void 로.
안타깝게도 Void 클래스를 통해 상속 불가능하며, constructorprivate 라 접근 불가능하다.
그럼 자바는 왜 void를 타입으로 만들었냐, 바로 리플렉션 때문이다.

public class Test {
 public static void main(String[] args) throws SecurityException, NoSuchMethodException {
  Class c1 = Test1.class.getMethod("Testt",null).getReturnType();
  System.out.println(c1 == Void.TYPE);
  System.out.println(c1 == Void.class);
 }
}

class Test1{
 public void Testt(){}
}

여기서 눈여겨볼 부분이 바로 getMethod 에서 메소드 정보를 불러온 다음 getReturnType 메소드를 호출하는데,
만약 void가 키워드로 끝났을 경우 얘가 void인지 아닌지 판가름하기 어려워진다.
이런 디자인으로 인해 자바에서는 Void라는 클래스를 만들었다.
그럼 void는 원시 타입인가? 맞다. 단지 다른 원시 타입처럼 변수 등으로 타입 선언이 안된다는 것 뿐이다. (컴파일러가 막는다)
근데 제네릭은 웃기게 먹힌다. 즉, Future<Void> 가 먹혀서 void 람다식을 쓸 수 있다는 것이다. 오 시발…

.NET

.NET Framework에서도 voidSystem.Void 구조체의 별칭으로, 엄밀히 말하자면 타입은 맞다.
하지만, 자바와는 달리 제네릭으로도조차 못쓴다. MSDN에서는 Void 구조체를 아래와 같이 설명한다.

The Void structure is used in the System.Reflection namespace, but is rarely useful in a typical application. The Void structure has no members other than the ones all types inherit from the Object class.

이 구조체는 리플렉션용 구조체라는 것이다. 그 외에는 쓸 곳도 없고. 자바와 용도는 다를 게 없다.
그렇다면 void 메소드의 리턴타입을 어떻게 가져오나, 자바와 같이 리플렉션을 사용해 보겠다.

public class Test {
 public static void Main(string[] args) {
  Type c1 = typeof(Test1).GetMethod("Testt").ReturnType;
  Console.WriteLine(c1 == typeof(void));
  //Console.WriteLine(c1 == typeof(System.Void)); //CS0673 오류
 }
}

class Test1{
 public void Testt(){}
}

자바와 비슷하다.

근데 희한하게 typeof(System.Void) 식이 안먹힌다. 자바에서 Void.class 식으로 타입 가져올 수 있다는 것과 대조적이다.
게다가 자바와 달리 제네릭을 못쓴다. 이렇게 막힌 이유는 ECMA 335 표준에 따르기 때문인데,
Partition II, Section 9.4 에서 제네릭에서 사용하지 말하야 할 유형을 아래와 같이 기술했다.

  • 참조형 형식 (예: System.Generic.Collection.List 1<string&> 이렇게 하면 안 됨.)
  • 값 형식 중 필드에 CIL 평가 영역(어셈블리 상 평가식)을 가리키는 유형 (예:List<System.RuntimeArgumentHandle>)
  • void (예: List<System.Void> 이렇게 하면 안 됨.)

즉, 이 표준으로 인해 컴파일러에서 Void 구조체 사용을 아예 막은 것이다. 물론 자바도 닷넷에 비해 느슨하지만 막힌 건 마찬가지이다.
만약 List<System.Void> 이런 식으로 제네릭이나 할당 식으로 사용하려 하면 컴파일러는 아래와 같은 오류를 내뱉을 것이다.

System.Void cannot be used from C# — use typeof(void) to get the void type object
System.Void는 C#에서 사용할 수 없습니다. void 형식 개체를 가져오려면 typeof(void)를 사용하세요.

그러므로 void 타입을 가져오려면 typeof(void) 외에는 방법이 없다.
C/C++ 처럼 void* 포인터도 가질 수 있는데 이 글 범주에서 벗어나고 관련도 없기 때문에 설명은 하지 않겠다.

그렇다. 결론적으로 얘기하면 자바나 닷넷이나 void는 리플렉션용으로 메소드 반환 형식을 인식하기 위해서만 존재하는 타입인 것이다.
끗.

composite / 2016년 8월 24일 / 미분류 / 0 Comments

[Java] 제네릭의 비애

자바에서도 제네릭 리턴 방식의 메소드를 꽤 이용할 것이다.
이는 별도의 캐스팅 타입 없이 간편하게 원하는 방식의 리턴 타입을 얻기 위함인데,
자바에서는 이런 방식의 메소드 작성이 그닥 편리하지 않다.
왜그런지 예제를 통해 알아본다.

public static <T> T getObject(String what){
    //T 클래스 정보를 가져오고 싶다.
    Class<T> clazz = T.class; //error
    //ㅅㅂ...
    T result = clazz.newInstance();
    clazz.getField(what).set(result, "foobar");
    return result;
}

그렇다. 자바는 제네릭 클래스의 클래스 정보를 가지고 오고 싶어도 못가져온다.
T.class도 안먹히고, 그렇다고 new Class<T>() 로 초기화 하고 싶어도 초기화 메소드가 하필 private 접근이다.
이에 반해, 제네릭에 강한 닷넷은 역시 닷넷답게 클래스 정보 접근이 매우 용이하다.

public static T GetObject<T>(String what){
    //T 클래스 정보를 가져오고 싶다.
    Type type = typeof(T);
    //우왕굳 이대로 진행!
    T result = type.CreateInstance();
    type.GetField(what).SetValue(result, "foobar");
    return result;
}

그래서 자바는 클래스 정보를 결국 명시적으로 넣어야 한다.

public static <T> T getObject(String what, Class<T> clazz){
    T result = clazz.newInstance();
    clazz.getField(what).set(result, "foobar");
    return result;
}

자바 개발자들이라면 다들 아무렇지도 않게 이렇게 처리할 것이다.
하지만 왜 이렇게 불편하게 메소드를 작성하고 싶은지 의문점을 가진 개발자는…
나 말고 있나? 별로 없어 보인다. 혹시라도 궁금한 사람을 위해 내가 속시원하게 풀이해본다.
물론 그전에 Stack Overflow를 통해 답변을 찾이본 이들도 있겠지만, 한글이면 더 좋잖아 ㅋ

자바는 형식 말소(Type Erasure)라는 별 희한한 법칙을 가지고 있다.
내용은 대충 이렇다.

  • 자바 컴파일러는 모든 제네릭 타입을 Object로 박싱 후 바이트코드로 변환한다.
  • 형식을 캐스팅하는 기호를 추가하여 안전한 타입을 유지한다.
  • 확장 제네릭 형식을 위하여 브릿지 메소드를 별도 생성하여 다형성을 유지한다.

그렇다. 자바에게 제네릭은 안전한 타입을 위한 기호 정의 그 이상 그 이하도 아니다.
이 법칙 때문에 닷넷처럼 제네릭 클래스와 비제네릭 클래스는 다른 클래스로 취급을 할 수 없으며, 메소드도 마찬가지가 되는 것이다.
위에 예제를 자바 컴파일러에서는 형식 말소 법칙에 의해 아래와 같은 코드로 재정의한다.

public static Object getObject(String what, Class clazz){
    Object result = clazz.newInstance();
    clazz.getField(what).set(result, "foobar");
    return result;
}

이렇게 되면 런타임 상에서 제네릭 타입 취급 안할 거라는 예상을 하기 쉬운데. 그렇다고 그건 아니다. 위에 얘기한 법칙의 2번째 규칙 때문이다.
그렇다면 확장형 제네릭은 어떻게 취급하느냐,

public static <T extends FooVO> T getObject(String what, Class<T extends FooVO> clazz){
    T result = clazz.newInstance();
    clazz.getField(what).set(result, "foobar");
    return result;
}

값 객체(Value Object)의 베이스 기반 임의 타입을 가져오는 메소드는 컴파일러에선 아래와 같이 이해한다고 보면 된다.

public static FooVO getObject(String what, Class clazz){
    FooVO result = (FooVO)clazz.newInstance();
    clazz.getField(what).set(result, "foobar");
    return result;
}

즉, 확장 대상 타입으로 가져온다고 보면 된다.
이는 제네릭 클래스에서도 똑같이 적용된다.

다행히도 이런 해석으로 인해 성능이 줄지는 않는다. 어자피 자바에 제네릭이 없다면 박싱과 언박싱을 할 거 뻔할 테니,
즉 결국 거의 같은 시나리오이기 때문에 성능 줄지도 않고, 그렇다고 늘지도 않는다. 계륵이지.

하지만 자바 런타임에서는 이게 나을 수밖에 없다. 첫번째로 하위 코드 호환성이 있고, (이게 주 목적 ㅅㅂ)
두번째로는 형식 말소에 기재된 대로, 파라미터화된 클래스를 생성할 필요가 없어지기 때문에 제네릭으로 인한 오버헤드를 줄일 수 있다.

그래도 제네릭 안쓰는 것보다 낫다. MapList 만 딸랑 정의하는 rawtype 즐겨쓰는 개발자 극혐. 대체 뭔 타입을 넣었다 꺼내는지 알 수가 없으니.

composite / 2016년 8월 19일 / Piss Development / 0 Comments

한국은 미래 투자가치가 없다. 절대로. 영원히.

S사가 선행연구조직을 폐지하고 IT 육성 제도사업인 소프트웨어 멤버쉽을 올해 폐지 예정이다.
그리고 다른 대기업과 함께 기업경쟁력과 기술확보를 위해 외국 스타트업 투자가 힌창이다.
이렇게 한창이지만 대기업은 한국 스타트업 투자는 거들떠보지도 않는다.
이는 대한민국 미래에 투자할 가치가 없다는 것이다. 왜일까?

  1. 한국은 선규제 정책으로 유명하다. 제식구 감싸는 중국조차 후속규제이다.
    이는 “소잃고 외양간 고친다”는 속담 인식이 나쁜 여론과 마인드가 한몫했다.
    오로지 개천에 용나는 행위를 원천 차단하는 선규제로 과연 스타트업이 활발?
    그럴 리 없는 거 알 사람은 다 안다.

  2. 이미 유능한 인재는 외국에 있고, 외국에 스타트업을 차린다.
    미래가치가 있는 아이템이 외국에 집중되는데, 생태계 조성을 할 수 없는 한국에 투자하고 싶겠나?
    이미 많은 투자자들은 한국 스타트업 투자를 상당히 꺼려하고 있다.
    물론 힌국 스타트업 육성을 위한 엔젤투자가 있지만, 투자대비 성과는 정말 “엔젤”이다.

  3. 자본력이 부족한 기술은 법적제도를 악용하여 거의 공짜로 기술취득이 가능하다.
    굳이 더 설명 안해도 뉴스에 수없이 국가와 대기업에 기술 털리는 사례가 많아서 설명이 필요없다.
    반드시 “알려진 기술”만 보호받는 특허보호제도로 인해 눈뜨고 당하고 망하는 사업자가 많은데,
    게디가 투자자도 투자했는대 대기어빙 채가면 그대로 완전한 손실이 되는데
    즉, 한국 스타트업에 투자하는 행위는 자살행위나 마찬가지다.

이런 꼬라지에 미쳤다고 국가와 기업이 한국 미래에 투자하는가?
누가 투자자던 절대 나설 수 없다.투자하면 99% 손해 감수해야 하니.
그렇기에 스타트업을 하거나 기발한 아이템을 이루고자 한다면, 반드시 탈조센해야 한다.
이나라는 미래가 없다. 미래에 투자도 없다. 국가조차도 제식구만 챙기거나 해외기술 비싸게 사는데.

절대 한국에서 스타트업하지 마라. 한국적인 실패와 인생 쫑난다는 게 어떤 느낌인지 느끼고 싶은 시람만 해라.

composite / 2016년 8월 11일 / Dog's bullshit / 0 Comments

잠긴 글: Mybatis Plus

이 콘텐츠는 비밀번호로 보호되어 있습니다. 보려면 아래에 비밀번호를 입력해주세요:

composite / 2016년 7월 26일 / Piss Development / 0 Comments

극단주의의 유행

국내 친여권 극단주의 일베.
국내 여성 극단주의 메갈.
해외 이슬람 극단주의 IS.
미국 금권 극단주의 트럼프.

지금은 대 극단주의 시대.

나? 종말 극단주의자임 개기지 마셈 ㄳ.
에라이 지구 멸망해버려라 ㅋ

그리고 지구는 멸망했다. 끗.

composite / 2016년 7월 20일 / Dog's bullshit / 0 Comments

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 / 0 Comments

구글에게 지도 해외 반출 거부가 핑계거리인 이유

이번엔 구글 지도 이슈로 넘어가도록 하겠다.
구글은 지도를 각 국가의 외부 업체로부터 항공 및 위성 지도 데이터를 받아 그것을 그대로 가공하여 서비스한다.
이건 구글에서 직접 밝혔다. 물론 내막은 구글 지도 담당 아니고서야 아무도 모르지만,

구글 어스에서 안보 시설 가릴 방법이 있다?

이런 추측에 구글 측은 사실과 다르다는 입장입니다. 구글코리아의 정김경숙 상무는 “위성영상이나 항공영상 업체 쪽에서 이미 의도적으로 블러 처리된 영상을 공급하는 경우가 있다”면서 “가능하면 블러 처리되지 않은 영상을 구매하고자 하지만 특정 지역에 대해 달리 대안이 없을 경우 어쩔 수 없이 해당 영상을 사서 서비스하기도 한다”고 설명했습니다.

구글 어스 또한 마찬가지다. 하지만 한국의 경우는 위성 데이터를 주지 않아 해외에서 받았는데, 이로 인해 한국에서 보안시설로 취급하고 있는 청와대가 아주 깨끗하게 보이고, 여기서부터 정부에서 “안보 때문에 구글에게 지도 못 준다”는 입장을 고수한 것이다.
근데. 개소리다. 왜그런지 설명하겠다.

국내 측량업 등록부터 빡세다

한국에서는 지도를 만들던 위성사진 찍던 하여튼 지도나 지리 관련 사업을 하려면 “측량업 등록”을 반드시 해야 한다.
기준이 상당히 빡세기 때문에 대기업은 귀찮아서 안한다. 이는 네이버와 다음도 마찬가지.
자료는 여기를 참조하라. 측량업의 등록기준(제16조, 제18조제1항관련)
그럼 다음 로드뷰는 어떻게 한거냐고? 이런 이런. 다음이 미쳤다고 직접 나서서 로드뷰를 찍었겠는가? 걸리면 벌금폭탄인데?
당연히 외주를 줘서 찍었다. 차량에 다음이라는 로고 표기만 박혔을 뿐이지.
다음 로드뷰 ‘대박’…개발업체는 ‘울상’
이 기사만 봐도 다음이 직접 로드뷰 안만들었다는 거 납득하겠는가?
이정도인데 구글은? 나같아도 측량업 등록하려는 병신짓을 하는 것보다 그냥 등록한 측량업의 자료를 사는 게 더 싸고 빠르다.

네이버와 다음 지도도 데이터 제공업자 따로있다.

위에서 설명한 그대로라 중복이 있을 수 있는데, 약간의 부연설명을 하도록 하겠다.
국내에서는 구글 지도가 너무 허술해서 네이버와 다음 지도를 많이 이용할 것이다. 나도 그렇다.
그런데 네이버와 다음 지도가 어디서 만들었는지는 당연히 공식적으로 공개를 안했기 때문에 담당자 말고는 모른다.
하지만 확실한 것은, 측량법에 의해 지도 데이터는 네이버와 다음이 별도로 신고하지 않으면 만들 수가 없다는 것이다.
결국 외주를 줄 수밖에 없다. 당연히 각 지도업체로부터 데이터를 받으면, 네이버와 다음은 이를 가공하고 서비스한다.
또한, 측량법에 안보에 의해 보안시설 가려야 하는 조항이 있기 때문에, 가공할 때에도 따로 신경을 쓰긴 한다.
물론 원본부터 청와대니 부대 위치와 사진은 가려진 채로 말이지. 포털은 그거 갖다 쓰면 되는 거고.

그럼 구글도 어자피 지도 넘겨도 같은 결과?

그렇다. 구글에 지리 데이터를 팔 때도 안보시설 가리고 주면 되는 것이다. 여기서 구글의 주장이라고 알려진 게 있는데,
“안보시설을 가리면 정확한 데이터를 제공할 수 없다”면서 안보시설 가리는 거에 소극적이라는 인터넷 기사 인용이 많다.
근데 구글이 그런 말을 했다는 증거는 내가 아무리 뒤져봐도 찾아볼 수가 없다. 과연 꾸며낸 말일지, 아 다르고 어 다르게 썼는지 알 길은 없다.
하지만 확실한 점은, 구글에게도 보안 시설 가린 데이터를 주면 충분히 측량법에 위배되지 않고도 구글에 지도 서비스를 할 수 있겠끔 가능하다는 것이다.
하지만 이제부터 골칫거리가 하나 나오기 시작했다.

국내에 서버를 둬라?

일단 구글에 한국 서버는 없다. 근데 서비스한다.
몇몇 보수(?) 언론이 주장하기로는 중국, 러시아도 구글 서버 있는데 한국만 서버 없다고 징징대는데, 이는 사실이 아니다.
그저 구글 까내리려고 소설쓰는 건데, 중국과 러시아는 구글이 아예 철수한 국가기 때문에 서버가 애초에 있을 수도 없다.
당연히 구글도 국내에 서버를 두려고 했었다. 하지만 KT의 병크로 무산됐다. 근데 그것도 모르는 아해들은 그것도 모르고 국내에 없다는 이유로 구글을 깐다.
이렇게 구글을 무차별적으로 깔 수 있는 이유가 상당수 언론사에서 구글 데이터센터 백지화 기사를 삭제했기 때문이다. 그래서 좀처럼 찾아볼 수 없다.
미닉스 웹툰, 블로그에만 남아져 있는 자료들로는 객관성이 결여될 우려를 표시할 사람이 있기 때문에 올리지는 않겠다. 그냥 알아서들 구글 검색 해라.
게다가, 구글도 국내에 서버를 두기는 두었었다. 하지만 두기도 무섭게 한국이 무슨 짓을 했느냐.
구글, 한국 통신사 IDC로 사용자 정보 수집 의혹 확산
왜 구글은 ‘정보기술 강국’ 한국을 외면했을까
자, 지들이 구글 거부했으면서 수집했다고 지랄, 그래서 압수수색하고 지랄, 구글은 시발 철수. 이런 호되게 당한 경험이 있기 때문에.

그리고 한국에서는 서버에 철통보안을 구축할 수 없는데, 이는 통신비밀보호법 때문이다.

제15조의2(전기통신사업자의 협조의무)판례문헌
① 전기통신사업자는 검사·사법경찰관 또는 정보수사기관의 장이 이 법에 따라 집행하는 통신제한조치 및 통신사실 확인자료제공의 요청에 협조하여야 한다.
② 제1항의 규정에 따라 통신제한조치의 집행을 위하여 전기통신사업자가 협조할 사항, 통신사실확인자료의 보관기간 그 밖에 전기통신사업자의 협조에 관하여 필요한 사항은 대통령령으로 정한다.
[본조신설 2005.5.26]
(출처 : 통신비밀보호법 일부개정 2014.10.15 [법률 제12764호, 시행 2014.10.15] 법무부 > 종합법률정보 법령)

즉, 국가에서 필요하면 무조건 암호화 없는 자료를 넘겨야 하며, 협조에 불응할 경우에 따른 처벌 조항도 존재한다… 시발.
카카오도 이 법안 때문에 프라이버시를 주장한 이석우 대표는 검찰과 국정원의 압박에 빈털터리로 카카오에서 쫓겨났다.

뭐 좋다. 그럼 구글 지도만 국내에서 서비스 하는 건 어떻냐는 의견도 꽤 나왔다. 구글은 당연히 “불가능”하다는 입장을 고수했다.
구글 지도가 애초에 아예 해외에 있는데, 국내 지도만 서버를 분리해서 서비스한 사례는 그 어떤 곳도 없고, 한다고 해도 천문한적인 비용이 소모된다.
구글 입장에서는 당연히 납득하기 어려운 조건이고, 한국 정부 또한 헌법에 명시되었기 때문에 입장에서는 다른 업자와 같이 지켜야 하는 입장인 것이다.
지금 이 문제가 바로 구글과 정부 사이의 불편한 진실인 것이다.

좋은 방안이 없을까?

구글 지도에 한국을 추가하는 행위는 국내 소비자 뿐 만 아니라 해외 소비자들에게도 한국에 대한 기회를 많이 담을 수 있어서 관광산업과 경제발전에 기여할 수 있는 장점이 있지만,
반면 이로 인해 구글 지도를 오픈하면 국내 지도 사용의 감소로 인하여 국내 산업에 큰 타격이 있는 어두운 면이 있다고 볼 수 있다.
근데, 어두운 면은 어자피 겪어야 한다. 경쟁을 강요하는 국가이면서, 해외 경쟁으로부터 보호하는 참 치사한 국가. ㅋㅋ
WIPI가 풀리고, 컨텐츠 사업 매출이 줄었는가? 통신사 나자빠졌는가? 아니다. 물론 컨텐츠 사업 중 고꾸라진 업체도 있을 것이다. 물론 이를 끝까지 개긴 업체들 말이다.
어쨌든, 구글과 국가가 조율할 수 있는 좋은 방법은 뭐가 있을까? 이제 여러분이 생각해볼 차례이다.

  • 구글 손을 들어주면 단기적으로는 상당한 타격이 예상되나, 장기적으로는 한국 발전에 기여할 가능성은 있다.
  • 국내업자 손을 들어주면 국내 업체는 구글로부터 사업을 지킬 수 있다. 근데 그게 다다.

이걸 보면 아무리 생각해도 역시 구글에 오픈해주는 게 나을 것 같다.
왜냐면, 안보로 가던 어떤 방면으로 가던 이는 이미 대체 방안이 존재하고 유일하게 방안이 없는게 바로 결국 국내 업체 역차별 뿐이니까.
안보 문제? 안보 안따지는 국가가 있긴 한거냐?
중국 사례를 보자. 중국도 한국과 마찬가지로 지도 해외 반출 금지 국가다. 근데 구글에 중국 지도 아주 잘 보인다.
중국, 구글에 상세 지도 제공했다.

물론 2008년 베이징 올림픽 때문에 공개했다는 설이 있지만, 안타깝게도 오차가 상당하다고 한다.
이걸 보면, 어자피 보안 시설은 충분히 국내에서 가려서 구글에 제공하면 되고, 이는 결국 안보 문제도 해결되는데.

지도 데이터 구글 걍 줘라. 해결봤잖아.

composite / 2016년 7월 15일 / Dog's bullshit / 4 Comments

구글 지도만 해결되면 포켓몬GO가 한국 출시될 것 같니?

뭐.. 맞는 말이다. 사실 같은 개발사의 인그레스도 비슷한 사정이긴 하다.
하지만 재밌는 점은, 국내 지리정보 해외반출 불가로 인해 서비스가 어려울 것 같은 인그레스는 버젓이 한국에 서비스하고 있다.
왜냐하면 굳이 그거 없어도 위치정보 기반의 서비스하는데 지장이 없기 때문이다.

그런데… 한가지 문제에 부딪혔다. 구글에서 한국 지도 데이터를 성공적으로 가져갔다고 치자.
인그레스도 해당되며 포켓몬고는 증강현실(AR) 게임이며, 이를 이용하려면 위치정보를 이용해야 한다.
한국에서는 이를 위치기반서비스(LBS)로 정의하는데, 여기까지는 다들 알 것이다.
의외로 모르는 애들 많은데, 방통위에서는 국내 해외 업체 할 것 없이 위치기반서비스(LBS)를 이용하려면 방통위에 신고해야 한다.
물론 개인정보가 아니라면 굳이 신고 안해도 된다. 예를 들면 자기 회사 주소 알려주는 용도로.
하지만 개인의 위치를 이용하여 서비스를 하려면 방통위에 무조건 신고를 하도록 법제화가 되어 있다는게 문제다.

위치정보의 보호 및 이용 등에 관한 법률

제9조(위치기반서비스사업의 신고) ① 위치기반서비스사업을 하고자 하는 자는 상호, 주된 사무소의 소재지, 사업의 종류, 위치정보시스템을 포함한 사업용 주요 설비 등에 대하여 대통령령으로 정하는 바에 따라 방송통신위원회에 신고하여야 한다. <개정 2007.12.21., 2008.2.29.>
②제13조제1항의 규정에 의한 사업의 폐지명령을 받은 후 1년이 경과하지 아니한 자(법인인 경우에는 그 대표자를 포함한다)는 제1항의 규정에 의한 사업의 신고를 할 수 없다.
③제1항에 따라 위치기반서비스사업의 신고를 한 자(이하 “위치기반서비스사업자”라 한다)가 그 신고한 사항 중 상호, 주된 사무소의 소재지 또는 위치정보시스템을 변경(변경으로 인하여 개인위치정보 보호를 위한 기술적 수준이 신고한 때보다 저하되는 경우에 한한다)하고자 하는 때에는 대통령령이 정하는 바에 따라 방송통신위원회에 변경신고를 하여야 한다. <개정 2007.12.21., 2008.2.29.>
④ 위치정보사업자가 제5조제1항에 따른 허가를 신청할 당시 위치기반서비스사업의 신고에 필요한 서류를 첨부한 경우에는 제9조제1항에 따른 위치기반서비스사업의 신고를 한 것으로 본다. <신설 2007.12.21.>

지금 이런 상황일 경우 문제가 봉착해 있다면, 나이앤틱랩스가 과연 방통위에 신고를 했을지 여부이다.
인그레스 출시 당시에는 신고하는 법이 강제화되어 있지 않았고, 해외 서비스는 신고해야 할 근거가 없었다.
그래서 스토어에서 지금까지도 인그레스가 버젓이 올라올 수 있었을 것이다.
근데 상황이 달라졌다. 나이앤틱랩스는 이제 구글로부터 독립했다.
구글이 위치기반서비스 신고를 해서 나이앤틱랩스가 패스했을 지 몰라도 지금은 논란에 휩사이기 쉽기 때문이다.
그래서, 나이앤틱랩스가 별도로 위치기반서비스 신고를 했을 지 여부가 포켓몬GO 오픈의 중요한 열쇠인 것이다.
물론 했다면 지도 문제만 해결하면 바로 출시 OK지만, 만약 신고를 안했다면 신고를 하던가, 아니면 한국 서비스를 제한할 수밖에 없을 것이다.
신고하면 1달이라는 긴 시간을 또 기다려야 한다. 어우 예. 암걸리겠다.

지금 포켓몬GO 때문에 게임업계들이 긴장이다. 어쩌면 치사하게 이 문제를 걸고 넘어질 확률은 차고도 넘친다.
자, 포덕들아. 이제 어떻게 할 것인가? 고켓몬 한국출시를 갈망한다면, 구글은 구글에 맡기고, 이제 이 문제에 집중해야 할 것이다.

참고로, 지리산업은 한국에서 손가락 안에 드는 정경유착 심한 사업이다.
구글이 지도반출 요청했을 때, 정부는 보안시설 가리면 허용해주겠다는 조건을 내걸었고, 국방부도 이에 동조했다.
또한 지도 국내 서버에 두고 관리해야 한다고 하는데… 이건 좀 애매하다.
하지만 지리정보원과 관련 부처, 지리산업계에서는 지리정보산업 다 망한다고 무조건 안 된다며 단세포적으로 노발대발 반발하고 있다는 점. 잊지 마라.

좆같은 한국의 정경유착 때문에 아이폰 하나 들어오는데 3년이란 세월을 WIPI 때문에 시간을 허비했던 역사가 있다.
증강현실(AR) 사업 또한 위치정보서비스 사업(LBS)에 해당되고, 게다가 지리산업계는 여기에 왈가불가 할 수 있다.

만약 고켓몬을 계기로 이 산업이 활성화된다면, 단기적으로는 엄청난 진통이 예상되지만, 장기적으로 뭐… 알지?
아이폰 덕분에 소비자들이 와이파이 잘쓰고 있잖아. 단기적으로는 수입 줄까봐 존나 지랄했던 통신사들 생각해봐.

composite / 2016년 7월 14일 / Dog's bullshit / 0 Comments

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

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

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

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

1. 전문용어의 부재

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

2. 고증 오류

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

3. 선동

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

마치며

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

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

1 2 3 22