목차

  1. 자바 특징
  2. JDK (Java Development Kit)
  3. JVM (Java Virtual Machine)
  4. 자바 프로그램 실행 단계
  5. 메모리 사용 영역

1. 자바 특징

1) 이식성이 높은 언어

2) 객체지향 언어

3) 함수적 스타일 코딩 지원

4) 메모리를 자동으로 관리 : 개발자가 직접 메모리에 접근할 수 없도록 설계. 객체 생성 시 자동적으로 메모리 영역을 찾아서 할당하고, 사용이 완료되면 Garbage collector를 실행시켜 자동적으로 사용하지 않는 객체를 제거

5) 멀티스레드를 쉽게 구현

6) 동적 로딩을 지원

 

 

2. JDK (Java Development Kit)

1) JDK 란?

- 자바 프로그램 개발 도구 
- 개발을 위한 클래스, 컴파일러, 실행 및 배포도구를 포함 등 개발을 위한 전반적인 환경 제공

 

2) 플랫폼

- 프로그래밍이나 컴퓨터 실행을 위한 기본적인 기능을 제공하는 것.
- Java의 JVM은 이런 다양한 플랫폼 위에서 동일한 Java 소스코드를 이용할 수 있는 환경 제공
- 플랫폼 종류: J2SE(Java 2 Standard Edition), J2EE(Java 2 Enterprise Edition), J2ME(Java 2 Micro Edition)

 

3) JDK 디렉터리 구조

JDK 디렉터리 구조

 

4) JVM, API, JRE, JDK 관계

- JDK(Java Development Kit) = JRE + 개발에 필요한 도구
- JRE(Java Runtime Environment) = JVM + 표준 클래스 라이브러리

JVM, API, JRE, JDK 관계

 

 

3. JVM (Java Virtual Machine)

자바 프로그램은 완전한 기계어가 아닌, 중간 단계의 바이트 코드이기 때문에 이것을 해석하고 실행할 수 있는 가상의 운영체제(JVM)가 필요

 

- 장점: Write once, run anywhere.

- 단점: 한번의 컴파일링으로 실행 가능한 기계어가 만들어지지 않고 JVM에 의해 기계어로 번역되고 실행되기 때문에, C와 C++의 컴파일 단계에서 만들어지는 완전한 기계어보다는 속도가 느림.

 

 

 

4. Java 프로그램 실행 단계

javac Hello.java	// 1) 컴파일러(javac.exe)로 자바 소스 파일 컴파일, *.class 파일 생성
java Hello		// 2) JVM을 구동시키는 명령어(java.exe)

1) Java 소스 파일을 컴파일러로(javac.exe)로 컴파일하면 확장자가 .class인 바이트 코드 파일이 생성됨. 
2) java.exe 명령어가 실행되면서 JVM은 바이트 코드 파일(Hello.class)을 메모리로 로드하고, 해당 운영체제에 맞게 기계어로 번역. 그리고 main() 메소드를 찾아 실행

 

main() method

- Program entry point (실행 진입점)
- java.exe로 JVM을 구동시키면 제일 먼저 main() 메소드를 찾아서 실행시킴.

 

자바 실행 단계
자바 실행 단계(자세히)

 

프로그램 동작 순서

 

5. 메모리 사용 영역

java.exe로 JVM이 시작되면 JVM은 운영체제에서 할당받은 메모리영역(Runtime Data Area)을 다음과 같이 세부 영역으로 구분하여 사용

=> 메소드 영역, 힙 영역, JVM 스택 영역

 

메소드 영역

  • 코드에서 사용되는 클래스(~.class)들을 클래스 로더로 읽어 클래스별로 런타임 상수풀(runtime constant pool), 필드(field) 데이터, 메소드(method) 데이터, 메소드 코드, 생성자(constant) 코드 등을 분류하여 저장.
  • JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역

 

힙 영역

  • 객체와 배열이 생성되는 영역
  • JVM 스택 영역의 변수나 다른 객체의 필드에서 참조
  • 참조하는 변수나 field가 없으면 Garbage Collector를 실행시켜 쓰레기 객체를 힙 영역에서 자동으로 제거

 

JVM 스택 영역 (-> Frame -> 로컬 변수 스택)

  • 각 스레드마다 하나씩 존재. 스레드가 시작될 때 할당
  • 기본적으로 main thread가 존재(JVM 스택도 하나)
  • Frame: JVM stack의 element
    - method를 호출할 때 마다 Frame을 추가(push)하고 method 종료되면 해당 Frame 을 제거(pop)하는 동작 수행
    - 예외 발생시 printStackTrack() method
  • 로컬 변수 스택: Frame 내부에 존재
    - 기본 타입 변수와 참조 타입 변수가 추가(push)되거나 제거(pop)됨.
    - 변수가 이 영역에 생성되는 시점은 초기화될 때, 즉 최초로 변수에 값이 저장될 때.

메모리 사용 영역

 

Ref. 이것이 자바다 - 신용권의 Java 프로그래밍 정복

목차
1. 간단 용어 정리
2. 
Framework vs. Library 심층 분석



1. 간단 용어 정리

  • API (Application Programming Interface)
    - 개발자가 공개적으로 노출한 멤버들을 사용하여 기능에 접근하고, 해당 기능을 구현하는데 사용된 코드를 숨길 수있는 인터페이스
  • SDK(System Development Kit)
    - 소프트웨어 개발 도구 모음
    - SDK 안에는 개발에 도움이 될 개발 도구 프로그램, 디버깅 프로그램, 문서, API 등이 있다.
  • Software Framework
    - 정의된 API를 제공하는 Software library의 모음
    - 라이브러리와 달리 애플리케이션의 틀과 구조를 결정할 뿐만 아니라, 그 위에 개발된 개발자의 코드를 제어함.
  • Software Library
    - 컴퓨터 프로그램에서 자주 사용되는 부분 프로그램들을 모아 놓은 것.
    - 정적, 동적(링크, 로드) 라이브러리로 나뉨



2. Framework vs. Library 심층 분석

결론: 누가 누구를 호출하느냐의 차이 (who calls who)

프레임워크에서는 프레임워크 코드가 우리 코드를 호출하고, 라이브러리에서는 우리 코드가 라이브러리를 호출한다.

  • Inversion of Control (IOC)
    JavaScript 프레임워크인 jquery를 예로, Document가 준비 상태(document on ready)일 때 우리가 정의했던 콜백을 호출하는 것은 프레임워크이다. 이것은 프레임워크가 담당하는 프레임워크의 통제부분의 흐름이다.

Framework code: 통제 흐름을 정의
Your code: 행동을 정의
Library code: 행동을 정의


  • 프레임워크와 라이브러리의 차이점은 Control에 관한 것. 통제의 흐름(flow of control)이 그 차이이다.
    프레임워크는 당신의 애플리케이션의 흐름을 통제하고, 라이브러리는 그러지 않는다.




Reference.
https://www.youtube.com/watch?v=D_MO9vIRBcA
http://waaan.tistory.com/15


목차
1. 버전관리란?
2. Git의 목표
3. Git의 기초
4. CLI
5. 명령어

 

1. 버전관리란?

버전 관리 시스템(Version Control System) :  파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템

  • 로컬 버전 관리 시스템
  • 중앙집중식 버전 관리 시스템(CVCS)
    - CVS, Subversion, Perforce 같은 시스템은 파일을 관리하는 서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용(Checkout).
  • 분산 버전 관리 시스템(DVCS)
    - Git, Mecurial, Bazaar, Darcs 같은 DVCS에서의 클라이언트는 단순히 파일의 마지막 스냅샷을 Checkout 하지 않음. 저장소를 전부 복제
    - 리모트 저장소가 존재

 

 

2. Git의 목표

  • 빠른 속도
  • 단순한 구조
  • 비선형적인 개발(수천 개의 동시 다발적인 브랜치)
  • 완벽한 분산
  • Linux 커널 같은 대형 프로젝트에도 유용할 것(속도나 데이터 크기 면에서)
 

3. Git 기초

  • 차이가 아니라 스냅샷
    Subversion과 가장 큰 차이점은 데이터를 다루는 방법
    - Subversion: 각 파일의 변화를 시간순으로 관리하면서 파일들의 집합을 관리
    - Git: 데이터를 파일 시스템 스냅샷으로 취급하고 크기가 아주 작음. 데이터를 스냅샷의 스트림처럼 취급
  • 거의 모든 명령을 로컬에서 실행
  • Git의 무결성: 체크섬

- 데이터를 저장하기 전에 항상 체크섬을 구하고 그 체크섬으로 데이터를 관리
- Git에서 사용하는 가장 기본적인(Atomic) 데이터 단위이자 Git의 기본 철학
- SHA-1 해시를 사용하여 만듦
- 40자 길이의 16진수 문자열
- ex) 24b9da6552252987aa493b52f8696cd6d3b00373

  • Git은 데이터를 추가할 뿐
  • 세가지 상태
    Git은 파일을 Committed, Modified, Staged 이렇게 세 가지 상태로 관리
    - Committed : 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미
    - Modifed : 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않은 것을 말함
    - Staged : 현재 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미

 

 

4. CLI

Git을 사용하는 방법은 많지만 Git의 모든 기능을 지원하는 것은 CLI
GUI를 사용하려면 SourceTree 추천

 

 

5. 명령어

첨부파일에 있는 cheat sheet 을 보면 한눈에 명령어를 볼 수있다.

git-cheat-sheet-education.pdf
다운로드

 

 

 

Ref.
https://git-scm.com/book/ko/v2
GitHub Education

UIViewController를 category하여 ViewController를 제거하는 메소드를 추가해서 사용하고 있다.


아래에 따라 뷰 컨트롤러를 제거하는 로직이 다르므로 체크하여 분기를 태워야겠다.

  • Navigation Stack에 Push된 뷰 컨트롤러인가
  • 모달 형식으로 Present된 뷰 컨트롤러인가


아래 코드는 현재 뷰가 모달 형식인지 아닌지를 체크하는 로직이다.


- (BOOL)isModal

{

    if([self presentingViewController])

        return YES;

    if([[[self navigationController] presentingViewController] presentedViewController] == [self navigationController])

        return YES;

    if([[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]])

        return YES;

    

    return NO;

}



모달 형식이면 

[self dismissViewControllerAnimated:YES completion:nil];


네비게이션 스택에 푸시된 형식이면

[self.navigationController popViewControllerAnimated:YES];





Ref.

http://stackoverflow.com/questions/23620276/check-if-view-controller-is-presented-modally-or-pushed-on-a-navigation-stack

현재 디바이스에 설치된 앱이 App Store에 출시된 최신 버전인지 체크하는 방법이다.


+ (BOOL)needsUpdate

{

    NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];

    NSString* appID = infoDictionary[@"CFBundleIdentifier"];

    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://itunes.apple.com/lookup?bundleId=%@", appID]];

    NSData* data = [NSData dataWithContentsOfURL:url];

    NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    

    BOOL result = NO;

    

    if ([lookup[@"resultCount"] integerValue] == 1){

        NSString* appStoreVersion = lookup[@"results"][0][@"version"];

        NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];


        NSArray *versionArray = [currentVersion componentsSeparatedByString:@"."];

        NSArray *appStoreArray = [appStoreVersion componentsSeparatedByString:@"."];

        

        for (int i=0; i<appStoreArray.count; i++) {

            

            int bundleStat = [versionArray[i] intValue];

            int serverStat = [appStoreArray[i] intValue];

            

            if (bundleStat == serverStat) {

                result = NO;

                continue;

                

            } else if (bundleStat > serverStat) {

                result = NO;

                break;

                

            } else {

                result = YES;

                break;

            }

        }

    }

    

    return result;

}


참고로 lookup 변수에는 앱스토어 등록되어있는 나의 앱에 대한 여러 정보들을 갖고있더라.







멀티 프로세스와 멀티 스레드는 '동시에 가지 이상의 루틴을 실행 있는 역할'을 하는 것은 동일하다.

그럼 어떠한 차이점이 있을까?




멀티 프로세스(Multi Process)

  • 부모-자식 관계라고 해도 자신만의 메모리 영역을 가지게 된다.
  • 환경변수와 프로세스 핸들 테이블이 상속 가능할 뿐 결국 독립적인 관계이다.
  • fork를 통해 프로세스를 복사한다.
  • 유닉스 계열에서 ps 명령어로 현재 수행되고 있는 프로세스를 확인할 수 있다.
  • 프로세스 간의 통신을 하려면 IPC(Inter Process Communication; 세마포어, 큐, 공유메모리)를 통해야 한다.




멀티 스레드(Multi Thread)

  • 하나의 프로세스가 다수 개의 작업을 각각 스레드를 이용하여 동시에 작동 시킬 수 있다.
  • 스레드는 다음과 같은 공유 메모리를 가진다.






멀티 스레드는 멀티 프로세스에 비해 상당한 이점을 가진다

  1. 컨텍스트 스위칭(Context Switching) 시에 공유 메모리 만큼의 시간(자원) 손실이 줄어든다.
    : 프로세스 간의 컨텍스트 스위칭시 단순히 CPU 레지스터 교체 뿐만이 아니라 RAM과 CPU사이의 캐쉬메모리에 대한 데이터 까지 초기화 되므로 상당한 부담이 발생한다.
  2. Stack을 제외한 모든 메모리를 공유하기 때문에 global(전역), static(정적) 변수 그리고 new, malloc에 의한 모든 자료를 공유할 수가 있다.
    : 이는 프로세스간 통신(ex.pipe)과 같이 복잡한 과정을 거치지 않고 보다 효율적인 일처리가 가능하다는 것을 뜻한다. (핸들 테이블과 환경변수는 덤이다.)


결국 계산기와 메모장 처럼 서로 완전히 별개의 프로그램이라면 

독립적은 프로세스를 구성해야겠지만 서로 관련된 기능들은 멀티 스레드로 구현하는 것이 이득이다!





멀티 스레드의 효율성과 안정성 문제


여러 개의 스레드가 동일한 데이터 공간을 공유하면서 이들을 수정한다는 점에 필연적으로 생기는 문제이다.

멀티 프로세스의 방식의 프로그램에서 하나의 프로세스가 자신의 데이터 공간을 망가뜨린다면 그것은 해당 프로세스의 중단을 낳게 될 것이다. 하지만 멀티 스레드 방식의 프로그램에서는 하나의 스레드가 자신이 사용하던 데이터 공간을 망가뜨린다면 그 결과는 하나의 데이터 공간을 공유하는 모든 스레드를 작동불능 상태로 만들어 버릴 것이다.
이러한 문제에 대비하기 위해 Critical Section 기법이 존재한다.






Ref.

http://divineprocess.tistory.com/entry/Multi-Thread-구축

http://karlsenchoi.blogspot.kr/2011/02/blog-post_23.html

http://m.blog.naver.com/rja1104/220551216367

Remote branch의 이름은 직접적으로 변경할 수는 없으므로, 아래와 같은 방법을 사용한다.

 

1. Local에 있는 branch 이름 변경하기

git branch -m oldbranch newbranch

2. Remote에 존재하는 oldbranch 삭제하기

git push origin :oldbranch

3. newbranch push 하기

git push origin newbranch

 

 끝!

 

 

'Git' 카테고리의 다른 글

[Git] 커밋 메시지 수정하기 - git rebase  (0) 2020.03.06
[Git] 정의 및 사용방법  (0) 2018.05.29
[Git] .gitignore 적용 안될 경우 해결방법  (0) 2015.03.31

Search와 관련된 3 APIs

  • NSUserActivity
  • Web Markup
  • CoreSpotlight => 이 중에서 Core Spotlight를 자세히 볼 것이다.

Core Spotlight API 사용하기

  • Core Spotlight에 엔트리 저장하기

1. iOS 9에서 사용 가능한 Search API 사용하여 Core Spotlight에 저장이 가능하다.
아래에서 보듯이, 각각의 CSSearchableItem을 만들고 searchableItems라는 임시 어레이에 저장하자.

let attributeSet = CSSearchableItemAttributeSet(itemContentType: "image" as String)
attributeSet.title = person.name
attributeSet.contentDescription = "This is an entry all about the interesting person called \(person.name)"
attributeSet.thumbnailData = UIImagePNGRepresentation(person.image)

let item = CSSearchableItem(uniqueIdentifier: person.id, domainIdentifier: "com.ios9daybyday.SearchAPIs.people", attributeSet: attributeSet)
searchableItems.append(item)

2. CSSearchableIndex에서 indexSearchableItems를 호출하자.
이것은 실제로 사용자들이 검색할 수 있고 그 결과를 볼 수 있도록 CoreSpotlight에 저장하는 것이다.

CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems, completionHandler: 
{ error -> Void in
    if error != nil {
        print(error?.localizedDescription)
} })

3. 다음과 같이 검색 결과를 Core Spotlight에서 볼 수 있다.


  • 사용자에 대한 응답
    spotlight에서 검색 결과를 선택하면, AppDelegate의 continueUserActivity UIAppicationDelegate로 들어오게 된다. 이 곳에 로직을 추가하면 된다. 

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {

    // Find the ID from the user info
    let friendID = userActivity.userInfo?["kCSSearchableItemActivityIdentifier"] as ! String

    // Find the root table view controller and make it show the friend with this ID
    let navigationController = (window?.rootViewController as! UINavigationController)
    navigationController.popToRootViewControllerAnimagted(false)
    let friendTableViewController = navigationController.viewController.first as! FriendTableViewController
    friendTableViewController.showFriend(friendID)

    return true

  }


더 많은 정보



소스코드 - https://github.com/shinobicontrols/iOS9-day-by-day/tree/master/01-Search-APIs
참고 - iOS 9 Day by Day - by shinobicontrols



+ Recent posts