routine.entity.ts

import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Timestamps } from '../../TimeStamp.entity';
import { User } from '../../user/domain/User.entity';
import { RoutineToExercise } from '../../routineToExercise/domain/RoutineToExercise.entity';

@Entity()
export class Routine extends Timestamps {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToOne(() => User, (user) => user.routines)
  public user: User;

  @OneToMany(() => RoutineToExercise, (routineToExercise) => routineToExercise.routine)
  public routineToExercises: RoutineToExercise[];

}

 

exercise.entity.ts

import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Timestamps } from '../../TimeStamp.entity';
import { BodyPart } from './bodyPart.enum';
import { WorkoutLogToExercise } from '../../workoutLogToExercise/domain/WorkoutLogToExercise.entity';
import { RoutineToExercise } from '../../routineToExercise/domain/RoutineToExercise.entity';

@Entity()
export class Exercise extends Timestamps {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ type: 'enum', enum: BodyPart })
  bodyPart: BodyPart;

  @Column()
  exerciseName: string;

  @OneToMany(() => WorkoutLogToExercise, (workoutLogToExercise) => workoutLogToExercise.exercise)
  workoutLogToExercises: WorkoutLogToExercise[];

  @OneToMany(() => RoutineToExercise, (routineToExercise) => routineToExercise.exercise)
  routineToExercises: RoutineToExercise[];

}

 

routineToExercises.entity.ts

import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Exercise } from '../../excercise/domain/Exercise.entity';
import { Routine } from '../../routine/domain/Routine.entity';

@Entity()
export class RoutineToExercise {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToOne(() => Routine, (routine) => routine.routineToExercises)
  public routine: Routine;

  @ManyToOne(() => Exercise, (exercise) => exercise.routineToExercises)
  public exercise: Exercise;
}

 

 

routine 에서  유저 A 가 게시한 routine 목록을 검색하고 이와 연관된 excersie 값도 같이 검색한다. 이때 모든 값을 다 보여주지 않고 선택된 값만 반환 받는다.

const routines = await this.routineRepository
      .createQueryBuilder('routine')
      .leftJoinAndSelect('routine.routineToExercises', 'routineToExercises')
      .leftJoinAndSelect('routineToExercises.exercise', 'exercise')
      .innerJoin('routine.user', 'user')
      .select([
        'routine.id',
        'routine.name',
        'routineToExercises.id',
        'exercise.id',
        'exercise.exerciseName',
        'exercise.bodyPart',
      ])
      .where('routine.name = :name AND user.id = :userId', { name: 'test', userId: user.id })
      .getMany();

용어 설명

 

  • createQueryBuilder() : SQL 쿼리를 보다 세밀하게 제어할 수 있게 해주는 메소드입니다
    •  createQueryBuilder('routine')
      • routineRepository 를 이용하여 생성된 쿼리에서 Routine 엔티티를 참조할 때 사용할 별칭을 routine 으로 합니다.
  • .leftJoinAndSelect() : 지정된 엔티티와 연결된 다른 엔티티를 "왼쪽 조인"으로 불러오며, 결과에 포함시키기를 원하는 필드를 선택적으로 로드합니다.
    • .leftJoinAndSelect('routine.routineToExercises', 'routineToExercises')
      • Routine 과 RoutineToExercises 사이에 설정된 관계를 기반으로 왼쪽 조인을 수행하고, routineToExercises라는 별칭을 사용하여 조인된 결과를 선택합니다.
      • 이 조인은 Routine 과 RoutineToExercises 사이의 관계를 탐색하고 관련 데이터를 반환합니다.
      • 일치하는 항목이 없어도 Routine 데이터는 반환합니다.
  • .innerJoin() : 조건을 만족하는 데이터만 결과에 포함시키는 "내부 조인"을 수행합니다. 연결된 테이블의 매칭되는 행이 없다면 결과에서 해당 데이터를 제외합니다.
    • .innerJoin('routine.user', 'user')
      • Routine 테이블의 user 필드와 User 테이블에서 일치하는 항목만 결과에 포함시킵니다.
  • .where() :쿼리에서 데이터를 필터링할 조건을 설정하는 부분입니다.
    • .where('routine.name = :name AND user.id = :userId', { name: 'test', userId: 3 })
      • 조건을 설정 : routine.name = :name AND user.id = :userId
        • routine.name = :name 은 Routine 테이블의 name 필드가 쿼리 파라미터 :name으로 지정된 값과 일치해야 한다는 것을 의미합니다.
        • :name, :userId와 같은 표현은 쿼리에 사용될 변수의 이름으로 자유롭게 지정할 수 있습니다.
      • 파라미터 바인딩: { name: 'test', userId: user.id }
        • name 필드가 'test' 이고 userId 필드가 user.id 에 일치하는 데이터만 반환합니다.

 

 

Mutex 와 Semaphore 는 모두 병행성 프로그래밍에서 상호배제를 달성하는 도구

  1. Mutex (뮤텍스):
    • 한 번에 하나의 스레드만이 자원에 접근할 수 있도록 하는 동기화 메커니즘입니다.
    • 이는 보통 크리티컬 섹션을 보호하거나 공유 자원에 대한 접근을 제어할 때 사용됩니다.
    • Mutex는 잠금을 획득한 스레드만이 해당 자원을 사용할 수 있도록 합니다
  2. 세마포어 (Semaphore):
    • 동시에 여러 스레드가 자원에 접근할 수 있는 허용 개수를 지정할 수 있는 동기화 기법입니다.
    • Counting Semaphore 과 Binary Semaphore로 나뉘며, Counting Semaphore은 여러 자원을 제어할 수 있습니다.
    • Semaphore는 초기값과 현재 값을 비교하여 스레드의 접근을 허용하거나 차단합니다

두 기법의 주요 차이

  • Mutex : 단일 자원에 대한 접근을 보호
  • Semaphore: 동시 접근 허용의 유연성을 제공

'컴퓨터 공학 > 운영체제' 카테고리의 다른 글

[OS] 경쟁상태 (Race Condition)  (1) 2024.06.19
[ OS ] 문맥교환 (context switch)  (0) 2024.06.18
[ OS ] 시스템 콜 (system call)  (0) 2024.06.18

 공유 자원에 대해 두개 이상의 프로세스가 동시에 접근을 시도할 때 접근의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태

→실행순서에 따라 결과값이 달라질수 있는 상태

 

경쟁상태에서 직면할 수 있는 문제

Mutual exclusion(상호배제) 위반 문제

  • 자원은 한 번에 하나의 프로세스 또는 스레드만이 사용할 수 있어야 한다.

deadlock (교착상태)

  • 멀티프로세스나 멀티스레드 환경에서 발생할 수 있는 상황으로, 각 프로세스 또는 스레드가 서로가 가지고 있는 자원을 점유한 채로 다른 프로세스 또는 스레드가 필요로 하는 자원을 기다리는 상태를 말합니다
  • 각 프로세스가 서로 필요로 하는 자원을 점유한 채 대기 상태에 빠진상태

starvation(기아상태)

  • 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리다가 끊임없이 필요한 컴퓨터 자원을 가져오지 못하는 상황을 말합니다.
  • 특정 프로세스가 필요한 자원을 영원히 할당받지 못하여 작업을 진행하지 못하는 상태

예방 방법

두 개 이상의 프로세스가 동시에 하나의 자원을 사용할 수 없도록 막아야한다.

이를 실현하기 하기 위한 방법으로  Mutex (Mutual Exclusion) 와 Semaphore(세마포어) 가 있다.

  • Mutex : 공유된 자원의 데이터를 여러 스레드가 접근하는 것을 막는 방법
  • Semaphore: 공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는 것, 하나의 스레드만 들어가게 할 수도 있고 여러 개의 스레드가 들어가게 할 수 있다

'컴퓨터 공학 > 운영체제' 카테고리의 다른 글

[ OS ] 세마포어 와 뮤텍스  (0) 2024.06.19
[ OS ] 문맥교환 (context switch)  (0) 2024.06.18
[ OS ] 시스템 콜 (system call)  (0) 2024.06.18

테스트코드 작성이유

  • 개발 과정에서 문제를 미리 발견할 수 있다.
  • 리팩토링을 안심하고 할 수 있다.
  • 빠른 시간 내에 코드의 동작 방식과 결과를 확인할 수 있다.
  • 좋은 테스트 코드를 연습하다 보면 자연스럽게 좋은 코드(코드 품질향상)가 만들어진다.
  • 의도한 대로 동작되는 것을 자신감 있게 말할 수 있다.

테스트코드의 종류

단위테스트 (Unit Test)

  • 함수, 메스드와 같은 개별적인 코드단위가 정상적으로 작동하는지 확인하는 테스트하는 과정

통합테스트 (Integration Test)

  • 서로다른 모듈들 간의  상호작용을 테스트하는 과정
  • 예) 신규로 만든 유저를 검색하는 API 가 정상적으로 DB 에서 유저를 찾을 수 있는지 테스트하는 과정 

E2E (End to End)

  • 애플리케이션의 흐름을 처음부터 끝까지 테스트하는 과정
  • 실제 사용자의 시나리오를 테스트함으로써 애플리케이션 동작을 테스트하게 되고, 이 테스트를 통과함으로써 애플리케이션이 문제 없이 작동하는지 확인하는 과정

 

참고자료

 

 

모든 공백제거

let str = "h e l l o w o r l d"
str = str.replace(/\s+/g, '');// helloworld

 

앞뒤 공백 제거

let str = "   hello   ";
str = str.trim(); // "hello"

 

공백확인

const str = " 123 4 "
/\s/.test(str) // true

\s 는 모든 유형의 공백 문자를 나타내는 메타 문자

+ Recent posts