Skip to content
Beside the Wheel
Search
Cancel
GitHub
LinkedIn
Select theme
Dark
Light
Auto
글
(57)
공부
(4)
코드 까보기, 오픈소스 기여해보기
데브옵스(네트워크) 스터디 후기
eBPF로 서버 성능 Profiling하는 법: Pyroscope의 구현 살펴보기
Downtime 없는 Spot Instance 클러스터 구축 과정
독후감
(33)
과학
(1)
니콜라 테슬라 평전
사회
(2)
능력주의와 불평등
그의 운명에 대한 아주 개인적인 생각
산문
(3)
보통의 존재
새는 날아가면서 뒤돌아보지 않는다.
시지프 신화 – 부조리에 관한 시론
소설
(11)
수레바퀴 아래서
멋진 신세계
데미안
말테의 수기
구토
인간실격
젊은 베르테르의 슬픔
노르웨이의 숲
삼국지
황야의 이리
고래
인문
(5)
지성적 회심
담론
효율성
미쳤다는 것은 정체성이 될 수 있을까?
영향에 대한 불안
자기계발
(5)
홀로 성장하는 시대는 끝났다
C의 유전자
네 명의 완벽주의자
세상에서 가장 긴 행복 탐구 보고서
학습하는 조직
전공
(3)
IT 엔지니어를 위한 네트워크 입문
코드로 인프라 관리하기 2판
데브옵스 엔지니어를 위한 실전 관찰가능성 엔지니어링
철학
(3)
지극히 인간적인 삶에 대하여
아리스토텔레스 수사학
사마의 평전
발표
(4)
Git hook으로 Repository README에 파일트리 넣기
2023 DSM 컨퍼런스 - 좋은 프로젝트에 대한 고찰
DSM DevOps 분야 설명회
Xquare 관련 컨테이너 기술 설명회
생각들
(7)
2023년에 쓴 일기장
변화에 대하여
비구조적인 회고에 대하여
의식의 영역에 대하여
국카스텐
짧은 생각들
소유냐 존재냐
회고
(9)
2022.03-04 대덕소마고 입학소감/다짐
2022.05-08 프로젝트와 인간관계
2022.09-2023.02 불안과 판단
2023.03-07 DMS 리더 회고
2023.08-11 나는 누구인가?
2023.12 더 많은 걸 배우기 위한 경험
2024.03-04 3학년으로서 근황
2024.05-07 나름 알찬 3학년
2024.08-12 첫 회사
TIL
(810)
DevOps
(272)
AWS
(77)
Analytics
(5)
Athena
EMR
Glue
Kinesis
Lake Formation
Computing
(15)
Auto Scaling
(5)
ASG Lifecycle Hook
Auto Scaling
Auto Scaling termination policies
Scaling cooldowns
State Change Event
EC2
(6)
EC2
EC2 Fleet
Elastic Fabric Adapter
Instance Store
RI와 Saving plan
Spot Instance
ECS
Elastic Beanstalk
Fargate
Lambda
Database
(6)
Aurora
DynamoDB
EFS
RDS
RDS proxy
Redshift
Management and governance
(4)
CloudFormation
CloudTrail
CloudWatch
LogGroup
Netwoking
(20)
elb
(3)
Application LoadBalancer components
Connection Draining
ELB
security
(3)
NACLs
Security Groups
WAF
Bastion Host
CloudFront
Direct Connect Gateway
EC2 Instance Connect Endpoint
ENI
Global Accelerator
NAT gateway & NAT instance
Route53
Transit Gateway
VPC
VPC endpoint
VPC Mapping Service
VPN
VPN Options
Security
(9)
AWS Managed Microsoft AD
Cognito
Conformance Packs & Security Hub
IAM
KMS
KMS Datakey
MalformedPolicyDocument
Microsoft Active Directory
WAF & Firewall Manager & Shield Advanced
Storage
(11)
EBS
(3)
EBS
EBS gp2 vs gp3
EBS vs Instance Store
AppSync
DayaSync
EFS
FSx
S3
S3 Glacier Vault Lock
Snow Famliy
Storage Gateway
API Gateway
AWS cloud computing
AWS Organization
Region과 Zone
SAA 오답노트
SAA 요약
Well Architected
Container
(22)
CNI
(3)
Calico
CNI
Install Calico
Docker
(15)
Docker Image Layer
dockersock 권한에러
DockerSwarm
exec user process caused exec format error
Overlay Network
Private registry 구축
Prune
README
가상화와 컨테이너
도커 네트워크
도커 네트워크 명령어
도커 명령어
도커 스토리지
도커 아키텍처
도커 안에서 도커 사용하기
cAdvisor
Container Orchestration
ContainerRuntime
Docker와 PID1
DR
(2)
DR strategies
Fail over와 서버 이중화
IaC
(12)
Terraform
(7)
aws 서버 네트워크 구축
Terraform
Terraform import와 Terraforming
Terraform taint
Terraform with AWS
Terraform 키워드
Terratest
Ansible
Cobbler
Configuration Drift
Phoenix Server
Understanding Ansible, Terraform, Puppet, Chef, and Salt
Kubernetes
(102)
EKS
(13)
Add IAM to RBAC
Amazon VPC CNI
AWS Load Balancer Controller
EBS CSI driver
EKS ALB
EKS Control Plane
EKS kubecofig
EKS Network BestPractice
EKS Spot Instances with Karpenter
EKS 인증과정
IP addresse prefix
NLB IP mode
Node not Ready
Network
(11)
DNS
(4)
CoreDNS
DNS in k8s
External DNS
ServiceDNS
Debugging DNS Resolution
eBPF
HTTPProxy
IPVS
NetworkPolicy
Network Troubleshooting
Node and Pod Network Layout
Service Mesh
(9)
istio
(9)
Dry run
gateway log debug 하는 법
Istio Arcitecture
Istio authorization
Istio Configuration Profiles
Istioctl
Istio RBAC
Resource Annotations & Labels
ServiceEntry
tools
(19)
ArgoCD
(5)
ApplicationSets
Apps of Apps
ArgoCD 설치
Config Management Plugins
Health Check
helm
(3)
Chart Development Tips
Helm
Values Files
Karpenter
(2)
Karpenter
Karpenter best practices
Kyverno
(2)
Kyverno
Usecases
GoCD
Install Cilium
K8s Metric API
MetalLB
node shell
Node Termination Handler
OPA Gatekeeper
개념
(31)
Node Scheduling
(3)
Assigning Pods to Nodes
cordon, drain
Taints and Tolerations
object
(15)
Annotation
CRD
Deployments
Deployment Status
Deployment Strategy
Events
ingress
Labels and Selectors
Pod
Pod Readiness and Probes
Pod 생성과정
PV & PVC
RollingUpdate
Service와 port
StatefulSets
Volume
(2)
attachdetach controller
CSIDriver
CNI Specification
Disruption Budget
Endpoints
etcd
HPA와 VPA
K8s의 도커런타임 사용중단
Kubeproxy
NodePort와 ServicePort와 targetPort
Workloads
가상 IP와 서비스 프록시
사이드카 패턴
실습
(15)
Auth
(5)
Authenticating
k8s 클러스터 root CA를 통한 사용자 인증
OIDC Authentication with Dex
Security Context for a Pod or Container
Token Webhook with Guard
10 most common mistakes using kubernetes
Cert manager
End user RBAC
K8s를 위한 SpringBoot 개발
kubectl context
minukube 시작하기
NetworkPolicy Cilium example
Pulling images from ECR on Kubernetes
SpringBoot 서비스를 위한 Kubernetes 설정
환경변수 설정
K8s Architecture
Kubernetes
Kubernetes Overview Diagrams
MetalLB
Monitoring
(24)
datadog
(5)
datadog
DatadogAnomalydetectionAlgorithms
datadog APM 기능 사용하기
datadog 아키텍처
helmChart로 Agent 설치
elk
(4)
Elastic Search
ElasticSearch 검색 명령어
ELK Stack
Logstash
grafana
(2)
Granafa agent
Pyroscope Distributor and Ingester
loki
(1)
Loki Canary
prometheus
(5)
kiali with prometheus
prometheus
prometheus agent mode
prometheus glossary
prometheus storage
thanos
(2)
Rule
Thanos
DeepFlow
DeepFlow 논문 요약
Grok exporter
SLO, SLI, SLA
telemetry
Proxy
(15)
envoy
(3)
Envoy
LDS
xDS configuration
nginx
(9)
location block
nginx certbot
nginx docker
NGINX Ingress Basic Auth
nginx 명령어
nginx 설정
sites available
SSL passthrough
리버스 프록시
Contour
Contour CRD 설치
Reverse Proxy vs. Ingress Controller vs. API Gateway
tools
(14)
Clium
CUE
Dex
Dex K8s Authenticator
GPG
jenkins
Keycloak
minio
Mortar
OpenHistorian
openssl로 pemKey 만들고 접속하기
Packer
tar
Vault
CI/CD파이프라인
Cloud Agnostic Design
Platform Engineering
데브옵스
Network
(59)
error
(1)
Context deadline exceeded
L1 network access layer
(8)
CRC
Ethernet과 TokenRing
L2 스위치와 STP
MTU
NIC
데이터링크 제어(DLC)
매체 접근 제어(MAC)
아날로그, 디지털 신호와 전송
L2 internet layer
(15)
라우터
(4)
ECMP
라우터
라우팅 알고리즘
멀티캐스트 라우팅
CIDR
ICMP
IP
IPAM
IPSec
IP 데이터그램과 단편화
NAT
PacketTracer 네트워크 구성
secondary IP
서브넷
정보기기운용기능사 실기
L3 transport layer
(6)
4계층 장비
SO_REUSEADDR
SSH config
Sticky Session과 Session Clustering
TCP와 UDP
전송계층 프로토콜
L4 appplication layer
(13)
http
(3)
HTTP
HTTP Options
keep alive
tls
(3)
SNI
TLS
TLS 인증서 발급 절차를 이해해보자
ACME
CDN
DHCP
DNS 레코드유형
FTP Active, Passive mode
java로 간단한 socket 프로그램만들기
SMTP의 보안 시스템
VPN
(3)
firezone
VPN
Wireguard와 Firezone
개념
(5)
가상화 기술
네트워크
네트워크 보안
네트워크 침해
이중화
bandwidth
Exponential Backoff And Jitter
OSI 7Layer
Switch
vTAP
WebRTC
로드밸런서
브라우저에 url을 입력하면 어떤일이 생길까?
OS
(127)
Embedded
(6)
Audio Codec
Cramfs
I2C
시리얼 통신
임베디드 리눅스 프로그래밍 수업 정리
임베디드 시스템
linux
(102)
Authority
(3)
chattr과 chown
chmod
사용자 관리
BPF
(12)
BCC
BPF
BPF communicates with userspace
BPF ring buffer
BPF System Call
BPF 프로그램 타입
BTF
libbpf
libbpf helper 함수
XDP
메모리 로딩
서브프로그램
Disk & Dir
(9)
Linux 디렉토리 구조
LVM
od
RAID
Symbolic Link
백업
파일 관리 명령어
파일 시스템
파일 종류
ELF
(2)
ELF
SEC()
ETC
(10)
linux 표준 에러 코드
mail
man
Perf
PMU
Redirection와 FD
Runlevel
set
X window
명령어들
Kernel
(19)
Block I/O
CPU Load Average
entropy
vmlinux
동기화와 lock
디버깅
메모리 관리와 캐시
모듈과 장치 관리
스케줄러 소스 분석
시스템 콜과 인터럽트
유저모드와 커널모드
이식성
커널 개념
커널 모듈
타이머
파일시스템
프로세스 관리
프로세스 스케줄러
프로세스 주소 공간
Memory
(2)
Swap메모리
VSS, RSS, PSS, USS
Network
(17)
DNS
(2)
bind로 DNS 서버 정의하기
DNS 서버
주요명령어
(4)
arp
ifconfig
ping과 netstat
route로 라우팅 테이블 확인하기
DERP
Domain-based Split Tunnels
ip_forward와 rp_filter
IP masquerading
iptables
iptables 방화벽 설정
namespace와 cgroup
Netfilter
network namespaces
ufw
Virtual Networking Interface
Process
(8)
cgroup
Deamon process
httpd
pipe
signal
top
프로세스 관리
환경변수와 프로세스
Shell
(3)
bash_profile과 bashrc
shell
zshrc
System call
(10)
epoll
file 관련 systemcall
fork와 exec
ioctl
mmap
perf event
rlimit
thread 관련 systemcall
wait과 waitpid
리눅스 시스템 프로그래밍 프로젝트
kprobe와 kretprobe
Linux Package
Linux 배포판
Linux 부팅 과정
Linux 특징 및 관련용어
Stack trace와 kallsyms
쉘 단축키
memory
(2)
Memory Mapping
페이지 교체 알고리즘
process
(6)
TAS
교착상태와 스케줄링
생산자 소비자 문제
임계영역과 상호배제
프로세스의 개념
프로세스의 관리
VM
(2)
VMware Fusion NAT config
VMware Fusion Ubuntu 디스크 용량 늘리기
window
(1)
Active Directory Domain Services
보안
(1)
엑세스 제어
CPU 아키텍처
c언어 컴파일과정
디스크 시스템
반도체 8대 공정
운영체제 유형
유저, 커널레벨 스레드
파일 시스템
개발
(55)
AI
(18)
Vector Search
(3)
Distance Metrics
Index-realated chians
Vector Search
실습
(3)
CNN, RNN
MNIST 숫자 판별
배, 자동차, 비행기 분류하기
자연어 처리
(1)
BERT
CNN
Document Question Answering
DropOut
Keras
Optimizer
RAG
RNN
선형회귀
임베딩
퍼셉트론
활성화함수
App
(2)
React Native
(2)
New Architecture
React Native
SEO
(2)
sitemap
Web Vitals
Tools
(20)
Git
(9)
Flow
(2)
GitFlow
GithubFlow
hooks
(3)
githook을 위한 perl command
GitHub hooks
파일트리 자동생성
GitLab
git reflog
Selfhosted Runner
자동커밋
vi
(3)
vim
vim 단축키
vi 단축키
Airflow
Firefox 상단 탭 없애는 법
GTM
Intellij Profiling tools
Makefile
mermaid 문법
Spark
Tridactyl
암호화
(5)
AES&IV
Certificate formats
Cipher
DB 암호화
Keytool
테스팅
(1)
테스팅 용어
authn과 authz
FineGrained와 CoarseGrained
Nightly build
turborepo
소프트웨어 공학
압축 알고리즘
자막 파일 포맷
데이터베이스
(60)
DB설계
(8)
DBMS와 RDBMS
데이터모델링
무결성 제약조건
분산데이터베이스
스키마
정규화와 반정규화
테이블분할
트랜잭션 ACID와 격리수준
MQ
(4)
Docker로 Kafka 실행
RabbitMQ
Spring with Kafka
메시지큐
NoSQL
(16)
MongoDB
(8)
Atlas Search
BinData
MongoDB
MongoDB Aggregation
MongoDB Document로 POJO 상속받기
MongoDB 스키마설계 고려사항
MongoDB 유저관리
MongoDB 쿼리
PostgreSQL
(2)
PostgreSQL
PostgreSQL명령어
redis
(2)
Redis
Spring Redis Phantomkey
Cassandra
Memcached VS Redis
NoSQL 데이터유형
NoSQL에는 ACID가 없다고?
SQL 쿼리
(23)
최적화
(3)
DB 커넥션 풀
옵티마이저
조인 수행원리
쿼리종류
(5)
DCL
DDL
DML
Procedural/Nonprocedural DML
TCL
Alias
FK옵션
GROUP BY와 HAVING절
GROUPING SETS와 GROUPING
INNER JOIN과 OUTER JOIN
ON절
ORDER BY절
ROLLUP과 CUBE
SELECT쿼리 실행순서
계층형 질의
서브쿼리
윈도우 함수
제약조건
집계함수
집합연산자
Change Date Capture
ClickHouse
Column, Row기반 DB
Data Lake와 Warehouse
MySQL Replication
OLAP
pgbouncer
Postgresql Transaction Wraparound
Two Phase commit
서버
(72)
netty
(5)
HashedWheelTimer
netty server 예제
netty 메시지 전송 흐름
netty의 thread 모델
webFlux와 netty
node.js
(3)
module.exports와 exports
puppeteer
v8과 libuv
Spring
(62)
AOP
(8)
트랜잭션
(3)
TransactionAttributeSource
트랜잭션
트랜잭션 전파
AdviceAnnotation
Pointcut
ProxyFactoryBean
Spring AOP
Spring에서 aspectj weaving사용하기
Event
(2)
ApplicationEventPublisher
@TransactionalEventListener
JPA
(27)
JPQL
(2)
FetchJoin
경로표현식
QuerydslJpa
(8)
fetchResults가 deprecated된 이유
Paging
Projection
QuerydslJpa와 QClass
QuerydslPredicateExecutor
기본문법
동적쿼리
벌크연산
캐싱
(3)
1차캐시
2차캐시
영속성 컨텍스트
Cascade
@GeneratedValue 코드보기
GenerateValue Column에 값을 넣는다면
Hibernate dialect
Hibernate 쿼리실행순서
Id로 연관관계 객체 저장
JDBC Object Mapping Fundamentalsentity
JPA
N+1 문제
OrphanRemoval
Persistable
ReadOnlyQuery 최적화
벌크연산
트랜잭션 전파 설정
SpringSecurity
(2)
CORS
CSRF
Validation
(2)
@GroupSequence
@Valid와 @Validated
Web MVC
(2)
Request 처리과정
SpringServletContainerInitializer
WebFlux
(7)
R2DBC
(2)
R2DBC
R2DBC 사용
@Controller
RouterFunctions
WebClient
WebFilter
WebFlux
기본원리
(9)
@Autowired 빈 주입 스캔 원리
@ComponentScan
Ioc와 DI
Programmatic과 Declarative
Reflection과 직렬화
등록된 빈 목록 출력하기
빈
선점 잠금과 비선점 잠금
싱글톤
AOT
@Cacheable
Spring 6.0과 Spring Boot 3.0
WAS
(2)
tomcat 구성요소
웹서버와 WAS
아키텍처 및 방법론
(46)
API 아키텍처
(4)
GraphQL
REST
RPC
SOAP
DDD
(5)
DDD
DDD의 아키텍처
도메인영역
이벤트 스토밍
컨트랙트
MSA
(8)
MSA의 장단점
메시지 브로커
사가 패턴
사가 편성
시맨틱 버저닝
통신
트랜잭션 격리
트랜잭션 로그 테일링 패턴
객체지향
(2)
SOLID
응집도와 결합도
디자인패턴
(25)
1. 생성패턴
(5)
빌더 패턴
싱글톤 패턴
추상팩토리 패턴
팩토리메소드 패턴
프로토타입 패턴
2. 구조패턴
(7)
데코레이터 패턴
브릿지 패턴
어댑터 패턴
컴포짓 패턴
퍼사드 패턴
프록시 패턴
플라이웨이트 패턴
3. 행위패턴
(11)
메멘토 패턴
방문자 패턴
상태 패턴
옵저버 패턴
이터레이터 패턴
인터프리터 패턴
전략 패턴
중재자 패턴
책임연쇄 패턴
커맨드 패턴
템플릿메소드 패턴
디자인패턴
위임 패턴(Delegate Pattern)
CQRS
HexagonalArchitecture
알고리즘
(15)
자료구조
(3)
LSM Tree
Trie
세그먼트트리
2020 중등부 정올 2차
N Queen
Range GCD
가장 가까운 두 점
담금질 기법
볼록 껍질과 회전하는 캘리퍼스
오일러 경로 테크닉
왜판원순회
외판원순회
직사각형 스위핑
최소외접원
코드포스 문제모음
언어
(80)
Go
(11)
BSON
Command line argument, flag
defer와 panic
GC
gomod와 gosum
Go에서 하기 쉬운 실수
pprof
slice
toolchain
고루틴 스케줄링
메모리 관리
Java
(20)
JVM
(8)
Heap 영역 구조와 GC
Java Bytecode
jcmd
JVM 구성요소
Permanent to Metaspace
Runtime Data Area
TLAB과 PLAB
메모리누수
Thread
(4)
Thread 상태
@Volatile
wait()과 notifyAll()
가상스레드
Inner static class
JAR과 WAR
JAVA
JDKProxy와 CGLibProxy
JLink & JDeps
record
예외와 에러
제네릭과 variance
JavaScript
(7)
Iterator
Lexical Scope와 Closure
Promise
useEffect 안에서 setInterval 사용하기
절대경로 설정
프로토타입
화살표 함수
Kotlin
(20)
변수
(3)
List와 MutableList
Nullable
val과 var
클래스
(8)
@JvmField
@JvmStatic
Object
Sealed Class, interface
생성자
코틀린에서의 Static
클래스 상속
필드와 접근자 메서드
함수
(1)
기본인자
Collections
field 상속
InlineFuntion과 Reified
Label
Sequences
람다 표현식
범위 지정 함수
제네릭과 variance
Rust
(19)
ffi
(3)
extern
FFI
repr
메모리 참조
(5)
Rc 타입과 Weak 타입
temporary value is freed
Unwrap
소유권과 Lifetime
스마트 포인터 활용
스레드
(3)
Condvar
동시성
멀티 스레드 웹 서버 만들기
예외처리
(1)
Anyhow
String
Trait
구조체 impl
조건문과 반복문
클로저
타입과 변수
함수와 메서드
CustomAnnotation
자바<?>와 코틀린<*>
직렬화 serialVersionUID
코드
(24)
TestCode
(5)
Kotlin
(4)
Kotest
Kotest Assertions
Kotest Specs
Mockk
Mock과 Spy
비동기
(15)
coroutine
(8)
thread
(1)
공유객체 스레드 동기화
Channel
Coroutine CPS
Coroutine Delay
Coroutine Dispatcher
Coroutine Scope, Context
Integration
코루틴
reactor
(3)
Callback과 Futures
Reactor
Reactor Pattern과 event loop
cold stream과 hot stream
Coroutine vs Reactor
Flow
netty 사례연구
빌드
(4)
Gradle
(4)
DependencyHandler
Git action gradle caching
Gradle LifeCycle
멀티모듈
GitHub
LinkedIn
Select theme
Dark
Light
Auto
태그: 코드
총 24개의 글이 있습니다.
Kotest
kotlin
2024. 3. 13.
코틀린에서는 아래와 형태와 같은 DSL(Domain Specific Language) 스타일의 중괄호를 활용한 코드 스타일을 제공한다. 코틀린 내부에서 제공하는 Standard library 대부분도 DSL을 이용해 작성된 것을 볼 수 있다. Type safe builders Kotlin Standard Library Kotlin Scope Functions (let, also, apply, run ..) 하지만 기존에 사용하던 Junit과 AssertJ, Mockito를 사용하면 Mocking이나 Assertion 과정에서 코틀린 DSL 을 활용할 수 없다. 기존에 JAVA에서 사용하던 Junit, Assertion, Mockito 등의 테스트 프레임워크 대신에, Kotest나 Mockk와 같은 도구들
Kotest Assertions
kotlin
2024. 3. 13.
Assertions shouldBe name shouldBe "eunbin"// == assertThat(name).isEqualTo("eunbin") Inspectors forExactly mylist.forExactly(3) { it.city shouldBe "Chicago"} forAtLeast val xs = listOf("sam", "gareth", "timothy", "muhammad") xs.forAtLeast(2) { it.shouldHaveMinLength(7)} Exceptions shouldThrow shouldThrow { // code in here that you ex
Kotest Specs
kotlin
2024. 3. 13.
Kotest는 10가지 다른 스타일의 테스트 레이아웃을 제공한다. 그중 일부는, 다른 테스트 프레임워크와 비슷한 구조로 만들어지기도 했다. 스타일 간에 기능적인 차이는 없다. 스레드, 태그 등 모두 동일한 유형의 구성을 허용하지만, 이는 단순히 테스트를 구성하는 방법에 대한 선호도의 문제이다. 코테스트를 사용하려면 테스트 스타일 중 하나를 확장하는 클래스 파일을 만들어야 한다. 그런 다음 원하는 Spec (추상)클래스를 상속받고 init {} 블록 안에서 테스트 케이스를 작성하면 된다. 테스트 스타일유사한 테스트 프레임워크Fun
Mockk
kotlin
2024. 3. 13.
Mockk는 코틀린 스타일의 Mock 프레임워크이다. Mockito를 사용하는 경우 코틀린 DSL 스타일을 활용할 수 없지만, Mockk를 사용하면 아래와 같이 코틀린 DSL 스타일로 Mock 테스트를 작성할 수 있다. //Mockitogiven(userRepository.findById(1L).willReturn(expectedUser) //Mockkevery { userRepository.findById(1L) } answers { expectedUser } Mockk의 사용을 위해서는 아래와 같은 의존성을 추가해줘야 한다. dependencies { testImplementation("io.mockk:mockk:1.12.0")} 예시 Mocking val permissionRepository =
Mock과 Spy
testcode
2024. 3. 13.
Mockito 등의 라이브러리를 쓰다보면, Mock과 Spy를 사용하게 될 것이다. 둘 다 클래스의 가상 객체를 만들어서 메소드와 필드를 모의 실험하기 위해 쓰인다는 공통점이 있다. 그렇다면 차이점은 무엇일까? 비교 간단히 말하자면, Mock은 완벽한 가짜 객체를 만드는데 반해, Spy는 기본적으로 기존에 구현되어있는 동작을 따르고 일부 메소드만 stub 한다. Mock 객체의 함수를 호출했을때 그 함수에 stub된 동작이 없으면 코드나 라이브러리에 따라 문제가 생길 수 있다. strict 하게 규칙이 설정된 라이브러리(ex. mockk)의 경우에는 호출 즉시 예외가 던져질 수 있고, null이나 기본값 (int = 0, String = ""...)이 반환되도록 되어있을 수도 있다.(ex. mockito)
Coroutine vs Reactor
비동기
2024. 3. 13.
코틀린 코루틴과 리액티브 스트림의 구현체 중 하나인 Reactor의 차이점은 무엇이 있을까? 아래와 같이 사용자의 정보를 받아 환영 메세지를 생성한 후 반환하는 메서드가 있을때, 이 메서드를 호출하는 코드를 각 방식으로 작성해보자. fun generateWelcome( usernameOrIp: String, userProfile: UserProfile?, // 프로필 정보 block: Block?, // 차단 여부): WelcomeMessage = when { block != null -> WelcomeMessage( "You are blocked. Reason: ${block.reason}", WARNING )
Flow
비동기
2024. 3. 13.
coroutine의 Flow는 데이터 스트림이며, 코루틴 상에서 리액티브 프로그래밍을 지원하기 위한 구성요소이다. kotlinx-coroutines-core-jvm 라이브러리의 kotlinx.coroutines.flow 패키지에 인터페이스로 정의되어있다. public interface Flow&x3C;out T{ public suspend fun collect(collector: FlowCollector&x3C;T>)} { public suspend fun collect(collector: FlowCollector)}"> Flow 생성시 연산자(map, filter, take, zip 등)들이 추가되면 Flow (SafeFlow) 의 형태로 체인을 형성하게 되고 collect() 호출 시 루트
cold stream과 hot stream
비동기
2024. 3. 13.
flow에서 사용되는 개념인 cold stream과 hot stream에 대해 알아보고, 서로 비교해보자. 우선 observable과 producer의 개념에 대해 알아보자. observable Observable은 observer를 producer에 연결해주는 함수이다. obserable을 함수처럼 call하면 observer에 값이 전달된다고 생각하면 된다. producer producer는 obserable의 실행 값이다. producer는 web socket이 될 수도 있고, DOM event가 될 수 있고, iterator도 될 수 있다. 보통은 observer.next(value)를 통해 값을 받는 것이 producer라고 생각할 수 있다. cold stream cold stream은 스트림의 구
Channel
coroutine
2024. 3. 13.
Channel은 2개의 Coroutine 사이를 연결한 파이프라고 생각하면 된다. 이 파이프는 두 Coroutine 사이에서 정보를 전송할 수 있도록 한다. 하나의 Coroutine은 파이프를 통해서 정보를 보낼 수 있고, 다른 하나의 Coroutine은 정보를 받기위해 기다린다. 이 채널을 통한 두 Coroutine간의 커뮤니케이션은 공유메모리가 아닌, 커뮤니케이션을 통해서 이뤄진다. Thread는 어떻게 Communicate 할까 소프트웨어를 만들면서 Resource를 Blocking하는 작업, 예를 들면 네트워킹이나 DB를 사용하거나 아니면 계산이 필요한 작업을 할때 우리는 그 작업들을 쓰레드로 분리한다. 이 쓰레드간에 공유할 자원이 필요할때 우리는 두개의 쓰레드가 동시에 그걸 쓰거나 읽게 하지 못하도
Coroutine CPS
coroutine
2024. 3. 13.
Kotlin coroutines are managed at the JVM level using the concept of “continuations.” Continuations are a programming technique that allows suspending the execution of a function at a certain point and resuming it later from where it left off. Coroutines build upon this concept to provide a high-level and efficient way to write asynchronous code. Continuation When a code with suspend is converted t
Coroutine Delay
coroutine
2024. 3. 13.
아래와 같은 timeout(혹은 delay)가 내부적으로 어떻게 동작하는지 알아보자. GlobalScope.launch { withTimeout(10) { ... }} 일단 withTimeout의 코드를 살펴보자면 아래와 같다. 가장 아랫부분을 보면 time이 실제로 track되는 것은 CoroutineDispatcher의 구현이라고 적혀있다. Implementation note: how the time is tracked exactly is an implementation detail of the context’s [CoroutineDispatcher]. / * Runs a given suspending [block] of code inside a coroutine with
Coroutine Dispatcher
coroutine
2024. 3. 13.
Coroutines always execute in some context represented by a value of the CoroutineContext type, defined in the Kotlin standard library. The coroutine context is a set of various elements. The main elements are the Job of the coroutine, which we’ve seen before, and its dispatcher, which is covered in this section. The coroutine context includes a coroutine dispatcher that determines what thread or t
Coroutine Scope, Context
coroutine
2024. 3. 13.
To launch a coroutine, we need to use a coroutine builder like launch or async. These builder functions are actually extensions of the CoroutineScope interface. So, whenever we want to launch a coroutine, we need to start it in some scope. public interface CoroutineScope { / * The context of this scope. * Context is encapsulated by the scope and used for implementation of coroutine bu
Integration
coroutine
2024. 3. 13.
interface Service { fun savePost(token: Token, item: Item): Call&x3C;Post>} suspend fun createPost(token: Token, item: Item): Post = serviceInstance.savePost(token, item).await()}suspend fun createPost(token: Token, item: Item): Post = serviceInstance.savePost(token, item).await()"> Let’s say you want to use Coroutine with code that used futur (which corresponds to several libraries s
공유객체 스레드 동기화
thread
2024. 3. 13.
동시에 읽고 쓰이는 공유 객체에서 스레드 동기화를 적절하게 사용하는 방법에 대해 알아보자. Atomic Synchronized block 스레드 한정 Mutex Actor AtomicInteger CAS(Compare And Swap) 알고리즘을 사용한다. 원리를 간단하게 말하자면, 변경하려는 값과 현재 저장된 값을 비교해서 같으면 변경하고 다르면 값을 변경하지 못하게 하는 것이다. 변경하려는 값과 현재 저장된 값이 다른 경우는 중간에 다른 스레드에 의해 값이 변경된 경우로 볼 수 있기에 변경을 허용하지 않는다. 사용법은 아래와 같다. suspend fun exampleFun(action: suspend () -> Unit) { val n = 100 val k = 1000 val writ
코루틴
coroutine
2024. 3. 13.
프로그래밍 언어에는 루틴이라는 개념이 있다. fun main() { ... val addedValue = plusOne(value)} fun plusOne(value: Int) { return value + 1} 위와 같은 코드가 있다고 했을떄, main 함수가 메인루틴이고 함수를 호출해서 이동하는 것은 서브루틴이라고 부른다. 서브루틴은 진입하고, 빠져나오는 지점이 명확하다. 메인 루틴이 서브루틴을 호출하면, 서브루틴의 맨 처음 부분에 진입하여 return문을 만나거나 서브루틴의 닫는 괄호를 만나면 해당 서브루틴을 빠져나오게 된다. 그리고 진입점과 탈출점 사이에 쓰레드는 블락되어있다. 우리가 보통 짜는 코드는 이렇게 동작한다. 그러나 코루틴(Coroutine)은 조금 다르다. 코루틴 함수는
netty 사례연구
비동기
2024. 3. 13.
파일을 업로드하면 그 파일을 순간 공유할 수 있도록 하는 플랫폼이 있다고 해보자. 그 파일 자체는 아마존 S3에 저장된다. 간단한 업로드 흐름을 구축하자면 아래와 같이 할 수 있다. 전체 파일을 수신한다. S3로 업로드한다. 이미지인 경우 섬네일을 생성한다. 클라이언트 애플리케이션에 응답한다. 여기에서는 2단계와 3단계가 병목 지점이 될 수 있다. 클라이언트에서 서버로 아무리 빠른 속도로 업로드하더라도 실제 드롭을 생성하고 클라이언트에 응답하려면 업로드가 완료된 후 파일을 S3로 업로드라고 섬네일을 생성할 때까지 오랫동안 기다려야했다. 파일이 클수록 대기 시간은 길었고, 아주 큰 파일의 경우 서버로부터 응답을 기다리다가 시간이 만료되는 경우도 있다. 업로드 시간을 줄이기 위한 두가지 다른 방법이 고안됐다
Callback과 Futures
reactor
2024. 3. 13.
어떻게 해야 JVM 위에서 비동기적인 코드를 작성할 수 있을까? Java는 asynchronous programming을 위해 두가지 모델을 제공한다. Callbacks: return 값을 직접 가지지 않고, 비동기 처리가 끝난 후 result 값을 가져올 수 있을때 추가 callback parameter(a lambda or anonymous class)를 가져오는 Asynchronous 메서드이다. Swing의 EventListener와 그 구현 클래스들이 대표적인 예시이다. Futures: Future&x3C;T>를 즉시 반환하는 Asynchronous 메서드이다. The asynchronous process computes a T value, but the Future object wraps
Reactor
reactor
2024. 3. 13.
Reactor란 Pivotal의 오픈소스 프로젝트로, JVM 환경에서 동작하는 non-blocking reactive 라이브러리로서 non-blocking IPC(Inter-Process Commumication)을 지원한다. Reactive Programing 반응형 프로그래밍(reactive programming)은 데이터 스트림과 변화의 전파와 관련된 선언적 프로그래밍 패러다임이다. 이 패러다임을 사용하면 정적 또는 동적 데이터 스트림을 쉽게 표현할 수 있다. In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. With
Reactor Pattern과 event loop
reactor
2024. 3. 13.
Reactor 패턴은 동시에 들어오는 여러 종류의 이벤트를 처리하기 위한 동시성을 다루는 디자인 패턴 중 하나이다. Reactor 패턴은 관리하는 리소스에서 이벤트가 발생할 때까지 대기하다가 이벤트가 발생하면 해당 이벤트를 처리할 수 있는 핸들러(handler)에게 디스패치(dispatch)하는 방식으로 이벤트에 반응하며, ‘이벤트 핸들링(event handling)’, event loop 패턴이라고도 부른다. Reactor 패턴은 크게 Reactor와 핸들러로 구성된다. namedescriptionReactor무한 반복문을 실행해 이벤트가 발생할 때까지 대기하다가 이벤트가 발생하면 처리할 수 있는 핸들러에게 디스패치한다. 이벤트 루프라고도 부흔다.Handler이벤트를 받아 필
DependencyHandler
gradle
2024. 3. 13.
DependencyHandler는 Gradle의 종속성(Dependencies)을 생성해주는 인터페이스이다. public interface DependencyHandler extends ExtensionAware { @Nullable Dependency add(String configurationName, Object dependencyNotation); Dependency add(String configurationName, Object dependencyNotation, Closure configureClosure); &x3C;T, U extends ExternalModuleDependency> void addProvider(String configurationName, Pro
Git action gradle caching
gradle
2024. 3. 13.
Gradle은 빌드할때 의존성 패키지들을 모두 다운받는다. 이때 Gradle은 빌드 시간과 네트워크 통신을 줄이기 위해 의존성 패키지를 캐싱해서 재사용하는 방법을 사용한다. 하지만 Github Actions의 workflow는 매 실행하다 새로운 환경을 구축하고, 매번 새롭게 의존성 패키지들을 가지고 와야 한다. 이는 전체 빌드 시간의 증가로 이어진다. 빌드 시간의 단축을 위해서 우리는 Github Actions의 actions/cache를 사용해서 gradle의 의존성을 캐싱할 수 있다. name: Gradle Caching uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: ${{
Gradle LifeCycle
gradle
2024. 3. 13.
Gradle은 의존성 기반의 프로그래밍용 언어이다. 이 말은 태스크를 정의하고 또한 태스크들 사이의 의존성도 정의 할 수 있다는 뜻이다. Gradle은 태스크들이 의존성의 순서에 따라 실행되고, 오직 한 번만 실행될 것임을 보장한다. Gradle은 태스크를 실행하기 전에 완전한 의존성 그래프를 구축한다. 빌드 단계 Gradle 빌드는 3단계로 구분된다. InitializationGradle supports single and multi-project builds. During the initialization phase, Gradle determines which projects are going to take part in the build, and creates a Project instance for
멀티모듈
gradle
2024. 3. 13.
멀티모듈은 하나의 프로젝트를 여러개의 모듈로 구성하는 것을 말한다. 모듈은 독립적으로 운영될 수 있는 의미를 가지는 구성요소 단위이며, 다른 모듈과의 상호작용으로 애플리케이션을 구성한다. intelij에서는 가장 상위 프로젝트에서 마우스 오른쪽 클릭을 하고, New Module 을 선택 후, 모듈 이름을 입력하면 프로젝트 내부에 여러개의 모듈을 만들 수 있다. &x3C;img src= height=250px/> 멀티모듈을 생성하면 모듈별로 build.gradle 파일이 생기기 때문에, 각 모듈에 맞게 의존성을 설정할 수 있다. 메