inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

pk 현대적인 설계관련해서 궁금한게있습니다~

미해결

김영한의 실전 데이터베이스 - 설계 1편, 현대적 데이터 모델링 완전 정복

안녕하세요. 영한님 현대적인 설계는 대리키를 PK 로 두라고 하셨습니다. 그 이유는 성능적인 측면으로 봤을때 자연키를 PK 로 두면 중간삽입이 자주 발생하여 페이지 단편화가 발생한다고 하셨습니다. 그리고 대리키로 AUTO-INCREMENT 를 주로 사용하시던데 일자-순번을 대리키로 사용해도 되나요? 등록된 일자와 그 일자의 순서에 따른 순번으로 PK 를 따는것도 괜찮은 방법인지 궁금합니다.

  • sql
  • mysql
  • dbms/rdbms
  • 소프트웨어-설계
  • SQLD
backendman 댓글 1 좋아요 1 조회수 118

[강의 자료 오타 제보]

해결됨

오브젝트 - 기초편

안녕하세요 . 제가 생각했을 땐 오타인 거 같아 제보드립니다. HIGH COUPLING이 높은 결합도라고 명시되어 있는게 맞는 거 같아 제보드려요! 시간대는 7:13분대 화면입니다.

  • 객체지향
  • 소프트웨어-설계
거북이 댓글 2 좋아요 1 조회수 88

다대다 엔티티 질문

미해결

김영한의 실전 데이터베이스 - 설계 1편, 현대적 데이터 모델링 완전 정복

수업 시간중에 속성이 있을때랑 속성이 없을때에 다대다 연결 방식이 다르다고 하셨는데, 그러면 다대다 연결이고 속성이 없으면 철저히 "연관 엔티티" 라고 말하면 안되는 건가요? 약간 말장난처럼 느껴져셔 헷갈려요ㅠㅠ ++ 질문 모든 테이블은 반드시 하나의 primary key 만을 가져야하나요? 감사합니다.

  • sql
  • mysql
  • dbms/rdbms
  • 소프트웨어-설계
  • SQLD
ghuhan18 댓글 2 좋아요 0 조회수 117

8-5 책임 분리를 통한 중복 코드 제거 과정에서 특정 조합은 불가능할 때

해결됨

오브젝트 - 설계 원칙편

안녕하세요! AbstractReader로부터 파싱에 대한 책임을 분리하여 Parser라는 클래스를 새로 생성하는 내용 잘 들었습니다! 여기서 궁금한 것이 생겨 질문 남깁니다..! DatabaseReader, RedisReader, FileReader / CsvParser, JsonParser, XmlParser 구성은 총 9가지의 경우의 수가 나올 수 있을 것 같은데요 만약 '(DatabaseReader, XmlParser)는 불가능하고 (DatabaseReader, CsvParser)와 (DatabaseReader, JsonParser)가 가능하고, (RedisReader, XmlParser)와 (RedisReader, CsvParser)는 불가능하고 (RedisReader, JsonParser)만 가능하다' 와 같이 특정 조합이 불가능한 경우는 어떻게 컴파일 타임에 가능한 조합으로만 강제할 수 있을지 궁금합니다!

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
hello 댓글 2 좋아요 2 조회수 550

간접 참조에 대한 질문

해결됨

오브젝트 - 기초편

안녕하세요! 강의에 대한 질문이 있습니다. 실무에서 직접참조보다 간접참조를 선호하고 있는데요. 간접참조의 경우에는 어떻게 구현해야 객체지향적일 지 궁금합니다. 예를 들어서 Screening 객체가 Movie 객체를 간접 참조로 MovieId만 가지고 있는 경우 서비스 레이어에서 DAO를 통해 Movie 객체를 조회한 후 reservce() 메시지에 같이 넘겨야 할까요?

  • 객체지향
  • 소프트웨어-설계
박명규 댓글 2 좋아요 1 조회수 156

도움 되었어요!

해결됨

시스템 디자인 첫걸음: 면접에서 돋보이는 백엔드 아키텍처 설계하기

우와아 아키텍처에 대해 고민하게 된 비전공자인데 올려주신 강의가 많은 도움이 되었습니다. 감사합니다 :)!

  • 아키텍처
  • 면접
  • backend
  • 소프트웨어-설계
  • 시스템-디자인
로본 댓글 2 좋아요 0 조회수 125

채팅 시스템 메시지 플로어 질문드립니다

해결됨

모르면 승진 안되는 시스템 디자인

안녕하세요. 채팅시스템 1:1 메시지 플로우에서 질문드립니다 chat server i chat server j ... chat server n 존재할때 각 클라이언트는 서로다른 서버에 websocket 프로토콜로 연결이 되어있을꺼 같은데요 이때 i 서버에 있는 sender 가 j 서버에 있는 receiver 에서 메시지를 전송한다고 했을때 온라인시점에서 i 서버에서 메시지를 전송했다는 이벤트(혹은 시점)를 j 서버가 인지해야 각 서버의 websocket 에 연결되어있는 클라이언트들에게 메시지를 push 를 해줄수 있을꺼같은데요 키 벨류 스토어 외에 메시징 관련 시스템이 별도로 있어야 할꺼같은데 강의에서 해당 내용을 어떻게 설명해주신지 (큐를 통해 설명해주신건지) 명확하게 이해를 못한부분이 있어 질문드리게 됐습니다 감사합니다

  • 소프트웨어-설계
  • 시스템-디자인
  • 소프트웨어-공학
램쥐뱅 댓글 1 좋아요 0 조회수 107

6-2. 명령과 쿼리 분리 원칙 질문

해결됨

오브젝트 - 설계 원칙편

6-2. 명령 쿼리 분리 원칙으로 부수효과 관리하기에 관해 궁금한 점이 있어 질문드립니다! 명령과 쿼리 분리하기 14:43 ~ 해당 부분에서 Player 의 move 메서드를 canMove 라는 쿼리와 move 라는 명령으로 분리했는데, 여기서 궁금한 점이 있습니다. Player 는 이동 가능 여부에 대해 스스로 판단하고 그 결과에 따라 상태를 스스로 변경하는데, Game 의 tryMove 에서 성공과 실패에 대해 try-catch 구문을 사용하지 않고 if 분기를 사용하는 이유가 무엇인가요? 저는 tryMove 에서 canMove 쿼리 호출 없이 move 명령을 호출하고, 성공/실패에 대한 처리는 try-catch 에서 예외처리하는 것이 더 간단하다 생각했습니다. 이번 강의인 6-2의 Player 와 8-2 아이템 이동 로직 개선 강의의 Transfer 객체 둘 다 동일한 구조로 코드가 짜여져있어 if 분기를 사용한 이유가 궁금합니다! 현재 구조에서 Player 의 move 메서드에 예외를 던지는 if 분기가 없다면 Game 이 Player 의 이동에 관련된 모든 것을 결정하며 TDA 를 위반하는 코드라 생각합니다. 그렇다면 if 분기는 TDA 를 위반하지 않기 위해 넣은 것인가요? 아니면 Player 와 협력하는 다른 클라이언트가 canMove 호출 없이 move 를 호출할 경우를 대비해 넣은 것인가요? 후자라고 생각하기에는 1번 질문처럼 Player 가 스스로 판단할텐데 try-catch 대신 if 분기를 넣은게 잘 와닿지 않아 질문드립니다!

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
강명덕 댓글 2 좋아요 2 조회수 546

Redis 랜덤 값 추가 시 메타데이터 저장

해결됨

AI 시대에도 살아남는 엔지니어의 조건, 미국 빅테크 시스템 디자인, 알고리즘 사고, 오픈소스 실무 완성

Redis에 랜덤한 값을 키에 저장할 시 해당 키 탐색을 위해 FULL SCAN O(1) 대신 메타데이터를 통해서 탐색한다고 말씀하셨는데 이 메타데이터 자체도 Redis에 저장하는건가요? 아니면 programmatically하게 Map이나 딕셔너리에 저장한다는 의미인가요?

  • 소프트웨어-설계
  • 시스템-디자인
강토토 댓글 1 좋아요 0 조회수 122

사전문제가 잘 보이지 않습니다 !

해결됨

카카오 코테 6주 합격! 실전 파이썬 코딩테스트

(사진)

  • 코딩-테스트
  • 알고리즘
  • 소프트웨어-설계
  • data-structure
박시콩 댓글 2 좋아요 0 조회수 112

레디스(중앙 상태 관리 서버)에서 동시성 처리 하는 방식

미해결

대규모 시스템 설계 Part 1

동시성 제어는 분산락 원자적 연산 방식으로 해결한다고 설명해주셨는데, 레디스 분산락의 경우, 락을 획득하려는 클라이언트가 Redis의 Set 명령어를 사용하게 되는데, 이때 NX(Not eXists) 옵션을 통해 키가 존재하지 않을 때만 값을 설정하도록 하기 때문에, 이 연산은 원자적으로 수행된다고 합니다. 결론적으로 1, 2안 모두 원자적 연산을 의미하는것이라고 생각이 들어 헷갈리는데요..! 혹시 어떤 의도로 말씀해주신건지 설명해주실 수 있나요? 그리고 Redis를 예시로 들었을때, 레디스는 싱글 스레드 동작 방식이라서, 동시성 문제가 제어 된다고 하는데, 이 동시성 문제가 실제로 발생하는 경우는 어떻게 되는건지, redis 서버가 다중 노드일 때 발생하는건지 궁금합니다.

  • dbms/rdbms
  • 소프트웨어-설계
동동이는배를동동 댓글 3 좋아요 0 조회수 282

9-1 사소한 강의자료 오류

해결됨

오브젝트 - 설계 원칙편

9-1. 더 많은 요구사항 추가하기 강의자료 p.45, 강의영상 9:05 ~ WorldMap 은 target 으로 사용될 경우에만 Carrier 를 치환할 수 있는데, 해당 슬라이드에서만 강의자료의 설명과 X 표시가 잘못된 것 같습니다. 영상에서의 설명은 올바른데 자료 표기만 문제가 있는 것 같아 남깁니다!

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
강명덕 댓글 2 좋아요 1 조회수 109

7-3 상속을 이용한 중복 제거 질문 있습니다!

해결됨

오브젝트 - 설계 원칙편

7-3. 의존성 역전 원칙 - 추상화와 세부사항 13:43~ 수업을 듣던 도중 추상 클래스를 인터페이스와 함께 사용한 이유 가 궁금해 질문드립니다. 상속이 코드 재사용을 위해 그다지 좋은 방법이 아니라는(+ 자세한 내용은 뒤에서 더 자세히 살펴봄) 언급을 해주셨지만, 우선 여기서는 왜 이렇게 코드를 짰는지 궁금해 고민한 부분을 여쭤보고자 합니다. 인터페이스와 추상 클래스를 함께 사용하는 이유 1. 협력을 위해 제공하는 메시지를 확인하기 용이하기 때문인가요? 해당 강의를 듣고나서 맨 처음 들었던 생각은, "추상 클래스로만 추상화를 한 뒤, 상위 수준 객체가 인터페이스 대신 추상 클래스를 의존하면 안될까?" 였습니다. 추상클래스를 사용하더라도 read() 만 public 이고 readLines() 나 parse() 는 각각 private , protected 이므로 외부에 노출되지 않아서 괜찮지 않을까 생각했습니다. 더 고민해 보았는데, 인터페이스를 사용한다면 코드를 유지보수하는 과정에서 다음과 같은 이점을 얻을 수 있어서 그런가? 라는 생각이 들어 질문드립니다. 상위 수준의 객체가 인터페이스에 의존하면 역할을 한 눈에 파악하기 쉽다. Reader 는 read() 라는 메서드 시그니처로 "특정 데이터소스로부터 읽어오는 작업"을 수행한다. 라는 것을 인터페이스를 통해 명시한다. 즉, "명세" 역할 을 한다. 이는 유지보수 과정에서 해당 인터페이스만 읽고 구현체가 제공하는(또는 해야하는) 기능(public 메서드)들을 확인하기 용이하다. 즉, 역할을 한 눈에 파악하기 쉽다. 추상 클래스에 의존하면 역할을 한 눈에 파악하기 어렵다. AbstractReader 는 메서드 시그니처 뿐만 아니라 중복 로직의 경우 구현 내용까지 포함하고 있고, 여러 메서드들 중 외부에서 협력하기 위해 pubilc 으로 노출시켜 제공하는 기능을 한 눈에 파악하기 어렵다. 위 두 가지 내용이 인터페이스를 추상클래스와 함께 사용하는 이유가 될 수 있을까요? 2. 두 public 메서드 중 하나는 중복 로직, 하나는 각 구현체마다 다르게 구현하는 경우에도 인터페이스와 추상클래스를 함께 사용하는 것이 좋을까요? 1번에서 인터페이스와 추상클래스를 함께 사용한 이유로 언급했던 "역할을 한 눈에 파악하기 쉽다"는 장점이 있다면, 두 메서드 모두 public 일 때에도 추상클래스로만 구현하기 보다는 인터페이스와 추상클래스를 함께 사용하는 것이 좋을까요? 2번 질문은 예시 코드를 드리자면 Spring Boot 개발환경에서 작업한 코드로 CaptchaHashProcessor 인터페이스에는 public 메서드인 hash() , verify() 두 메서드가 있습니다. 해당 인터페이스를 구현한 두 구현체에서 verify() 메서드가 중복되는 상황입니다. 기존 코드 두 public 메서드를 제공하는 인터페이스 public interface CaptchaHashProcessor { HashResult hash(Long captchaId); Long verify(String hashedCode, Long userId); } 구현체 1 - hash 는 다르게 구현하나 verify 는 구현체 2와 내용 동일 public class RandomCaptchaHashProcessor implements CaptchaHashProcessor { private static final SecureRandom RANDOM = new SecureRandom(); private final Encryption encryption; private final CaptchaLogPort captchaLogPort; private final EncryptionProperties properties; @Override public HashResult hash(Long captchaId) { // 구현체마다 다름... } @Override public Long verify(String encryptedCode, Long userId) { // 중복 로직 ... } } 구현체 2- hash 는 다르게 구현하나 verify 는 구현체 1과 내용 동일 public class FixedCaptchaHashProcessor implements CaptchaHashProcessor { private static final String FIXED_IV = Base64.getEncoder().encodeToString(new byte[16]); private final Encryption encryption; private final CaptchaLogPort captchaLogPort; @Override public HashResult hash(Long captchaId) { // 구현체마다 다름... } @Override public Long verify(String hashedCode, Long userId) { // 중복 로직 ... } } 추상클래스 사용 여기서 추상클래스로 verify 중복 로직을 이동시키면서 인터페이스를 사용한다면 인터페이스를 구현한 추상클래스 public abstract class AbstractCaptchaHashProcessor implements CaptchaHashProcessor { protected final Encryption encryption; private final CaptchaLogPort captchaLogPort; @Override public Long verify(String hashedCode, Long userId) { // 추상 클래스로 이동한 중복 로직 ... } } 구현체 1 public class RandomCaptchaHashProcessor extends AbstractCaptchaHashProcessor { private static final SecureRandom RANDOM = new SecureRandom(); private final EncryptionProperties properties; public RandomCaptchaHashProcessor(Encryption encryption, CaptchaLogPort captchaLogPort, EncryptionProperties properties) { super(encryption, captchaLogPort); this.properties = properties; } @Override public HashResult hash(Long captchaId) { // 구현체마다 다름 ... } } 구현체 2 public class FixedCaptchaHashProcessor extends AbstractCaptchaHashProcessor { private static final String FIXED_IV = Base64.getEncoder().encodeToString(new byte[16]); public FixedCaptchaHashProcessor(Encryption encryption, CaptchaLogPort captchaLogPort) { super(encryption, captchaLogPort); } @Override public HashResult hash(Long captchaId) { // 구현체마다 다름 ... } } 이렇게 구현할 수 있을텐데, 인터페이스를 사용하지 않는다면 hash 메서드까지 추상 클래스의 추상 메서드로 명시해서 상위 수준 클래스가 추상 클래스에 의존해도 될 것 같아서 고민이 됩니다! 이 질문을 작성하면서 다른 생각도 떠올랐는데요, CaptchaHashProcessor 는 캡챠 코드를 암호화(hash) 하고 캡챠 코드를 검증(verify) 한다는 두 가지 책임을 가진 것 같아서 어쩌면 암호화 책임은 인터페이스와 그 구현체들로 제공하고, 검증 책임은 또다른 클래스에서 구현하는 것이 적절한가? 하는 생각도 듭니다... 좋은 강의를 제공해주시고 긴 질문 읽어주셔서 감사합니다. 질문은 타인이 저에게 소중한 시간을 소비하는 것이라 생각해 강사님의 시간 낭비가 되지 않도록 영양가 있는 질문을 잘 하고싶습니다. 혹시나 질문의 내용 구성이나 태도, 질문을 이끌어낸 사고과정 등에서 부족한 부분이 보였다면 어떻게 개선하면 좋을지 말씀해주시면 감사하겠습니다!

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
강명덕 댓글 1 좋아요 3 조회수 1191

시니어엔지니어 지원

해결됨

모르면 승진 안되는 시스템 디자인

이정도 스콥만 어느정도 완전히 인지하면 시니어 레벨 엔지니어 시스템 디자인 인터뷰는 어느정도 커버 될까요?

  • 소프트웨어-설계
  • 시스템-디자인
  • 소프트웨어-공학
댓글 1 좋아요 0 조회수 128

Blob Storage에서 파일 업로드에 대한 동시성을 어떻게 제어할 수 있을까요?

해결됨

AI 시대에도 살아남는 엔지니어의 조건, 미국 빅테크 시스템 디자인, 알고리즘 사고, 오픈소스 실무 완성

용량이 큰 파일의 binary를 기반으로 해시화해서 동시 업로드 할 경우 동일한 파일이 업로드 될 수 있을 것 같습니다. 이럴 경우 해결책이 있을까요?

  • 소프트웨어-설계
  • 시스템-디자인
이정환 댓글 2 좋아요 0 조회수 160

함수형 스타일에 대해선 어떻게 생각하시나요?

해결됨

오브젝트 - 설계 원칙편

이제 꼭 함수형 언어를 사용하지 않더라도 요즘 언어들 대부분 함수형 언어의 아이디어나 장점들을 반영하는 트렌드인데, 회사에서도 코틀린을 사용 중이라 질문 드려봅니다. 코틀린 라이브러리들을 사용하다 보면 함수형 스타일의 설계와 API들을 꽤 많이 보고 있기도 하고 특히 람다를 굉장히 많이 사용하는데 적절하게 람다나 함수형 스타일의 코드를 사용하는 기준이나 원칙들도 있으신지 궁금하네요.

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
빡소리 댓글 2 좋아요 1 조회수 142

값 객체 활용에 대해

해결됨

오브젝트 - 설계 원칙편

안녕하세요. 항상 객체 지향의 본질을 가르쳐주시는 강의 정말 잘 듣고 있습니다. 실무에서 JPA를 사용할 때 값 객체 활용에 대해서도 궁금합니다. RDB 기준 하나의 테이블에 매핑되는 경우말고, 값 객체를 별도의 테이블로 매핑해야될 경우에도 많이 사용하시는지 궁금합니다.

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
빡소리 댓글 2 좋아요 1 조회수 172

노션링크

해결됨

Python을 위한 디자인 패턴

conceptual_singleton.py 강사님 싱글톤패턴 드롭다운 코드예시 9:25 이부분 코드 예시가 펼쳐져 있지않아서 볼수가없네요. 팩토리패턴 예시도 강의영상에서는 펼쳐져있지않네요. 노션링크를 보면서 학습해야할 것같은데 어디있는지 모르겠습니다 ㅠ

  • python
  • 객체지향
  • 디자인-패턴
  • 소프트웨어-설계
  • 클린코드-기획전
미노 댓글 3 좋아요 1 조회수 245

스스로 고민하고 답을 보지 않고 구현을 해보았는데요

해결됨

카카오 코테 6주 합격! 실전 파이썬 코딩테스트

# 1012 T = int(input()) dx = [0, 0, 1, -1] dy = [-1, 1, 0, 0] for _ in range(T): M, N, K = map(int, input().split()) graph = [[0] * M for i in range(N)] st = [] seen = set() # seen.add((0, 0)) for i in range(K): x, y = map(int, input().split()) graph[y][x] = 1 st.append([y, x]) cnt = 0 while st: cur = st.pop() for i in range(4): x = dx[i] + cur[0] y = dy[i] + cur[1] if not (0 <= x < N and 0 <= y < M): continue if (x, y) in seen: continue if graph[x][y] == 0: continue st.append([x, y]) seen.add((x, y)) if (cur[0], cur[1]) in seen: continue else: seen.add((cur[0], cur[1])) cnt +=1 print(cnt) 값이 처음 구현 햇을때 제대로 안나오길래 원래는 cur를 for i in range(4) 위에서 seen에 찍어줬었는데 -> 실패 그래서 cur를 방점을 찍어주듯이 주변을 다 돌고 자신을 seen에 찍게 했더니 통과가 되서 혹시 코드에 조언해주실 수 있는지 질문드립니다!

  • 코딩-테스트
  • 알고리즘
  • 소프트웨어-설계
  • data-structure
감스트의웃음노예 댓글 2 좋아요 0 조회수 143

실례지만 여기에 후기 올립니다.

해결됨

오브젝트 - 설계 원칙편

영호님 강의 잘 들었습니다. 객체지향적인 설계에 대한 근원이되는 내용에 관심이 많아 영호님의 서적과 강좌를 자주 보게 되네요 본론 시중에 나와 있는 서적과 강좌가 정말 잘 되어 있는 만큼 사람들이 많이 사용하는 스프링 프레임워크에 적용한 예제도 가끔 있으면 어떨까 합니다. 생각보다 이 부분이 제 주변인들의 가려운 부분이었어요 예를 들면 스프링을 사용하는 가정하에 비즈니스 계층에 적용해야하는데, 다형성이 필요한 서비스의 경우 "인터페이스 - 구현체" 로 구축시 구현체들을 Spring Bean으로 사용할 경우, 컴파일 시 구체적인 구현체가 아니라 에러가 나는데 이럴때는 구현체를 매핑해주는 팩토리를 생성해서 사용해야된다 와 같은 다소 객체지향과는 동떨어지지만 소소한 설명이 언급되어도 좋을 것 같습니다. 아마 강좌나 서적을 보는 많은 사람들이 비슷한 생각일 것 같습니다. "이 부분을 만약에 업무에 적용시킨다면 어떻게 해야 할까나?" 대부분 이런 생각이지 않을까 해서 드린 말씀입니다. 항상 고품질의 강좌와 서적을 위해 애써주시는 영호님께 다시 한 번 감사드립니다.

  • 객체지향
  • 소프트웨어-테스트
  • 소프트웨어-설계
ycseol 댓글 3 좋아요 2 조회수 612

인기 태그

인프런 TOP Writers

주간 인기글