JavaScript Basics. 01. 자바스크립트 기본 환경 설치 및 기본 문법

환경 설치 자바스크립트란? HTML과 CSS와 함께 클라이언트 측 웹 프로그래밍을 할 수 있도록 돕는 프로그래밍 언어 C, C++, 자바와 같은 언어에 비해 문법이 쉽고 브라우저에서 바로 실행됨 조금만 배워도 HTML, CSS와 함께 바로 사용 가능 컴파일러 언어와 인터프리터 언어 자바스크립트는 인터프리터 언어로 작성과 동시에 바로 실행할 수 있는 언어이다. 프로그래밍은 일반적으로 컴파일러와 인터프리터라는 과정을 통하여 프로그래밍 진행 바로 작성한 프로그램을 확인할 수 있는 언어를 인터프리터 언어, 컴파일러 언어는 소스 코드를 기계어로 번역하는 과정이 필요함. 기반 환경 구축하기 ES6부터 CLI를 활용해야한다. node.js, npm, react, git등을 활용하려면 터미널을 활용해야 한다. ...

May 31, 2025

OS. Operating System 오버뷰

운영체제(OS) 컴퓨터 하드웨어와 사용자 사이에서 중간 역할을 수행하며, 하드웨어 자원을 효율적이고 안전하게 관리하고, 사용자 프로그램이 원활하게 실행되도록 지원하는 시스템 소프트웨어 커널 운영체제의 핵심 부분, 하드웨어와 직접 상호작용 하여, 자원 관리와 시스템 콜 처리를 담당하는 코드 영역, 일반적으로 운영체제는 커널을 지칭한다. 역할 운영체제는 CPU, 메모리 등의 하드웨어를 효율적으로 사용할 수 있도록 관리하고, 애플리케이션이 자원을 효율적으로 할당받아 문제 없이 실행될 수 있도록 한다. CPU 관리(CPU 스케줄링) CPU가 실행 중인 프로그램을 모두 동시에 실행할 수 있는 것은 아니므로, 프로그램들이 효율적으로 CPU를 할당받도록 할당 순서와 사용 시간을 결정하는 역할 ...

May 17, 2025

DB. Database 오버뷰.

데이터베이스(Database, DB) 여러 사람이 공동으로 사용하기 위해 통합, 저장하여 운영하는 데이터들의 집합 특정 조직(서비스)의 업무를 수행하는데 필요한 상호 관련된 데이터들의 모임이다. DBMS(Database Management System) 데이터베이스를 관리하기 위한 프로그램, 대표적으로 SQL을 사용하는 관계형 데이터베이스(RDBMS)가 있고, SQL을 사용하지 않는 NoSQL DBMS도 있다. 관계형 데이터베이스(Relational DB, RDB) 2차원 표를 이용해서 데이터간의 상호 관계를 정의하는 데이터베이스 스키마(Schema) 데이터베이스의 구조와 제약 조건에 대한 전반적인 명세. 엔티티, 어트리뷰트, 릴레이션, 제약 조건 등을 전반적으로 정의한 DB의 구조적 정의 ...

May 3, 2025

Algorithm. LIS(Subsequence)

소개 수열의 원소를 골라내서 만든 부분 수열 중, 각 원소가 이전 원소보다 크면서, 가장 긴 길이를 가지는 부분 수열을 찾는 알고리즘 DP 방식과 Binary Search를 쓰는 Greedy 방식 두 가지가 있으며, 별개의 방식이 아닌 두 방식이 밀접하게 연관되어 있다. 아이디어 LIS는 현재까지 구한 부분 수열의 결과를 이용해 더 긴 부분 수열을 만들어 나가는 문제이다. DP는 이전 계산 결과를 이용해 현재 상태를 구하며, Binary Search를 이용한 방식은 같은 아이디어를 유지하면서 탐색 과정을 최적화한 것이다. ...

April 3, 2025

Software Engineering. DI와 DIP

의존성 주입(Dependency Injection) 의존성 주입은 객체가 필요한 의존성을 내부에서 직접 생성하지 않고 외부에서 전달받는 방식이다. 별도의 DI 프레임워크나 주입 전용 객체가 반드시 필요한 것은 아니다. 생성자를 통해 객체를 전달하는 것만으로도 의존성 주입이 된다. 의존의 의미 A → B: A가 B에 의존한다. A가 동작하기 위해 B의 타입이나 기능을 사용한다면 A는 B에 의존한다. B의 공개 인터페이스가 바뀌면 A도 영향을 받을 수 있다. 다음 코드에서 Greeter는 구체 타입인 EnglishGreetingProvider를 직접 생성한다. final class EnglishGreetingProvider { func greeting() -> String { "Hello, World!" } } final class Greeter { private let provider = EnglishGreetingProvider() func greet() { print(provider.greeting()) } } 이 구조에서는 구현을 교체하거나 테스트 대역을 사용하려면 Greeter를 직접 수정해야 한다. ...

March 27, 2025

Network. VPN(Virtual Private Network)

소개 VPN은 공용 네트워크를 이용하여 사설 네트워크처럼 안전하게 통신할 수 있도록 하는 기술이다. 공용 네트워크를 통해 사설 네트워크처럼 안전하게 데이터를 주고받는 기술, 데이터를 암호화하여 외부로부터의 도청, 해킹, 감시로부터 보호하고, 원격으로 사설 네트워크에 안전하게 접속할 수 있도록 한다. 동작 원리 암호화 사용자의 데이터를 암호화 하여 전송하므로, ISP나 외부에서 데이터를 읽을 수 없도록 한다. 터널링 VPN 터널이라는 보안 통로를 통해 전송됨, 데이터 패킷을 감싸 보호하는 역할을 한다 대표적인 VPN 프로토콜: OpenVPN, IPsec, WireGuard IP 주소 변경 VPN 서버를 통해 인터넷에 접속하면 목적지 서버에는 사용자의 공인 IP 대신 VPN 서버의 IP가 보인다. 하지만 VPN 사업자는 사용자의 원래 IP와 트래픽 정보를 볼 수 있고, 쿠키나 계정 같은 다른 식별 수단도 남으므로 VPN이 익명성을 보장하는 것은 아니다. ...

March 4, 2025

SniffMEET. 닉네임 검증 개선 고민

작업 내역 닉네임 TextField의 검증 방식을 다시 정리했다. 현재는 UITextFieldDelegate로 길이 검증과 버튼 활성화를 처리하고 있었는데, 중복 체크까지 같은 흐름에 넣을 경우 네트워크 요청이 너무 자주 발생할 수 있어 보였다. 현재 구현 현재는 Delegate 기반으로 다음 두 가지를 처리하고 있었다. extension ProfileCreateViewController: UITextFieldDelegate { func textFieldDidChangeSelection(_ textField: UITextField) { guard let textCount = textField.text?.count else { return } submitButton.isEnabled = (textCount > 1 && textCount < 9 ) } func textField( _ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String ) -> Bool { guard let text = textField.text else { return false } let newLength = text.count + string.count - range.length let inputTextValid = newLength <= 15 return inputTextValid } } 길이 검증 자체는 단순했고, 현재 사용성도 나쁘지 않았다. 문제는 중복 체크처럼 네트워크 요청이 들어가는 검증까지 같은 방식으로 처리하기에는 부담이 커진다는 점이었다. ...

February 13, 2025

Swift. 프로토콜 요구사항과 메소드 어트리뷰트

RemoteDBRequestBuildable 프로토콜을 추가한 뒤, 이전에는 나타나지 않던 unused-result 경고가 발생했다. 구체 타입에서는 사라졌던 경고 기존 구현의 request()에는 @discardableResult가 붙어 있었다. 반환값을 사용하지 않아도 경고가 발생하지 않았다. final class SupabaseDBRequestBuilder { @discardableResult func request() async throws -> Data { Data() } } let concrete = SupabaseDBRequestBuilder() try await concrete.request() 이후 Builder를 프로토콜로 추상화했지만 프로토콜 요구사항에는 해당 어트리뷰트를 붙이지 않았다. protocol RemoteDBRequestBuildable { func request() async throws -> Data } extension SupabaseDBRequestBuilder: RemoteDBRequestBuildable {} let abstract: any RemoteDBRequestBuildable = SupabaseDBRequestBuilder() try await abstract.request() 구체 구현에는 여전히 @discardableResult가 있는데도, 프로토콜 타입으로 호출하면 경고가 다시 나타났다. 호출을 검사하는 선언과 실행할 구현 컴파일러는 호출 지점의 정적 타입을 기준으로 사용할 메서드 선언을 해석한다. ...

February 10, 2025

SniffMEET. 세션 저장 메소드를 공개해도 괜찮을까?

세션 저장하기 AuthManager와 SessionManager의 역할을 분리하고 나니, 세션을 받아오는 쪽과 저장하는 쪽이 서로 달라지는 문제가 발생했다. (AuthManager가 세션도 관리하던)기존 구조에서는 saveSession(for:)가 외부에 노출되어 있지 않았는데, 역할이 옮겨진 뒤에는 AuthManager에서 받아온 세션을 SessionManager로 전달해야 했다. 고민한 점 saveSession(for:)는 사실상 AuthManager가 세션을 받아온 상황에서만 필요한 메소드다. 그런데 이 메소드를 공개하면 캡슐화가 약해진다는 생각을 했고, 다시 AuthManager로 돌리면 SessionManager가 맡아야 할 책임을 되돌리는 것이 되었다. 따라서 몇 가지 방법을 떠올려 봤다. (최종 선택) saveSession(for:)를 공개한다 saveSession(for:)를 AuthManager로 다시 옮긴다 같은 로직을 AuthManager와 SessionManager에 각각 작성한다 세션이 갱신됐다는 이벤트를 따로 전달할 수 있는 통신 레이어를 만든다 처음에 가장 괜찮아 보였던 건 세션 갱신 이벤트를 따로 전달하는 방식이었다. ...

February 10, 2025

SniffMEET. 세션 갱신과 정보 접근을 SessionManager에 캡슐화하기

SessionManager 사용성 개선 세션을 갱신하는 방법 Supabase 서버와의 통신이 필요할 때, 우선 세션의 유효성을 검증해야 한다. 기존 방식에선 직접 AuthManager의 싱글톤 객체에서 세션을 갱신하는 작업을 했지만 AuthManager와 SessionManager의 역할 명확하게 분리 AuthManager의 싱글톤 해제 와 같은 변화점이 있었고, 기존 AuthManager가 담당하던 세션 갱신, 복원 작업이 SessionManager로 옮겨졌다. SessionManager의 싱글톤 객체에서 세션의 유효성을 체크하는 컴퓨티드 프로퍼티의 부울리언 값을 체크하여 세션을 갱신하는 메소드를 호출하는 방식을 사용했다: if try SessionManager.shared.isExpired { try await SessionManager.shared.refreshSession() } 이 방식은 SessionManager의 싱글톤 객체 호출이 두 번 일어나고, refreshSession이라는 메소드를 직접 노출해서, SessionManager가 세션을 갱신하는 방법을 직접 노출하는 문제가 있다. ...

February 10, 2025