2020년 5월 28일 목요일

[Java] 러시아 시간 출력 오류

특정 국가, 환경에서 Java에서 가져온 시간과 윈도우에 적용된 시간 값이 다른 경우가 발생할 수 있다.

이는 대부분 오래된 JDK나 JRE를 사용해서 생긴 문제라고 보면 된다.

우리에겐 낯설은 써머타임(Daylight saving time, DST)에 대한 것인데,
써머타임 적용, 폐지에 대한 신규 정보가 JVM 시스템에 반영되어있지 않아서 발생하는 문제라고 한다.

해결은 JDK나 JRE를 최신 버전으로 올려주면 되는데 문제는 쉽게 업데이트를 결정할 수 없는 경우다. (안정성 또는 호환성 고려, 폐쇄망 환경 등으로 인한 업데이트의 어려움)

이 경우엔 아래의 두가지 대안이 있다.


1. 실행 옵션에 -XX:+UseGetTimeOfDay를 적용.

시간 관련 동작 수행 시 매번 gettimeofday() 시스템 콜을 이용해 시스템 시간을 가져온다. 성능 저하가 있다.



2. 타임존 정보를 갱신해주는 프로그램을 이용해 패치 (Time Zone Updater)

오라클에서 제공하고 있다. 

tzupdater.jar를 내려받은 후 아래 명령어를 실행해주면 시간이 정상적으로 보정된다.
java -jar tzupdater.jar -v -f -l http://data.iana.org/time-zones/releases/tzdata2017c.tar.gz


2020년 5월 24일 일요일

[Java] 빈도수를 간단하게, map의 merge()

Map을 이용해 빈도수를 계산할 때 어떤 언어에서는 간단히 myMap[key]++과 같이 해주면 되는데 Java에서는 그렇게 동작하지 않는다.

그래서 대개 AtomicInteger와 같이 레퍼런스 타입으로 처리하거나 ContainsKey 또는 get()의 null값 체크 후 빈도수를 기록하는 지저분한 코드가 작성되곤 한다.

Java 8에선 이러한 문제(?)가 다소 해결되었는데 아래와 같이 Map의 merge 함수를 이용하면 한 줄의 코드로 단순 카운팅 기능을 구현할 수 있다. 한 줄의 코드이지만 Atomic operation은 아님에 주의할 필요는 있다.

myMap.merge(key, 1, Integer::sum);

함수 이름이 좀 헷갈리게 지어진 것은 아쉽지만 한번 기억해두면 쓰기 편하다.

public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

• key: 키

• value: 값. 초기 값으로 쓰이거나 이전 갑과 병합됨.

• remappingFunction: 새로운 값을 지정하는데 쓰이는 함수, 이전 값이 있는 경우 호출됨. BiFunction은 함수 인수가 2개이면서 결과 값이 있는 함수를 뜻한다.

2020년 5월 19일 화요일

[NSIS] StrCpy 사용법

IndexOf와 RIndexOf랑 StrCpy를 쓰면 결과물이 지저분해질 순 있어도 NSIS 내부에서 원하는 문자열 조작을 어떤식으로든 할 수 있다.

문법
StrCpy 저장변수 문자열 [최대길이] [시작_오프셋]
: 최대 길이와 시작 오프셋이 생략되거나 음수 값이 올 수 있는게 특징이다.

예시
StrCpy $0 "a string"
→ "a string" - 기본 복사

StrCpy $0 "a string" 3
→ "a s" - 최대 길이를 3으로 지정했으므로 처음의 3글자인 "a s"만 선택됨.

StrCpy $0 "a string" -1
→ "a strin" - 최대 길이를 음수로 하면 문자열의 뒤에서 부터 잘라내는 동작을 함.

StrCpy $0 "a string" "" 2
→ "string" - 복사 시작 위치를 2로 지정했으므로 "a "가 스킵됨.

StrCpy $0 "a string" "" -3
→ "ing" - 복사 시작 위치를 음수로 하면 뒤에서 지정된 길이만큼 문자열을 가져옴.

StrCpy $0 "a string" 3 -4
→ "rin" - 뒤에서 부터 4글자인 "ring"을 가져온 다음 앞의 3글자인 "rin"만 선택됨.

https://nsis.sourceforge.io/Reference/StrCpy

2020년 5월 18일 월요일

[C#] Task, Task

Task와 Task의 Generic인 Task<TResult>는 쓰레드풀에서 쓰레드를 가져와 비동기 작업을 실행해 준다. Generic은 값을 반환하는 작업인 경우에 쓰인다. Task를 실행한 다음엔 IsCanceled, IsCompleted, IsFaulted 등 속성을 이용해 Task의 상태를 확인할 수 있다.

Task를 실행하는 방법엔 여러가지가 있다. Task 인스턴스를 만든 다음 Start() 메서드를 호출하거나 TaskFactory.StartNew(Action<Object>, Object) 메서드를 호출해 한번에 처리하는 방식이 있다. 더 간단하게는 Task.Run()을 이용할 수도 있다. 다만 이 메서드는 .Net 4.5 이상에서 제공된다.

Task는 비동기적으로 실행되기 때문에 Task의 모든 작업이 끝나기 전에 애플리케이션이 종료되는 경우가 생길 수 있다. 이러한 경우엔 Wait() 메서드를 이용해 Task의 작업이 끝날때까지 호출 쓰레드가 기다리게 할 수 있다. 무한정 기다리기 싫은 경우엔 Wait() 메서드에 timeout을 지정해주면 된다.

Task는 대기하지 않고 백그라운드에서 돌리고 싶은 작업이 있을 때 유용하다. 실행 문맥과 독립적인 작업을 Task로 처리하면 사용자가 대기하지 않아도 되기 때문에 사용성 측면에서도 이점이 있다. 여기에 코드까지 깔끔해지는 것은 덤이다.


// Task의 생성과 실행을 따로.
var t1 = new Task(() => {
    // work
});

t1.Start();
// other work
t1.Wait();

// Task의 실행과 생성을 한 번에.
var t2 = Task.Factory.StartNew(() => {
    // work
});
// other work
t2.Wait();


2020년 5월 14일 목요일

GTA 5 (Grand Theft Auto V) PC 무료



















무려 GTA 5를 21일까지 에픽게임즈에서 무료로 다운로드 받을 수 있다.

출시된지 오래된 게임이라 높은 사양을 요구하지 않아서 대부분의 PC에서 부담없이 즐길 수 있으리라 생각된다.

최소 사양
권장 사양
OS
Windows 10 64비트, Windows 8.1 64비트, Windows 8 64비트, Windows 7 64비트 서비스 팩 1, Windows Vista 64비트 서비스 팩 2* (*Vista OS에서는 NVIDIA 비디오 카드를 권장합니다)
OS
Windows 10 64비트, Windows 8.1 64비트, Windows 8 64비트, Windows 7 64비트 서비스 팩 1
프로세서
인텔 코어 2 쿼드 CPU Q6600 @ 2.40GHz(4 CPU) / AMD Phenom 9850 쿼드코어 프로세서(4 CPU) @ 2.5GHz
프로세서
인텔 코어 i5 3470 @ 3.2GHZ(4 CPU) / AMD X8 FX-8350 @ 4GHZ(8 CPU)
메모리
4GB RAM
메모리
8GB RAM
비디오 카드
NVIDIA 9800 GT 1GB / AMD HD 4870 1GB (DX 10, 10.1, 11)
비디오 카드
NVIDIA GTX 660 2GB / AMD HD7870 2GB
사운드 카드
DirectX 10 100% 호환
사운드 카드
DirectX 10 100% 호환
HDD 공간
90 GB available space
HDD 공간
90 GB available space

누구에겐 부담을 가질만한 잔인한 샌드박스 게임이지만 공짜라는데 뭐 받지 않을 이유가 있나.
내려받기는 에픽 게임즈 런처 설치한 뒤 런처 통해서 내려받는 방법이 가장 수월하다.