자바에는 기본자료형인 primitive type과 boxed primitive type이 존재한다.

 

java 1.5 이상 부터 primitive type과 boxed primitive type간의 autoboxing과 autounboxing을 제공한다.

 

memory 영역으로 나뉘어 보면, primitive type은 stack 영역에 저장된다. 반면, boxed primitive type은 내부적으로 primitive type을 갖고 있는 wrapping된 class이므로 heap영역에 저장된다.

 

 

Primitive Type

- 스택 영역에 저장되기 때문에, 메모리 효율성과 접근면에서 뛰어나다.

 

 

 

boxed Primitive Type

- collection에서 사용할 떄는 Primitive type을 사용할 수 없으므로 boxed primitive type을 사용해야한다.

 

- 명시적으로 null을 주입해야 할 경우

    ex) db에 명시적으로 null을 넣고자 할 때 int(primitive type)를 사용하면 기본 값(0)이 적용된다. 

 

- parameterized type을 사용할 때

   ex) List<Long>

 

- boxed primitives는 Wrapping Object이므로, 비교연산(==)에 주의하자.

 

 

Caching

- boxed primitive type에서는 자주 사용하는 값에 대해 Caching 기능을 갖고 있다.

 

 

 

Long 객체의 내부 코드를 살펴보면, -128~127 사이의 값을 Caching 해두고 있는데 범위 내의 값을 비교할 땐 미리 생성해 둔 객체로 비교를 한다.

 

    public static void main(String[] args){
        Long a = 127l;
        Long b = 128l;

        Long boxA = Long.valueOf(127);
        Long boxB = Long.valueOf(128);

        System.err.println(a==boxA);    //TRUE
        System.err.println(b==boxB);    //FALSE    

    }

 

 

위의 예제를 통해 살펴보면, 해당 값의 범위를 벗어 나면 비교연산에 실패하게 되므로 주의 해야한다.

Reflection

- Java에서 지원하는 API로, 객체를 통해 클래스의 정보를 분석해 낼 수 있다.
- 즉, 실행중인 Java Application의 Class 정보를 동적으로 접근하여 메소드, 필드 등에 접근하거나 인스턴스를 다룬다.

- 대표적인 예로 Spring의 Bean들은 Reflection을 통해 인스턴스들이 다뤄진다.

 

실제로 org.springframework.beans.annotation.AnnotationBeanUtils 클래스 내부를 보면 bean의 properties를 copy하는 메소드를 찾을 수 있는데, Object 타입의 bean과 java.lang.reflection.Method를 통해 bean의 메소드들이 다뤄지는 것을 확인할 수 있다.

/**
	 * Copy the properties of the supplied {@link Annotation} to the supplied target bean.
	 * Any properties defined in {@code excludedProperties} will not be copied.
	 * <p>A specified value resolver may resolve placeholders in property values, for example.
	 * @param ann the annotation to copy from
	 * @param bean the bean instance to copy to
	 * @param valueResolver a resolve to post-process String property values (may be {@code null})
	 * @param excludedProperties the names of excluded properties, if any
	 * @see org.springframework.beans.BeanWrapper
	 */
	public static void copyPropertiesToBean(Annotation ann, Object bean, @Nullable StringValueResolver valueResolver,
			String... excludedProperties) {

		Set<String> excluded = new HashSet<>(Arrays.asList(excludedProperties));
		Method[] annotationProperties = ann.annotationType().getDeclaredMethods();
		BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(bean);
		for (Method annotationProperty : annotationProperties) {
			String propertyName = annotationProperty.getName();
			if (!excluded.contains(propertyName) && bw.isWritableProperty(propertyName)) {
				Object value = ReflectionUtils.invokeMethod(annotationProperty, ann);
				if (valueResolver != null && value instanceof String) {
					value = valueResolver.resolveStringValue((String) value);
				}
				bw.setPropertyValue(propertyName, value);
			}
		}
	}

 

 

샘플 예제

 

간단하게 샘플 예제를 구현해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
class Calculator {
    private String name;
      
    public Calculator() {
        System.out.println("call Calculator()");
    }
    
    public int add(int a, int b) {
        System.out.println("call add()");
        int result = a + b;
        return result;
    }
    public int minus(int a, int b) {
        System.out.println("call minus()");
        int result = a - b;
        return result;
    }
}
 
public class ReflectionTest {
    
    public static void main(String[] args) throws Exception {
    
        
        Class<?> cls = Class.forName("Calculator");
        
        Field[] fields = cls.getDeclaredFields();
        
        for(Field field: fields) {
            System.out.println("field="+field.getName());
        }
        
        Calculator calculator = new Calculator();
        Method[] methods = cls.getDeclaredMethods();
        
        for(Method method: methods) {
            Object s = method.invoke(calculator, 4,3);
            System.out.println("result=" + s);
        }
        
        System.out.println("Class="+cls.getName());
    }
 
}
 
cs

 

field=name

call Calculator()

call add()

result=7

call minus()

result=1

Class=Calculator

 

 

 

 

장점

 

확장: 확장 가능한 인스턴스를 만들어 외부 사용자 정의 클래스를 작성 할 수 있다.
디버깅 및 테스트: 디버거는 리플렉션 속성을 사용하여 클래스의 private memeber를 체크할 수 있다.

 

 

단점

 

성능 : reflection은 성능이 느리므로 성능에 민감한 프로그램이라면, 자주 호출되는 코드에서는 피하는 것이 좋다.
내부 노출 : reflection은 클래스 추상화를 손상 시킬 수 있다. 즉, 클래스 코드의 변경이 있으면 동작의 변경이 따를 수 있다.

 

 

 

https://docs.oracle.com/javase/tutorial/reflect/index.html

 

Trail: The Reflection API (The Java™ Tutorials)

Uses of Reflection Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine. This is a relatively advanced feature and should be used only by developers

docs.oracle.com

 


Defualt Method

- 디폴트 메소드는 자바8 에서 더 유연하게 인터페이스를 만들 수 있도록 추가한 방법이다.

- 자바 8 이전에는 인터페이스의 메소드는 반드시 모두 상속해야만 했다. 

- 자바8 에서는 default라는 키워드를 통해 디폴트 메소드를 지정할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

interface Calcuator {
 
 default void add(int a, int b) {
        System.out.println((a+b));
    }
 
    default void minus(int a, int b) {
        System.out.println((a-b));
    }
}
 
 
 
 
public class Test implements  Calcuator{
      public void cal(){
           add(3,5);
       } 
}
    
 
cs

위와 같은 방법으로 상속받은 Calculator 인터페이스는 add, minus 라는 디폴트 메소드를 호출 할 수 있다.

또한 그동안 자바에서는 다중상속이 불가능한 것으로 알려져 있던 것을, 디폴트 메소드를 통해 어느정도 구현할 수 있다. 하지만 다이아몬드 상속 문제를 반드시 피해야 하는데 만일 인지하지 못할 경우 다음과 같은 컴파일 에러가 날 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 

interface
 Calcuator {
 
    default void add(int a, int b) {
        System.out.println((a+b));
    }
 
    default void minus(int a, int b) {
        System.out.println((a-b));
    }
 
}
 
interface  DoubleCalculator {
    default void add(int a, int b) {
        System.out.println((a+b)*2);
    }
 
    default void minus(int a, int b) {
        System.out.println((a-b)*2);
    }
 
 
}
 
/**
 * 디폴트 메소드로 인해 어느 정도 다중 상속 개념이 될 수 있다. 다이아모몬드 상속 문제를 피해야한다.
 */
public class DefaultMethod implements  Calcuator, DoubleCalculator{
 
   
    public void cal() {
        add(3,5);
        minus(3,6);
    }
}
 
cs


위와 같은 경우, 컴파일 시 에러가 나는데   Interface의 상속을 통해 Override를 통해 문제를 해결할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
 
interface Calcuator {
 
    default void add(int a, int b) {
        System.out.println((a+b));
    }
 
    default void minus(int a, int b) {
        System.out.println((a-b));
    }
 
}
 
interface  DoubleCalculator {
    default void add(int a, int b) {
        System.out.println((a+b)*2);
    }
 
    default void minus(int a, int b) {
        System.out.println((a-b)*2);
    }
 
 
}
 
interface CalAndDoubleCal extends Calcuator,DoubleCalculator{
 
    @Override
    default void add(int a, int b){
        Calcuator.super.add(a,b);
        DoubleCalculator.super.add(a,b);
    };
    @Override
    default void minus(int a, int b) {
        Calcuator.super.minus(a,b);
        DoubleCalculator.super.minus(a,b);
    }
 
}
 
 
public class DefaultMethod implements CalAndDoubleCal{
 
    public void cal(){
        add(3,5);
    }
}
cs




함수형 인터페이스(Functinal Interface)

- 오직 하나의 추상 메소드를 지정한다.

- @Functional Interface 를 붙이는 것을 권장한다.

- 람다식 사용 가능


Predicate<T>

Java.util API 내부를 살펴보면 test라는 하나의 추상 메소드만 지정된다.  test는 제네릭 형식의 T 객체를 인수로 받아 boolean을 반환한다.

또한 Predicate 인터페이스는 복작한 predicate를 만들 수 있도록 negate, and, or 메소드를 제공하는데 이는 default 메소드이다.


1
2
3
4
5
6
7
8
        //predicate
       Predicate<String> nonEmptyString = s -> !s.isEmpty();
       Predicate<String> emptyString = s -> s.isEmpty();
       System.err.println(nonEmptyString.test("")); //false
       System.err.println(nonEmptyString.and(emptyString).test("")); //두개의 조건을 모두 만족해야하므로 false
       System.err.println(nonEmptyString.or(emptyString).test("")); //둘중 하나만 만족해도 되므로 true
       System.err.println(nonEmptyString.negate().test("")); // nonEmpytyString predicate의 반대상황을 테스트 true
 
cs



Consumer<T>

Java.util API 내부를 살펴보면 accept라는 하나의 추상 메소드만 지정된다.  accept는 제네릭 형식의 T 객체를 인수로 받아 void을 반환한다.


1
2
3
4
5
6
7
        //consumer
        Consumer<String> outConsumer = s -> System.out.println(s);
        Consumer<String> errConsumer = s -> System.err.println(s);
 
        outConsumer.accept("k");  //k
        outConsumer.andThen(errConsumer).accept("g"); // g, g
cs


Function<T,R>

Java.util API 내부를 살펴보면 aaply라는 하나의 추상 메소드만 지정된다.  appy는 제네릭 형식의 T 객체를 인수로 받아 제네릭 형태의 R객체를 반환한다.



1
2
3
4
5
6
7
    //function
        Function<String,String> lowerFunction = s -> s.toLowerCase();
        Function<String,String> upperFunction = s -> s.toUpperCase();
 
        System.out.println(lowerFunction.apply("S"));       //s
        System.out.println(lowerFunction.andThen(upperFunction).apply("S"));    // S
 
cs


'programming > Java' 카테고리의 다른 글

primitive type과 boxed primitives  (0) 2019.11.24
Reflection  (0) 2019.09.20
[JAVA 8] - 함수형 프로그래밍(Functional Programming)  (0) 2019.02.17
# Enum (열거형)  (0) 2018.05.20
# NIO - Selector  (0) 2018.05.19

함수형 프로그래밍 (Functional-style programming)

부수 효과를 없애고 순수 함수를 만들어 모듈화 수준을 높이는 프로그래밍 패러다임

: 부수효과란  주어진 값 이외의 외부 변수 및 프로그램 실행에 영향을 끼치지 않아야 된다는 의미이며, 부수효과를 만족하는 함수를 순수함수라고 한다.


- 순수함수 : 모든 입력이 입력으로만, 모든 출력이 출력으로만 사용
- 비순수함수: 숨겨진 입력이나 출력이 존재


즉 함수형 프로그래밍은 순수함수를 지향, 최대한 숨겨진 입력과 출력을 제거하여 가능한  코드를 입력과 출력의 관계로 사용해야 한다.


객체지향 프로그래밍과 함수형 프로그래밍

1) 객체 지향은 명령형 프로그래밍이고, 함수형 프로그래밍은 선언형 프로그래밍이다.


: 우선 명령형 프로그래밍과 함수형프로그래밍의 차이의 핵심은 문제해결의 관점이다. 기존의 우리가 객체지향 프로그래밍을 할 때는 데이터를 어떻게 처리할 지에 대해 명령을 통해 풀어 나아갔다면, 함수형 프로그래밍은 선언적 함수를 통해 무엇을 풀어나아갈지 결정하는 것이다.


아직 Stream API에 대해 다뤄보진 않았지만, 간단히 샘플 코드를 통해 비교해본다면 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
        List<String> myList =
                Arrays.asList("c1""a2""b3""4""5");
 
        // 기존방식
        for(int i=0; i<myList.size(); i++){
            String s = myList.get(i);
            if(s.startsWith("c")){
                System.out.println(s.toUpperCase());
            }
        }
 
        // stream API를 이용한 방식
        myList.stream()
              .filter(s -> s.startsWith("c"))
              .map(String::toUpperCase)
              .forEach(System.out::println);
 
 
cs


처음보면 크게 와 닿지 않을 수 있지만, 기존 방식과는 많이 다르다. 중요한 점은 프로그래밍 패러다임의 변화이다. 단순하게 함수를 선언함으로써 데이터들을 내가 원하는 방향으로 처리해 나아가고 있다는 점이다. 한눈에 보더라도 함수형프로그래밍을 통해 구현한 아래코드가 무엇을 하고있는지에 대해 명확하다.


2) 함수형 프로그래밍에서 함수는 1급객체 여야 한다.

위키피디아의 정의된 1급객체의 의미를 인용하면..

특정 언어의 일급 객체 (first-class citizens, 일급 값, 일급 엔티티, 혹은 일급 시민)이라 함은 컴퓨터 프로그래밍 언어 디자인에서 일반적으로 다른 객체들에 적용 가능한 연산을 모두 지원하는 객체를 가리킨다.


1급 객체(First class object)란 다음과 같은 조건을 만족하는 객체이다.

  • 변수나 데이터 구조안에 담을 수 있다.
  • 파라미터로 전달 할 수 있다.
  • 반환값(return value)으로 사용할 수 있다.
  • 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
  • 동적으로 프로퍼티 할당이 가능하다.
  • 기존 데이터의 불변성(Immutable)


자바에서 그동안 함수는 메소드를 값으로 표현할 수 없어 1급 시민이 아닌 2급 시민으로써 역할 해왔다. 하지만 자바8에서 함수는 1급시민이 되어 함수형 프로그래밍의 핵심이 되었다.


사실 위의 2가지 특징이 함수형 프로그래밍의 모든 것을 나타낸다고 생각하는데, 위의 특징이 단점이 될 수도 있다. 예를 들면, 덕분에 코드의 간결성이 증가되었지만 그만큼 학습의 필요로 한다. 함수형 프로그래밍을 학습하는 것은 결코 쉽지 않기 때문에 오랜 학습이 필요하다.



Java 8만의 3가지 기술

- 인터페이스의 디폴트 메소드

- 메소드 레퍼런스, 람다

- Stream API




참조

- https://velog.io/@kyusung/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9A%94%EC%95%BD#%EB%AA%85%EB%A0%B9%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EA%B3%BC%EC%9D%98-%EB%B9%84%EA%B5%90

- Java8 in action


django framework


파이썬 기반의 무료 오픈소스 웹 애플리케이션 프레임워크(Open Source Web Application Framework)


- 빠른 개발, 쉬운 구축 (개발 비용감소)


- 확장성, 보안


- 기본적인 admin 기능의 구현



-하지만 좋지 않은 성능




Architecture


- MVC 패턴 기반 MVT 아키텍처






  1. Model : data 구조 혹은 스키마

  2. View : MVC 의 Controller에 해당 

  3. Template : MVC의  view에 해당








Structure








  • sample2 : root project

  • managy.py : django와 상호작용하는 커맨드라인 유틸리티

  • settings.py: 환경 구성

  • urls.py: url선언에 대한 저장. url dispatcher 구성

  • wsgi.py : WSGI 호환 웹서버의 진입점




https://docs.djangoproject.com/ko/1.11/intro/tutorial01/


https://zetawiki.com/wiki/%EC%9E%A5%EA%B3%A0_manage.py_%EB%AA%85%EB%A0%B9%EC%96%B4




'programming > Python' 카테고리의 다른 글

pyenv를 통한 python 개발환경 구성  (0) 2018.12.12
HOST, IP Address 간단하게 활용  (0) 2018.06.16
Python 주요사항 및 특징  (0) 2018.06.13


MacOS 기준 설치

$ brew install pyenv

$ brew upgrade pyenv





path 설정 - 설치시 나오는 문구로 설정

$ vi ~/.bash_profile




>> if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi



=> 설치 시 나오는 문구를 적용하면 된다.






pyenv를 통한 설치 가능 리스트


$ pyenv install --list





virtualenv 설치 및 설정 - 설치시 나오는 문구로 설정

$ brew install pyenv-virtualenv



$ vi ~/.bash_profile



>> if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi




! virtaulenv 는 프로젝트마다 가상환경을 구성할 수 있는 가상환경을 제공한다.





virtualenv 목록


$ pyenv virtualenvs





virtualenv 만들기


$ pyenv install 3.6.5

$ pyenv virtualenv 3.6.5 python-3.6.5


--> pyenv virtualenv [version] [naming]






virtualenv 시작 및 종료


$ pyenv activate python-3.6.5 << 시작

$ pyenv deactivate                 << 종료





alias를 통한 시작 및 종료

$ vi ~/.bash_profile


>> alials p3on='pyenv activate python-3.6.5'

>> alias poff='pyenv deactivate'


$ p3on


$ poff






Jupyter Notebook & Bpython pip install

$ p3on

$ pip install --upgrade pip

$ pip install bpython


$ bpython                     << 실행


$ pip install jupyter


$ jupyter notebook            << 실행




'programming > Python' 카테고리의 다른 글

django framework overview  (0) 2019.01.28
HOST, IP Address 간단하게 활용  (0) 2018.06.16
Python 주요사항 및 특징  (0) 2018.06.13



local host Name 및 IP , Remote Host 와 IP 구하기


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import socket
 
def print_mynetwork_info():
    host = socket.gethostname()
    ip_addr = socket.gethostbyname(host)
    print('HOST:' + host)
    print("ip Address:" + ip_addr)    
 
def print_remoteNetwork_info():
    remote_host = 'www.naver.com'
    remote_ip = socket.gethostbyname(remote_host)
    try:
        print(remote_host)
        print(remote_ip)
    except socket.error as identifier:
        print('error msg:' + expression)
        #예외 무시
        pass
    except:
        print('all eror')
        #예외 무시
        pass    
    finally:
        print('end')
 
 
if __name__ == '__main__':
    print_mynetwork_info()
    print_remoteNetwork_info()
cs



>>

HOST:myHost

ip Address:192.168.0.24

www.naver.com

210.89.160.88

end





로우 레벨의 네트워크 함수를 다루는 경우 IP 주소의 일반적인 문자열 표기 방식은 많이 사용하지 않는다. 이 문자열을 32비트의 바이너리 형식으로 변경해야한다.




IPv4 주소를 다른 포맷으로 변환


파이썬의 소켓 라이브러리는 여러가지 IP주소포맷을 다룰 수 있는 유틸리티 함수를 가지고 있고, 여기서 inet_aton()과  inet_ntoa()를 사용할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import socket
from binascii import hexlify
 
def convert_ipAddress():
    host = socket.gethostname()
    ipAddr = socket.gethostbyname(host)
    packed_ip = socket.inet_aton(ipAddr)
    unppcked_ip = socket.inet_ntoa(packed_ip)
 
    print(ipAddr)
#바이너리 데이터를 16진수로 표현
    print(hexlify(packed_ip))
    print(unppcked_ip)
 
 
if __name__ == '__main__':
    convert_ipAddress()
cs




>>

192.168.0.24
b'c0a80018'
192.168.0.24




호스트와 네트워크 바이트 순서에 맞게 정수 변환

호스트의 운영체제로부터 얻은 데이터를 네트워크 바이트 순서로 변환하거나 반대로 변환하는 작업을 수행하는 경우가 있는데, 운영체제 혹은 네트워크 환경에 따라 데이터의 포맷의 표현방식이 각자 다르기 때문이다.

네트워크 바이트 순서 = 시스템이 내부적으로 데이터를 표현하는 방법 



1
2
3
4
5
6
7
8
9
10
11
import socket
 
def convert_integer():
    data=1234
    # 32-bit long
    print ('original: %s -> long host byte order: %s, network byte order:%s' %(data,socket.ntohl(data),socket.htonl(data)))
    # 16-bit short
    print ('original: %s -> long host byte order: %s, network byte order:%s' %(data,socket.ntohs(data),socket.htons(data)))
 
 
convert_integer()
cs



>>

original: 1234 -> long host byte order: 3523477504, network byte order:3523477504

original: 1234 -> long host byte order: 53764, network byte order:53764










참고 서적 : 파이썬을 활용한 네트워크 프로그래밍


'programming > Python' 카테고리의 다른 글

django framework overview  (0) 2019.01.28
pyenv를 통한 python 개발환경 구성  (0) 2018.12.12
Python 주요사항 및 특징  (0) 2018.06.13


Python


- 파이썬은 1991년 발표된 인터프리터 방식의 프로그래밍 언어이다. 


- 인터프리터란 코드 한줄 한줄 읽어가며 실행하는 프로그램이고 실행하는 도중 에러가 나면 다음 코드는 실행되지 않는다.


- 즉, 파이썬은 스크립트 기반의 언어이다.


- 2000년도에 python2, 2008년도에 python3가 나왔다.




특징


- 명시적이고 심플하며 간결하다.


- 그렇기 때문에 높은 생산성을 가지고 있다.


- 문법이 굉장히 쉽다.


- 하지만 문법이 엄격하다. 예를 들면, 들여쓰기가 의무 규칙이고 자체가 하나의 코드 블럭이 되기 때문에 tab문자를 사용하지 않도록 권장한다.


- PEB-8에 명시된 공식 코딩 가이드에서는 스페이스 바로 공백 4문자를 넣기를 권장한다.


- 반복 가능한 객체. 이것은 파이썬의 가장 큰 특징 중 하나이다.

 : 파이썬에서는 반복가능한 객체(iterable)라는 강력한 기능을 제공하며 집합,문자열,리스트,함수 등 반복을 가능하게 한다.


- 가상 머신 위에서 실행되기 때문에 실행속도는 느린편이다. 

 : 가상 머신은 3.3 버전 이후 pyvenv를 사용한다.


- 다양하고 많은 라이브러리를 지원한다.




병렬 처리


- 기본적으로 파이썬 프로그램은 하나의 쓰레드에서 실행된다. (Single Thread)


- 쓰레드 클래스에서 daemon 속성은 서브쓰레드가 데몬 쓰레드인지 아닌지를 지정하는 것인데, 데몬 쓰레드란 백그라운드에서 실행되는 쓰레드로 메인 쓰레드가 종료되면 즉시 종료되며, 데몬 쓰레드가 아니라면 서브 쓰레드는 메인 쓰레드가 종료되도 자신의 작업이 끝날 때까지 계속 실행된다.


- 파이썬은 멀티스레딩을 지원하기 위해 GIL(Global Interpreter Lock)을 도입하여 사용하게 되었다. 따라서 python  스레드 10개를 만들어도 실제 10개가 만들어져도 GIL때문에 하나밖에 안돌아가는 현상이 있다. 뿐만 아니라 여러 성능 문제도 존재하기 때문에 파이썬에서의 병렬처리는 다중 스레드가 아닌 다중 프로세스로 GIL을 우회하는 방식을 사용한다.


네트워크 프로그래밍을 수행할 경우 파이썬의 동시성 및 병렬성에 대해 자세히 알아봐야 할 것 같다.




Python2 vs Python3


- 특이하게 python3는 python2와 호환되지 않는다.


- python2에는 많은 문제와 취약점을 갖고 있다.


- python3.x 부터 모든 문자는 유니코드 처리한다. 유니코드 특성상 2바이트 혹은 4바이트를 차지하는데 2.x 는 기본 1바이트이기 때문에 속도차이는 당연히 날 것이고 이 문제를 해결하기 위해 3.3 버전 이후부터 문자열 객체에서 가장 많은 바이트를 차지하는 문자를 기준으로 각 문자가 차지할 공간을 정하도록 변경되었다.




PEP


- PEP 이란 Python Enhancement Proposals 약자로서 파이썬을 개선하기 위한 제안서를 의미한다. 이러한 PEP 다음과 같이 크게 3 종류로 구분할 있으며, Python Software Foundation 공식 웹사이트인 python.org 에서 관리한다


- 특히 파이썬 코딩에 관련된 제안서는 PEP-8 에서 확인 할 수 있다.




FrameWork


Django : 풀 스택 웹 프레임워크

Flask : 마이크로 웹 프레임워크

Pygame : 파이썬으로 비디오 게임을 제작하기 위한 프레임워크






개발환경


파이썬 IDLE, Atom, SublimeText, VisualStudio Code, Eclipse-PyDev







앞으로 파이썬을 통해 주로 다뤄보고자 하는 것은  파이썬을 통한 네트워크 프로그래밍과 Django 프레임워크이다.








참고


http://pythonstudy.xyz/python/article/24-쓰레드-Thread

https://namu.wiki/w/Python



'programming > Python' 카테고리의 다른 글

django framework overview  (0) 2019.01.28
pyenv를 통한 python 개발환경 구성  (0) 2018.12.12
HOST, IP Address 간단하게 활용  (0) 2018.06.16

+ Recent posts