728x90
추상 클래스 (abstract class)

추상 클래스 (abstract class)

  • 구현할 클래스의 명세를 정의 : 하위 클래스에서 구체 사항을 구현
    • 실제로 구현되지는 않음
    • ex. abstract class Vehicle : 하위 클래스로 차량의 클래스인 차량, 오토바이 등을 구현
    • open 키워드 없이 상속 가능
abstract class Vehicle(val name : String, val color : String, val weight : Double) //primary constructor 속 프로퍼티는 abstract가 아님 { abstract val maxSpd : Double //추상 프로퍼티 : 하위 클래스에서 override해야 함 abstract fun start() abstract fun stop() // 추상 메소드 : 하위 클래스에서 구현해야 함 fun display() { println("$name / $color / $weight") }//비 추상 메소드 : 하위 클래스 모두가 해당 구현물을 갖게 됨 } class Car(name : String, color : String, weight : Double, override val maxSpd : Double) : Vehicle(name, color, weight) //상속 선언(maxsPd override 포함) { override fun start() { println("car start") } override fun stop() { println("car stop") } }
  • object를 이용한 추상 메소드 구현
abstract class Printer { abstract fun print() } val myPrinter = object : Printer() { override fun print() println("출력!")//하위 클래스 선언 없이 임시로 추상 메소드 구현 가능 }

인터페이스

  • 해야 하는 작업에 대한 추상적 명세
    • 클래스가 아니므로 다중 상속 가능
    • 강한 연관을 갖지 않음
interface Pet //인터페이스 상속 시 ': 인터페이스명' 추가 { //abstract 없이도 프로퍼티/메소드 선언됨 var category : String fun feeding() //다만 메소드는 내용 작성 시 일반 메소드로 동작 fun patting() { println("Keep patting!") } } class Cat(override var category : String) : Pet { override fun feeding() { println("Feed cat tuna!") } //patting은 인터페이스에서 선언되었으므로 오버라이드가 없어도 됨 }

데이터 클래스

  • 데이터 전달을 위한 객체 DTO(Data Transfer Object)
    • 자바에서는 POJO(Plain Old Java Object)
    • 구현 없이 데이터를 표현
    • 데이터를 접근하는 게터/세터 포함
  • 코틀린의 데이터 클래스 : 프로퍼티 = 필드 + 게터, 세터
  • 자동 생성 메소드
    • 게터, 세터
    • 비교를 위한 equals(), 키를 위한 hashCode()
    • 프로퍼티를 문자열로 보여주는 toString()
    • 객체 복사를 위한 copy()
    • 프로퍼티에 상응하는 component1(), component2(), ...
  • 선언 방식 : data class 이름(프로퍼티)
    • 주 생성자는 최소 하나의 매개변수를 가져야 함
    • 주 생성자의 모든 매개변수는 val, var 프로퍼티여야 한다
    • 데이터 클래스는 abstract, open, sealed, inner 키워드를 쓸 수 없음
data class Customer(var name : String, var email : String) { var job : String = "unknown" constructor(name : String, email : String, __job : String) : this(name, email) { job = __job } // 부 생성자 : 프로퍼티 선언 init { // init : 간단한 로직 선언 가능 } } val cus1 = Customer("kim", "kim@mail.com") val cus2 = Customer("kim", "kim@mail.com") println(cus1 == cus2) //동등성 비교, true 반환 println(cus1.equals(cus2)) //위와 동일 println("${cus1.hashCode(), ${cus2.hashCode()}}") // 고유값 동일 - 두 객체의 값이 동일하므로 참조하는 위치도 동일함 val cus3 = cus1.copy(name = "alice") // cus1 내용을 복사하면서 name만 새 값을 대입
  • 디스트럭처링(destructuring) : 객체의 프로퍼티를 개별 변수로 분해
val (name, email) = cus1 val (_, email) = cus1 // 특정 프로퍼티가 필요 없는 경우 val name = cus1.component1() //cus1의 1번째 component(name) 반환 val customers = listOf(cus1, cus2) //DTO가 많은 경우 리스트화 후 반복문 사용 for((name, email) in customers)

내부 클래스와 중첩 클래스

  • 코틀린의 내부 클래스
    • 중첩(Nested) 클래스 : 객체 생성 없이 이용 가능
      • 외부 클래스 생성 없이 내부의 nested 객체를 생성할 수 있음
      • 외부 클래스에 companion object를 갖고 있을 경우 해당 객체에 접근 가능
    • 이너(inner) 클래스 : 필드, 메소드와 연동하는 클래스(inner 키워드 필요) - 외부 클래스 프로퍼티에 접근 가능
      • 클래스 내에 키워드 없이 선언 시 nested class로 선언됨, 내부 클래스는 외부에 접근이 불가능하게 됨
      • 바깥 클래스의 private 멤버도 접근 가능
    • *익명 객체 : 일회용 객체 선언을 위해 object 키워드 사용

지역 클래스와 익명 클래스

  • 지역 클래스(Local Class)
    • 특정 메서드 블록이나 init블록과 같이 그 안에서만 유효한 클래스
      • 블록 범위 내에서는 사용되지 않음
class Smartphone(val model:String) { fun powerOn() : String class Led(val color : String) { fun blink() : String = "Blink $color on $model" }//지역 클래스 - 외부 프로퍼티에 접근 가능 val powerStatus = Led("Red") return powerStatus.blink() }
  • 익명 클래스(Anonymous Class)
    • 일회적으로 객체를 생성해 사용
    • 메모리 효율 혹은 개발 속도(오버라이딩 구현) 면에서 사용

실드 클래스와 열거형 클래스

  • 실드(Sealed) 클래스
    • sealed 키워드를 사용
    • 그 자체로는 추상 키워드와 같이 객체 생성은 불가
    • 기본 생성자는 private, 그 외에는 불허
    • 같은 파일 내에서만 상속 가능
    • 블록 내의 클래스는 필요한 경우 open 키워드로 선언하여 상속 가능
    • 주로 상태의 정의와 관리에 사용
sealed class Result { open class Success(val message : String) : Result() //해당 클래스는 상속 가능 class Error(val code : Int, val message : String) : Result() } class Status : Result() // 같은 파일에서만 상속 가능 class Inside : Result.Success("Success") // 내부 클래스 상속
  • 열거형 클래스(enum class)
    • 여러 상수를 선언하고 조건에 따라 값을 선택 가능
    • 동일한 자료형의 상수 나열 가능
enum class 이름(생성자) { 상수1(값), 상수2(값), 상수3(값), ... //값은 선택 가능 }
  • 어노테이션 클래스
    • 코드에 부가정보 추가
    • @기호를 이용하여 사용
    • 컴파일러나 프로그램 실행 시 사전 처리
      • @Test : 유닛 테스트
      • @JvmStatic : 자바 코드에서 컴패니언 객체 접근
728x90
728x90
마크다운을 이용해 필기를 해보자

마크다운을 이용해 필기를 해보자

  • 연초에 마크다운의 존재를 처음 알고 쏠쏠히 써먹는 중이다.
  • 단순히 메모장으로 필기하는 것보다는 '조금' 더 상세하게 필기가 가능한데, 특히 코드 하이라이트나 VSCode extension을 이용한 이미지 붙여넣기 등의 기능 추가가 꽤 쏠쏠한 편이다.

  • 먼저 VScode를 설치한다. 다른 편집기도 많이 있긴 한데(StackEdit 등등...) 나는 이걸 쓰는게 다른 언어로 빨리 넘어가기도 좋고 해서 사용하는 편이다.
  • 설치할 익스텐션은 총 두개다 : Markdown All in One, Markdown Paste
  • 두 익스텐션까지 설치하고 나면, 이제 파일명.md로 파일 편집을 진행하면 된다.

간단한 마크다운 문법


#의 개수로 제목의 크기 조절이 가능하다(보통 2개까지가 유의미한 차이인듯)

# 1개

# 2개

# 3개

# 4개

#5개

-, +, *으로 글머리표를 쓸 수 있다.

  • 이렇게
  • 이렇게
  • 이렇게

숫자로도 순서가 있는 글머리표가 가능하다.

  1. 이렇게
  2. 이렇게
  3. 이렇게

-를 3번 쓰면 구분선이 생긴다


이렇게

`를 3번 쓰면 코드 하이라이트가 된다. 그 뒤에 언어 이름을 붙이면 해당 언어로 하이라이트가 된다.

//```c #include <stdio.h> int main(void) { printf("hello, world!"); }

꺽쇠 표시(>)를 쓰면 인용구로 사용할 수 있다.

이렇게

  • 달러 표시 사이에 있는 글들은 논문을 쓸 때 쓰는 tex 문법을 사용할 수 있다 : $$

    • 1, 12\sqrt1,\ \frac{1}{2}
  • 위에서 설치한 markdown paste는 복사한 이미지를 간단하게 붙여넣을 수 있다. ctrl+alt+v로 붙여넣으면 된다(다만 시간이 좀 걸릴 수 있다)

  • markdown all in one의 기능 중 md파일을 html로 바꾸는 기능이 있다. 이 기능을 이용하면 티스토리 글쓰기에 html 기능으로 작성한 글을 옮길 수 있다(테마에 따라 지원이 완전히 되지 않을 수 있다.)

  • 링크는 대괄호에 [표시할 이름]을, 소괄호에 (링크)를 넣는다. [ ] ( )이런 식으로(사이 공백은 붙인다.) : 이 글로 다시 돌아오는 링크

  • 이외에도 많은 문법이 있는데, 구글에 검색하면 많으나 컴퓨터로 기록할때는 이정도를 주로 쓰고 있다. 너무 악필이다 보니 컴퓨터 기록 방법을 고뇌하다 찾았는데, 생각보다 너무 유용하게 쓰이는 듯.

  • md 파일은 Github 웹사이트를 만들 때도 쓸 수 있는데, Github의 경우 티스토리보다 손이 좀 많이 가다 보니(웹사이트 구축에서 막히기 시작하니까 흥미가 훅 떨어지더라...) 그냥 티스토리에 아예 정착한 상황이다. md파일이 있으니 원할 때 그대로 옮겨갈 순 있을 것 같긴 한데, 티스토리가 섭종하지 않는 한은 그냥 이대로 갈 것 같다.

728x90
728x90
프로퍼티의 접근 - Setter, Getter

프로퍼티의 접근 - Setter, Getter

  • 자바의 필드 : 접근 메소드를 필요로 함
  • 코틀린의 프로퍼티 : 변수 선언 외에 접근 메소드가 별도로 있음
    • Getter/Setter : 코틀린의 프로퍼티 접근 메소드
class Person(var name: String, var age: Int) // 클래스 선언 fun main() { val user = User("Kim", 20) val name = user.name //getter에 의한 프로퍼티 반환 user.age = 25 //setter에 의한 프로퍼티 값 변경 }
  • 게터와 세터의 설정 원리 : 변수 설정 시 get(), set()이 각각 자동으로 선언됨
    • 아래 양식처럼 암묵적으로 선언되며 같은 양식대로 직접 커스텀할 수 있음
Class bar(...) { val A : Int //불변형은 getter만 선언됨 get() = field /* 프로퍼티를 get에 대입 시 무한 재귀 호출이 되기 때문에, 프로퍼티를 가리키는 변수인 field로 별도로 선언됨 */ var B : Int //가변형은 get, set 모두 선언됨 get() = field set(value) { field = value } }

지연 초기화

  • 클래스의 프로퍼티는 null일 수 없으므로 객체 생성 시 초기화가 필요한데, 객체 정보가 나중에 나타나는 경우 나중에 초기화할 방법이 필요
  • lateinit, lazy 키워드로 지연된 초기화 가능
  • lateinit
    • 클래스 간의 의존성이 있는 경우 (특정 클래스가 생성되어야 초기화할 수 있는 경우)
    • 테스트를 위해 임시로 객체를 생성해야 하는 경우
    • var형 프로퍼티만 가능
    • 초기화 전에는 프로퍼티의 getter, setter 사용이 불가
class Person { lateinit var name : String fun test() { if(~::name.isInitialized) println("not initialized") //초기화 여부 확인 else println("initialized") } } fun main() { val kildong = Person() kildong.test() //"not initialized" kildong.name() = "Kildong" //isInitialized = true kildong.test() //"initialized" } ///////////////////////////////////////////////////////// // lateinit을 이용한 클래스 생성의 지연 초기화 data class Person(var name : String, var age : Int) lateinit var person1 : Person //클래스 지연 초기화 fun main() { person1 = Person("Kildong", 30) //생성자 호출 시점에 초기화 }
  • lazy : 호출 시 by lazy로 지연 초기화
    • val에서만 사용 가능, 초기화 후값 변경 불가
    • lazy 키워드의 모드
      • by lazy(mode = SYNCHRONIZED) : 단일 스레드의 사용 보장
      • by lazy(mode = PUBLICATION) : 여러 곳에서 호출될 수 있으나 처음 초기화된 값 사용
      • by lazy(mode = NONE) : 락이 되지 않으므로 여러 스레드의 접근이 가능하나 값이 일관되지 않을 수 있음
class Lazytest { init {println("init block")} val subject by lazy { println("lazy init") "kotlin programming"//subject 접근 시 대입됨 } fun flow() { println("not init") println("subject : $subject") // 이 시점에서 subject가 초기화됨 } } fun main() { val test = Lazytest() test.flow() }
  • by를 이용한 위임
    • 람다식을 사용
    • 한 클래스가 다른 클래스에 위임
    • 위임된 클래스 멤버는 참조 없이 호출
    • <var|val|class> 이름 : 자료형 by 위임자
  • 위임을 쓰는 이유
    • 코틀린 라이브러리는 open되지 않은 클래스(상속 불가)
    • 표준 라이브러리의 복잡한 상속을 방지하나, 기능 확장이 어려움
    • 위임 사용 시 : 클래스 기능에 추가 기능을 구현 가능
interface Animal() { fun eat() {...} } class Cat = Animal() val cat = Cat() class Robot = Animal by cat //RobotCat의 멤버를 사용 가능
  • 위임의 특수 키워드
    • observable : 프로퍼티를 보다가 변경 발생 시 호출
    • vetoable : 반환값에 따른 변경 허용 및 취소
import kotlin.properties.Delegates class User { var name : String by Delegates.observable("NONAME")//observable 매개변수로 name 초기값 설정 { prop, old, new -> //프로퍼티, 기존값, 새로운 값을 매개로 받음 println("$old->$new") //이벤트 발생(name값의 변화) 시 실행 } }

정적 변수와 메서드

  • 코틀린의 클래스는 동적으로 생성
  • 동적 초기화 없이 사용 가능한 변수 = 정적 변수 : 코틀린에서는 컴패니언 객체라고 칭함
  • 사용하지 않아도 메모리에 상주하므로 자주 사용하는 객체에 대해 사용
class Person { var id : Int = 0 var name : String = "kim" companion object // 컴패니언 객체 : 객체 생성 없이 접근 가능 { var lang : String = "Kor" fun work() { println("working") } } } fun main() { println(Person.lang) //인스턴스 생성 없이 출력 가능 Person.lang = "Eng" //변경 가능 Person.work() //메소드 실행 가능 println(Person.name) //name은 companion이 아니므로 에러 }
728x90
728x90
클래스와 객체의 정의

클래스와 객체의 정의

  • 객체지향 : 절차 중심의 코드를 구조적으로 하고자 함
    • 구조적인 코드 구조를 클래스 / 객체를 이용하여 실제 세계와 비슷하게 작성
    • 객체와 그 관계를 표현하여 확장 - 재사용이 용이
  • 객체지향 용어
    • 추상화(abstraction) : 어떠한 내용을 개념화하는 작업 - 클래스의 기본 형식 구성
    • 인스턴스(Instance) : 클래스 객체 생성
    • 상속(Inheritance) : 부모 클래스의 내용을 자식 클래스로 물려받음
    • 다형성(polymorphism) : 하나의 이름으로 다양한 처리를 제공
    • 캡슐화(encapsulation) : 메소드 내용은 외부 사용자가 접근할 수 없게 함
    • 메시지 전송 : 객체 간의 데이터 교환
    • 연관 : 클래스 간의 관계
  • 언어 별 동의어(코틀린 : 그 외 언어들)
    • 클래스 : 분류, 범주
    • 프로퍼티(Property) : 속성(Attribute), 변수(Variable), 필드(Field), 데이터(Data)
    • 메서드(Method) : 함수(Function), 동작(Operation), 행동(Behavior)
    • 객체(Object) : 인스턴스(Instance)

클래스 생성자 (Constructor)

  • 클래스 생성 시 호출되는 함수
    • 객체 생성 시 필요한 값을 인자로 설정 가능
  • 주 생성자(Primary Constructor) : 클래스명과 함께 기재, 보통 constructor 키워드는 생략 가능
  • 부 생성자 (Secondary Constructor) : 클래스명 본문에 기재, 하나 이상의 부생성자를 정의 가능
class Bird { //프로퍼티 var name : String = "noname" var wing : Int //생성자 constructor(name:String, wing : Int) { this.name = name //생성자, 메소드에서 클래스 프로퍼티 참조 this.wing = wing } //메소드 fun fly() { println("Fly!") } } fun main() { val coco = Bird("coco", 2) coco.fly() }

상속(Inheritance)

  • 자식 클래스가 상위(부모) 클래스 내용을 계승
  • 상위 클래스의 프로퍼티와 메소드가 하위로 적용됨
  • open class (class명) : 클래스를 상속 가능한 상태로
    • class (클래스명) : (상위 클래스명) : 클래스 상속
    • 코틀린 클래스는 묵시적으로 Any 클래스로부터 상속됨
open class Bird(var name : String, var wing : Int) //pri. Constructor, 프로퍼티 선언한 상위 클래스 { fun fly() { println("Fly!") } } class Lark(name : String, wing : Int) : Bird() //클래스 상속 : 상위 클래스의 프로퍼티와 동일하게 Construct { fun singalong { print("sing together") } } class Parrot : Bird() { var language : String //만약 하위 클래스에 새 프로퍼티 추가 시 별도로 선언 constructor(name : String, wing : Int, language : String) : super(name, wing) //부생성자로 클래스 상속 시 super 키워드 사용 { this.language = "..." } fun speak() { println("hello?") } } fun main() { var lark = Lark("mylark", 2) var parrot = Parrot("myparrot", 2, "Eng") }

다형성(Polymorphism)

  • 같은 이름을 사용하지만 매개변수가 다른 함수
    • 하나의 이름으로 여러 기능 수행
    • static polymorphism : 컴파일 시점의 다형성, 메소드 오버로딩
    • dynamic polymorphism : 런타임 다형정, 메소드 오버라이딩
  • 오버라이딩
    • 기능을 바꾸어 재설계
    • ex. push() - 확인 / 취소 로 서로 다른 기능을 수행하게 할 수 있음
    • 클래스 상속과 같이 open으로 상위 메소드에 선언해주고, override로 상속
    • final override 사용 시 오버라이드를 선언한 클래스의 하위 클래스는 재정의 금지
  • 오버로딩
    • 같은 기능을 구현하지만 인자 수나 타입이 다름
    • ex. print("hello") (string), print(1)(int)와 같이 같은 출력이지만 받는 인자가 다름
fun add(x:Int):Int { return x+1 } fun add(x:Double) : Double { return x+1.0 //오버로딩 : 다른 type } fun add(x:Int, y:Int) : Int { return x+y //오버로딩 : 다른 인자 개수 }

super, this

  • super
    • 상위 클래스의 참조
    • super.프로퍼티, super.메소드(), super() : 프로퍼티, 메소드, 생성자 참조
  • this
    • 현재 클래스의 참조
    • this.프로퍼티, this.메소드, this() : 프로퍼티, 메소드, 생성자 참조
open class Person { //상위 클래스 constructor(firstName: String) { println("[Person] firstName: $firstName") } constructor(firstName: String, age: Int) { //생성자 오버로딩 println("[Person] firstName: $firstName, $age") } } class Developer: Person { //Person 클래스 상속 constructor(firstName: String): this(firstName, 10) { // Developer 클래스의 아래 constructor 접근 (age default로 10 대입) println("[Developer] $firstName") } constructor(firstName: String, age: Int): super(firstName, age) { // Developer Class의 상위 클래스인 Person Class의 생성자 접근 println("[Developer] $firstName, $age") } }
  • 외부 클래스 호출(@)
    • 클래스 내부의 클래스(inner class)에서 상위 클래스 호출 시 super@클래스명으로 호출한다.
  • 앵글브라켓(<>)
    • 클래스와 인터페이스 중복 사용 시 사용할 상위 클래스를 지정 가능
open class A { open fun f() = println("A class f") fun a() = println("A class a") } interface B { fun f() = println("B interface f") fun b() = println("B interface b") } class C : A(), B { override fun f() = println("C class f") fun testing() { f() //C클래스의 f b() //B 인터페이스의b super<A>.f() //A클래스의 f super<B>.f() //B클래스의 f } }

가시성 지시자와 캡슐화

  • 클래스를 작성할 때 클래스 외부로부터 접근을 차단하는 속성이나 기능
  • 가시성 지시자(visibility modifier)
    • private : 클래스 내부에서만 접근 가능
    • public : 접근 가능(기본값)
    • protected : 상속된 클래스만 접근 가능
    • internal : 같은 모듈 내에서만 접근 가능
    • 변수명, 함수명, 클래스명, 지시자 등에 붙을 수 있음
728x90
728x90
람다식과 고차함수 요약

강의 링크 : https://www.edwith.org/boostcourse-mo-kotlin-basic1/joinLectures/28611

람다식과 고차함수 요약

  • 람다식 : {인자 -> 본문}
val sum : (Int, Int) -> Int = {x, y -> x+y} val mul = {x:Int, y:Int -> x * y} val add : (Int) -> Int = {it + 1} //it은 전달받은 인자를 의미 (함수 인자가 하나인 경우)
  • 고차 함수 : 리턴값이나 인자가 함수인 함수
fun high(name : String, body : (Int)->Int) : Int { prinln("name : $name") val x=0 return body(x) } //함수 호출 val res1 = high("TxT", {x->inc(x+3)}) //인자로 전달되는함수 인자가 하나인 경우 : it으로 대체 가능 val res2 = high("TxT") {inc(it+3)} //매개변수가 없을 때 함수 이름만 사용 val res3 = high("TxT", ::inc) //inc는 람다식으로 변환됨 // 매개변수가 하나인 경우 + 람다식 전달 val res4 = high("TxT") {it+3}

클로저

  • 람다식 함수에서 외부 변수에 접근할 수 있는 방법
  • 외부 변수를 capture하여 사용
fun main() { val calc = Calc() var result = 0 // 외부의 변수 calc.addNum(2,3) { x, y -> result = x + y } // 클로저 println(result) // 값을 유지하여 5가 출력 } class Calc { fun addNum(a: Int, b: Int, add: (Int, Int) -> Unit) { // 람다식 add에는 반환값이 없음 add(a, b) } }

코틀린 표준 라이브러리

  • 코틀린 표준 함수는 확장 함수 형태의 람다식으로 제공
  • let() : 객체를 인자로 넘기고 결과값 반환
//main문 내 val score : Int?=32 // 기존 null검사 fun chkScore() { if (score != null) println("Score : $Score") } //let을 이용한 null검사 - null이면 {...}이 실행되지 않음 fun letChkScore() { score?.let{println("Score:$it)} }
  • also() : let은 결과값 반환, also는 함수에 전달한 객체를 반환
    • 함수 블록 {...}의 마지막 문장을 let은 결과로 반환
    • also를 사용 시 마지막 문장을 반환하지 않음 (=대입이 안됨)
var m=1 m = m.also{it+3} //m은 1 - 연산한 결과가 m에 대입되지 않음
  • apply(): also와 같이 객체를 전달하고 반환받음
    • also와 달리 확장 함수로 처리되므로 클래스 인자 접근 시 it을 사용하지 않아도 됨
val person = Person("", 0) //apply val result = person.apply { name = "James" age = 56 } //also val result = person.also { it.name = "James" it.age = 56 }
  • run() : 익명 함수 / 객체 호출 두가지로 활용
    • block 내용 수행 후 결과값을 반환
    • 조건부 메소드 사용 가능
    • apply와 다르게 객체에 접근하면서 함수 블록{...}의 마지막 결과가 실행됨
run { if (firstTimeView) introView else normalView }.show()
  • with() : 전달받은 객체를 처리
    • safe call(?.)이 없으므로 let과 함께 쓰임
supportActionBar?.let { with(it) { setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(R.drawable.ic_clear_white) } }
  • use() : 객체 사용 후 호출한 객체를 닫아줌(close())
    • 파일을 사용할 때 유용
private fun readFirstLine() : String { BufferedReader(FileReader("text.txt")).use{ return it.readline() } }
728x90
728x90
조건문을 통한 분기 (1)

강의 링크 : https://www.edwith.org/boostcourse-mo-kotlin-basic1/joinLectures/28611

조건문을 통한 분기 (1)

  • C언어의 조건식과 유사
if(...) { ... } else if (...) { ... } else { ... } val bar = if(...) a else b //1줄로 축약 가능 //if문을 이용한 대입 val a = 1 val b = 2 val bar = if(...) { println("a") a } else { println("b") b }
  • in 연산자 : 범위 내에 값이 있는지 확인
if (score >= 80 && score <= 89>) //score이 80 ~ 89 내인지? if (score in 80..89) { ... } // 위와 동일한 동작

조건문을 통한 분기 (2)

  • When문 : Switch - Case문의 간략화
when(x) { /*(일치하는 값 or 표현식) -> 수행할 명령문*/ 0, 1 -> printf("x is 0 or 1") returnvalue(x) -> print("return is correct") // 함수 리턴값과 비교 is Int -> println("x is int") /*(일치하는 범위) -> 수행할 명령문*/ in 1..10 -> println("x is in 1 ~ 10") !in 10..20 - > println("x is not in 10 ~ 20") ... /*else -> 수행할 명령문*/ else -> println("??") }
  • 인자가 없는 경우 - 다양한 조건식 구성 가능
var scroe = readline()!!.toDouble() var grade : Char = 'F' when { score >= 90.0 -> grade = 'A' score in 80.0..89.9 -> grade = 'B' score in 70.0..79.9 -> grade = 'C' else -> grade = 'F' } ...

반복문

  • for문
for(x in 1..5) // (요소 변수 in (컬렉션 or 범위)) { ... }
  • 다양한 반복법
//감소 for (i in 5 downto 1) //5,4,3,2,1 //단계별 증가 for (i in 1..5 step 2) //1, 3, 5 //혼합 for (i in 5 downto 1 step 2) //5, 3, 1
  • while문 : C의 while / do-while과 동일하게 동작한다.
while(...) { ... } //조건을 만족하는 동안 계속 동작 do { ... }while(...) //조건 검사가 밑에서 동작하므로 처음 1회는 무조건 동작

흐름의 중단과 반환 (1)

  • 흐름 제어
    • return : 함수의 결과를 반환
      • 반환값이 없는 경우 return 혹은 return Unit
      • 함수 마지막에는 Unit을 생략해도 return Unit이 동작함
    • break : 반복문을 끝냄
    • continue : 반복문 내용을 생략하고 조건으로 넘어감
  • 예외 처리
    • try {...} catch {...} : 예외 발생시 catch 내용 수행
    • try {...} catch {...} finally {...} : 예외가 발생해도 finally 내용은 수행

예외 처리

  • 실행 도중에 비정상적으로 프로그램 종료 시
    • OS 문제 (System Call Fault 등)
    • 입력값 문제 (int형에 문자열 입력 등)
    • 연선 문제 (divide by zero 등)
    • 메모리 할당 실패
    • HW 문제(전원 문제, 기억 장치 문제 등)
try { //예외처리 가능성이 있는 문장 } catch(e:classname) //e:예외처리 클래스 이름 { //예외처리 문장 } finally { //try-catch와 무관하게 실행할 문장 }
  • 사용자에 의한 예외 발생
    • throw Exception(message : String)을 이용
if(/* error */) { throw Exception("Error!") }
728x90
728x90
함수 선언과 호출

강의 링크 : https://www.edwith.org/boostcourse-mo-kotlin-basic1/joinLectures/28611

함수 선언과 호출

fun sum(a:Int, b:Int): Int{ var sum = a+b return sum }
  • fun 키워드로 함수 선언
    • 매개변수 (이름 : type) 선언
    • 함수의 반환 타입 결정 (fun _ : type)
    • 반환 필요 시 return
  • 함수의 간략화된 선언 - 바로 return하는 경우
fun sum(a:Int, b:Int) : Int = a+b //매개변수를 통해 return 추론이 가능한 경우 return 자료형도 생략 가능 fun sum(a:Int, b:Int) = a+b
  • 매개변수의 기본값 : 인자가 전달되지 않을 때 기본으로 사용할 값 설정 가능
fun email(ID : String, domain : String = "naver.com") { println("your email is ${ID}@${domain}") } fun main(){ email("Kildong") //your email is Kildong@naver.com email("Kildong", "Gmail.com") //your email is Kildong@Gmail.com }
  • 반환값이 없는 함수 : Unit return
fun out(name : String) : Unit { println("name : ${name}") return Unit //return Unit은 아무것도 반환하지 않음(생략 가능) } fun outp(name : String) : Unit = println("name : ${name}") //위 함수와 동일하게 동작
  • 함수 매개변수 지정
    • 기본값이 있는 매개변수의 경우 지정하여 대입 가능
fun sum(a : Int = 1, b : Int = 2) = a+b fun main() { println("1+2 = ${sum()}") //1+2 = 3 println("1+4 = ${sum(b = 4)}") //1+4 = 5 println("3+2 = ${sum(a = 3)}") //3+2 = 5 }
  • 가변인자 : vararg 키워드로 여러 개의 인수를 받을 수 있음
    • for문을 이용하여 함수에서 처리 가능
fun varprint(vararg a : Int) { for (n in a) { println("number is ${n}") } println("===========================") } fun main() { varprint(1) varprint(1,2) varprint(1,2,3,4,5,6,7,8,9) } /*출력결과 number is 1 =========================== number is 1 number is 2 =========================== number is 1 number is 2 number is 3 number is 4 number is 5 number is 6 number is 7 number is 8 number is 9 =========================== */

함수형 프로그래밍 패러다임 (1)

  • 코틀린은 멀티 패러다임 언어 : 함수형 / 객체지향
  • 함수형 프로그래밍
    • 단순한 코드 지향
    • 코드의 테스트나 재사용성 증가
    • 람다식, 고차함수 활용 : 함수의 인자에 함수를 대입 가능
    • 순수 함수 제공
  • 순수 함수
    • 부작용이 없는 함수 : 동일 입력 - 동일 출력
    • 값의 예측이 가능
    • 함수 외부의 상태를 바꾸지 않음 : 함수에 없는 외부 객체가 사용되는 경우(함수 리턴값을 대입하는 등)
    • 람다식, 고차함수 사용을 위해 필요한 개념
    • 입력 - 내용을 분리하여 재사용성이 높음
    • 병행 작업 시 안전
    • 테스트, 디버깅 시 유리
  • 람다식
    • 익명 함수의 일종으로 이름 선언 없이 사용 가능
    • {x, y -> x+y}
    • 고차 함수에 인자로 넘기거나 결과값으로 사용할 수 있음
  • 일급 객체(First Class Citizen)
    • 함수의 인자, 반환값으로 쓰일 수 있음
    • 변수에 대입할 수 있음
    • 코틀린의 함수는 일급 객체로 다룸
  • 고차 함수
    • 함수 인자가 함수가 되는 것
fun highFunc(sum : (Int, Int) -> Int, a : Int, b : Int) : Int { //첫 번째 매개변수 : sum이라는 람다식 변수는 Int 2개를 받아 Int를 반환 return sum(a, b) } fun main() { println(highFunc({x, y -> x + y}, 10, 20)) }

함수형 프로그래밍 패러다임 (2)

  • 고차함수의 호출 방법 : 값에 의한 호출, 이름에 의한 호출, 참조에 의한 호출
  • 값에 의한 호출 : 함수 인자는 값으로 처리되어 수행된 값을 전달
fun main() { val result = callByValue(lambda()) // 람다식 함수를 호출 println(result) } fun callByValue(b: Boolean): Boolean { // 일반 변수 자료형으로 선언된 매개변수 println("callByValue function") return b } val lambda: () -> Boolean = { // 람다 표현식이 두 줄이다 println("lambda function") true // 마지막 표현식 문장의 결과가 반환 }
  • 이름에 의한 호출 : 함수 이름을 매개변수로 전달하여, 함수가 사용될 때 실행
fun main() { val result = callByName(otherLambda) // 람다식 이름으로 호출 println(result) } fun callByName(b: () -> Boolean): Boolean { // 람다식 함수 자료형으로 선언된 매개변수 println("callByName function") return b() } val otherLambda: () -> Boolean = { println("otherLambda function") true }
  • 참조에 의한 호출 : 콜론 기호(::)를 이용한 호출
fun main() { // 1. 인자와 반환값이 있는 함수 val res1 = funcParam(3, 2, ::sum) println(res1) // 2. 인자가 없는 함수 hello(::text) // 반환값이 없음 // 3. 일반 변수에 값처럼 할당 val likeLambda = ::sum println(likeLambda(6,6)) } fun sum(a: Int, b: Int) = a + b fun text(a: String, b: String) = "Hi! $a $b" fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int { return c(a, b) } fun hello(body: (String, String) -> String): Unit { println(body("Hello", "World")) }

익명함수, 인라인 함수

  • 익명 함수 : 이름이 없는 함수
    • 람다식 함수를 위한 임시 함수로 사용
    • 람다식에서 쓰기 어려운 return, break continue 등을 사용하기 위함
fun (x:Int, y:Int) : Int = x+y val add : (Int, Int) -> Int = fun(x,y) = x+y val add = fun(x : Int, y:Int) = x+y // 람다식과 유사한 형태
  • 인라인 함수 : 함수가 호출되는 곳에 함수 내용을 복사
    • 함수 호출 시 코드가 분기하는데, 이 부분이 없어지므로 성능이 증가
    • 과도한 호출 시 main 함수 자체의 크기가 커질 수 있음
inline fun foo(...) { ... } fun main(){ foo() // foo 내용이 복사 }

인라인 함수의 제한

  • 코드가 복사되므로 내용이 많은 인라인 함수는 파일 크기를 증가시킬 수 있음
  • noinline : 람다식 함수는 인라인 되지 않도록 할 수 있음
inline fun foo(bar1 : () -> Unit, noinline bar2 : () -> Unit) { ... //bar1 람다식은 인라인 복사되지만, bar2는 인라인 x }
  • 확장 함수
    • 클래스의 멤버 함수를 외부에서 추가할 수 있음
    • 동일한 멤버나 메소드 존재 시 기존의 함수가 우선하여 호출됨

중위 함수, 재귀 함수

  • 중위 함수
    • 클래스 멤버 호출 시 점을 생략하고, 함수 이름 뒤의 소괄호를 생략
    • 조건
      • 멤버의 메소드 혹은 확장 함수
      • 매개변수가 존재
      • infix 키워드로 정의
infix fun Int.multiply(x:Int) : Int { return this * x } fun main { // 기존 표현법 : val multi = 3.multiply(10) val multi = 3 multiply 10 // 30 }
  • 재귀 함수
    • 자기 자신을 다시 호출
    • 필수 조건
      • 탈출 조건을 만들어야 함(무한루프 방지)
      • 호출 회수에 제한(함수 호출은 스택을 이용하므로)
    • 꼬리 재쉬 함수
      • 함수 분기 없이 재귀 호출 시 함수 영역을덮어씌우면서 호출 (스택 영역을 사용하지 않음)
      • 무한히 호출하더라도 stack overflow가 없음
      • tailrec 키워드로 선언
// 팩토리얼 함수 fun factorial(n:Int): Long { return if(n == 1) n.toLong() else n*factorial(n-1) } //꼬리재귀 팩토리얼 tailrec fun factorial(n : Int, run : Int = 1) : Long { return if(n ==1) run.toLong() else factorial(n-1, run * n) }
pn
728x90
728x90
코틀린의 특징

강의 링크 : https://www.edwith.org/boostcourse-mo-kotlin-basic1/joinLectures/28611

코틀린의 특징

  • 안드로이드의 주 개발 언어인 JAVA가 갖는 한계성을 보완 (애플이 Obj-C에서 Swift로 넘어간 것과 같은 맥락)
  • 목표
    • 웹, 어플(Android/IOS), 임베디드, IoT 등 모든 개발을 다양한 플랫폼에서 개발하고자 함
  • 특징
    • Jetbrain에서 개발 / 보급
    • 간결한 코드, 높은 호환성
    • 세미콜론은 선택
    • 안드로이드 공식 언어
    • 변후는 Nullable (?로 선언) / Not Null로 구분 가능 : Java의 NullpointerException을 방지
  • 플랫폼
    • JVM : 자바 가상 머신에서 동작하는 어플 (JAVA와 호환 가능)
    • JS : 자바스크립트에 의해 동작하는 웹앱
    • Native : LLVM 기반(ARM, x86 등) 컴파일을 지원
      • IOS / Mac / Android / Windows / Linux / WebAssembly 등등
  • 장점
    • 자료형 오류를 미리 잡을 수 있는 정적 언어(statically typed) : 컴파일러가 변수 타입을 미리 검증
    • 널 포인터로 인한 중단 예방 - NullpointerException(NPE)에서 자유로움
    • 자바와 100% 호환 : JVM 상에서 동작 가능
    • 함수형 / 객체지향 모두 가능
    • 세미콜론 생략 가능

기본 자료형과 변수 선언 (1) 불변형, 기본형

  • 자료형
    • 정수형 Int (1)
    • 문자열 String ("1")
    • 실수형 Float (1.00)
    • 그 외 (Double 등)
  • 변수
    • 불변형 val : 선언 후 값 수정 불가
    • 가변형 var : 수정 가능
    • 변수명은 숫자로 시작할 수 없고, 코틀린 키워드(while, if 등)으로는 선언 불가
val username : String = "kildong" //키워드 불변 / 이름 username : 자료형 문자열 / 값 "kildong" // 자료형은 대문자로 시작함에 유의
  • 변수 타입 지정을 해주지 않아도 컴파일러가 타입을 추론해줌
    • Ctrl+Shift+P를 누르면 추론된 타입 확인 가능
    • 자료형 추론을 하고자 하는 경우 초기값을 반드시 선언해주어야 함
var number = 10 //자료형 추론을 위해서는 초기값을 주거나 var number : Int //초기값이 없는 경우 자료형을 줘야 함
  • 카멜 표기법
    • 긴 이름의 변수를 선언하는 규칙 중 하나
    • 일반 변수, 함수명은 단어가 변경될 때 대문자로 시작 (카멜 표기법)
    • 클래스의 경우 대문자로 시작 (파스칼 표기법)
val camelCase var numberOfBooks //변수 선언 - Camel Expr Class AnimalCategory (){} Class CarEngine (){} //클래스 선언 - Pascal Expr

기본 자료형과 변수 선언방법 (2) 정수형과 실수형

  • 정수형 변수
    • Long : 8바이트
    • Int : 4바이트
    • Short : 2바이트 (-32768 ~ 32767)
    • Byte : 1바이트 (-128 ~ 127)
    • 부호 없는 정수형 : 앞에 U를 붙임 (0부터 2n2^n값까지)
  • 정수형 추론
    • 자료형 생략 시 Long 외에는 Int로 추론됨
    • 접미사 L : Long으로 추론 (ex. 123L)
    • 접두사 0x : 16진법 Int (ex.0x0F)
    • 접두사 0b : 2진 Int (ex.0b001100)
    • 접미사 u(uL) : unsigned int(Long) (ex. 123u, 123uL)
    • 가독성 : 언더스코어로 큰 수를 읽기 쉽게 표현 (ex. 123_456_789)
  • 실수형 변수
    • Double : 8바이트
    • Float : 4바이트
  • 실수형 추론
    • 기본은 Double로 추론
    • 접미사 F : Float로 추론됨 (ex. 3.14F)
  • 실수형 변수는 부동 소수점 표현
    • bit 일부는 기수를 일부는 지수 표현에 사용됨
    • 이로 인해 정확한 숫자 표현은 불가능 / 약간의 오차 존재

기본 자료형과 변수 선언방법 (3) 크기 범위와 기타 자료형

  • 자료형의 음수 표현 (2의 보수)
    • 2의 보수 : 이진수 값을 뒤집고 +1
      • ex. -6 : 0000 0110(2) >> 1111 1001(2) (뒤집기)>> 1111 1010(2) (+1)
    • 제일 왼쪽 비트(가장 큰 자리수)가 부호 비트 역할
  • 기타 자료형
    • 논리형 Boolean : 1bit로 true / false로 구분
    • 문자형 Char : 2바이트 유니코드 표현(\u0000 ~ \uffff)
  • String Pool
var str1 : String = "hello" var str2 = "hello" //str1 == str2는 true 반환 //문자열은 string pool에 저장되어 처리
  • $ 표현식
    • 문자열 내에 $기호 사용 시 변수 출력 가능
var a = 1 val s1 = "a is $a" // a is 1 val s2 = "a+1 is ${a+1}" //a+1 is 2

Null 타입

  • 코틀린 변수는 기본적으로 Null 허용 x
    • 선언한 변수는 반드시 값이 할당되어야 함
  • Nullable 선언 : ? 사용
val a : Int? = null val b : String? = null
  • null 변수를 연산시 오류 발생
    • null 연산 시도 시 컴파일 오류 발생
    • 메소드(.) 자리에 safe call(?. - null이면 연산 x)
    • assert call(!!.) : null이 아니라고 가정(컴파일러의 오류처리 무시) - null 접근시 NPE(NullPointException) 발생
    • 엘비스(elvis) 연산자 (?:) : 연산 오류 발생시 대입할 값 지정
val str1 : String? ... //str1의 대입 여부는 모른다고 가정 val len = str1?.length ?: -1 //val len = if(st1!=null) str1.length else -1

비교와 캐스팅

  • 자료형 변환 시 메소드 이용
val a : Int = 1 val b : Double = a.toDouble()
  • 변환 메소드의 종류
    • toByte
    • toLong
    • toShort
    • toFloat
    • toInt
    • toDouble
    • toChar
  • 이중 / 삼중 등호
    • 이중 등호(==) : 값 비교
    • 삼중 등호(===) : 참조 주소 비교 (nullable / not nullable 변수는 같은 값이어도 다른 주소로 할당)
  • 스마트 캐스트
    • 명시되지 않은 자료형을 자동변환
    • Number형 : 대입되는 숫자에 맞는 자료형으로 자동 캐스팅
    • Any형 : 자료형이 정해지지 않은 경우
      • 모든 자료형 클래스의 root 역할
      • 필요한 자료형으로 자동 변환
var test : Number = 12.2 //float test = 12 //int로 smartcast tset = 12L //long으로 smartcast test += 12.0 //다시 float로 smartcast

비트 연산자

  • 비트 메소드
    • shl(bits) : bits만큼 왼쪽으로 shift
    • shr(bits) : bits만큼 오른쪽으로 shift
    • ushr(bits) : bits만큼 오른쪽 shift(부호 변화 x)
    • and(bits) : bits와 and연산
    • or(bits) : bits와 or연산
    • xor(bits) : bits와 xor연산
    • inv() : bit 뒤집기
728x90
728x90
VSCode에 C언어 개발 환경 설정하기

VSCode에 C언어 개발 환경 설정하기

  • VSCode에 C/C++ 개발 환경 설정한다고 한참을 해멨는데, 결국 공식 가이드가 답이었다...
  • MINGW 말고, MINGW-W64를 설치하는게 답이었다. 하나씩 진행해보자!

VSCode 설치하기

  • 이 링크로 들어가서 설치한다. https://code.visualstudio.com/download
  • C/C++ Extension을 설치한다.
    • 위 검색창에 C를 누르면 이미지에 보이는 C/C++을 설치하면 된다.

MINGW 설치하기

  • 해당 링크로 들어가 MINGW를 설치한다 - https://sourceforge.net/projects/mingw-w64/files/Toolchains targetting Win32/Personal Builds/mingw-builds/installer/mingw-w64-install.exe/download
  • 설치 중간에 설정 부분에서 Architecturex86_64를 선택하고, 그 외에는 계속 진행한다.
  • 설치 후, 설치된 폴더를 환경 변수에 추가한다.
    • 파일 관리자에서 내 PC 우클릭 - 속성 - 고급 시스템 설정 - 환경 변수를 클릭한다.
    • 시스템 변수에서 Path를 찾아 편집을 누른다.
    • (mingw 설치 경로)\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin까지 복사한 후, 환경 변수에 추가해 준다.
  • cmd를 켜서 g++ --version, gcc --version의 결과가 다음과 같으면 성공이다.

빌드 환경 만들기

  • 일단 코드를 작성한다.
// hello.c #include <stdio.h> int main(void) { printf("hello, world!\n"); return 0; }
  • VScode에서 Terminal > Configure Default Build Task로 이동한다. 이때 C파일의 경우 gcc.exe를, Cpp는 g++.exe 를 선택한다.
{ "version": "2.0.0", "tasks": [ { "type": "shell", "label": "C/C++: g++.exe build active file", "command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe", "args": ["-g", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe"], "options": { "cwd": "${workspaceFolder}" }, "problemMatcher": ["$gcc"], "group": { "kind": "build", "isDefault": true } } ] }
  • 만약 mingw의 설치 폴더가 다르다면 위 command를 설치 폴더로 수정한다.
  • 이제 ctrl+shift+B를 누르면 C/Cpp 파일이 exe로 빌드된다.

디버깅 설정하기

  • 이번엔 디버깅이다. Run > Add Configuration...을 눌러 GDB를 선택한다.
  • 이후 F5를 누르면 디버깅이 가능하다.
728x90
728x90
Hybrid Multicloud

Hybrid Multicloud

  • Hybrid Cloud : private / public cloud를 하나의 인프라로 설정
  • 멀티클라우드 : 클라우드 전략 중 하나로, 서로 다른 클라우드 모델을 혼합한 것
    • Public / Private, IaaS/PaaS/SaaS를 조합
    • Cloud A - email / Cloud B - CRM / Cloud C(Private) - Infrastructue
    • 서로 다른 공급자를 이용할 수 있음
  • Using case
    • 한 서비스가 UI / API / Billing으로 구성된 multicloud로 가정
    • 만약 특정 region에서 수요가 peak를 찍을 경우, 해당 region의 UI / Billing 부분의 Cloud service를 확장시켜 대응 가능
  • 특정 클라우드에 모든 작업이 몰리는 것을 방지하기 위해 multicloud를 사용하기도 함

Microservices

  • 특정 어플리케이션을 작은 구성 요소, 혹은 서비스 단위로 분할하여 제공하는 것
  • 각각의 컨테이너에서 동작하는 stack을 보유
  • API, Event, Message를 통해 데이터 교환
  • Business에서의 의미
    • 다수의 개발자가 독립적으로 개발 가능
    • 다른 구성 요소에 대해 다른 stack으로 개발 가능
    • 각 구성 요소에 대해 독립적인 scaling 가능
  • SW의 개발 발전
    • 초기 : 단일 프로그램을 함께 개발
    • 중기 : PaaS를 통한 통합 개발 환경
    • 최근 : 서비스를 독립된 구성 요소(검색, 추천, 별점 등)로 분할하여 개발
      • 하나의 microservice에 이상 발생 시 다른 서비스로 대체 가능

Serverless Computing

  • Infrastructure에서 Scaling, Scheduling, Patching 등의 관리에 필요한 노력을 경감
  • 어플리케이션의 필요에 따라 자원 할당
  • 필요에 따라 코드를 동작하며 필요에 따라 Scaling
    • request된 정도에 따라서 비용 지불
  • 인프라를 추상화하고, 각 기능별로 코드가 실행
  • 모든 서비스에 대해 서버리스가 유용하지느 않음
    • 어플리케이션의 특징을 분석
    • 어플리케이션이 서버리스 패턴에 적합한지 확인
      • 단시간 구동되거나, 특정 기간에만 동작하는 경우
      • 이벤트 기반의 처리를 하는 경우
      • stateless microservice
  • Using Case
    • IoT, 모바일 백엔드, 마이크로서비스
    • 각종 데이터에 대해서 - 평가, 번역, 데이터 검증, PDF 처리, 정규화, 이미지 썸네일 등

Cloud Native Applications

  • 오직 클라우드 환경 내에서만 동작하기 위한 어플리케이션
    • 혹은 클라우드 특성에 맞게 재구성된 어플리케이션
  • 어플리케이션을 구성하는 마이크로서비스로 구성
    • 각 서비스는 독립적으로 scale됨
    • 각 미이크로서비스는 실행 단위인 Container로 package됨
  • Cloud Native Applications 개발 특징
    • Microservice architectrue : 어플리케이션을 기능 단위로 분리
    • rely on container : 유연성, scailability, portability 최대화
    • Agile Method : 유저 피드백에 기반한 빠른 업데이트

DevOps on the Cloud

  • 개발팀의 목표
    • 소프트웨어 설계, 개발, 전송, 실행
    • 신뢰성, 효율성 중시
  • 운영팀의 목표
    • 모니터링, 실패 예측, 환경 관리, 이슈 수정
  • DepOps = Develop + Operation
    • 개발, 운영, QA 담당이 하나의 팀으로 협업하는 것
    • 빠른 사용자 피드백 사이클을 통해 생산성 증가
  • DevOps process
    • Continuous delivery : 소규모로, 잘 설계된, 고품질의 소프트웨어
    • Continuous Integration : 코드 수정을 Immutable한 이미지로 배포 - 만약 수정이 필요할 경우 해당 구성 요소 전체가 수정
    • Continuous Deployment : 라이프사이클은 가능한 한 빠르게
    • Continuous Monitoring : deploy 이전까지 어플리케이션의 가용성 등을 모니터
  • 클라우드에서의 DevOps
    • Provision, installation, documentation의 과정을 자동화
    • Continuous Integration & Deployment
    • Define how to collaborate
    • low cost test
    • recover from diseasters quickly

Application Modernization

  • 레거시 시스템의 문제점 : 업데이트가 어려움, 유지 보수 비용이 높음
  • Application Modernization : 새로운 서비스 적용이 쉽고, 변화에 빠르게 응답할 수 있음
  • Application Modernization의 과정
    • Architecture
      • 과거 : 단일 구조로 개발
      • 현재 : 서비스 지향 - 프론트엔드 / 백엔드 등
      • 최근 : 마이크로서비스 - 매우 작은 단위로 프로그램 분할
    • Infrastructure
      • 과거 : 물리적 서버 사용
      • 현재 : 가상 머신
      • 최근 : 클라우드
    • Delivery
      • 과거 : 폭포형 - 장기적으로 계획, 개발, 테스트 순으로 진행
      • 현재 : Agile 방법론
      • 최근 : DevOps
728x90

+ Recent posts