5 / 19 좌측 무릎 내측 체외충격파

첫날보단 살짝 덜아프다고 느꼈지만...

여전히 아파서.  "아직 많이 아픈걸 보면 회복이 별로 안된건가봐요.."  라고 말을 했더니

 

물리치료사 : "첫 체외충격파보다 3배 강하게 하고있는겁니다"

라는 말을 듣고. 아 그럼 정말 많이 좋아진거구나! 하고 느꼈습니다.

 

치료를 받고 막 나왔을때는 항상 오.? 하나도 안아프네 ? 생각을 하지만..

 

저녁쯤엔 가만히 있어도 욱신욱신거립니다..

 

 

 

그... 프롤로 주사로 염증을 만들고.. 체외충격파로 염증을 싹 긁어낸다나.. 뭐라나.,.,.
프롤로 주사는 염증을 만들어야하니.. 아이싱이나 소염진통제 복용은 자제해야한다고 하지만..

 

이건 그래도 아이싱은 할 수 있어서 괜찮았습니다.

 

5 / 20~21 일반 물리치료만...

 

5 / 22 두번째 프롤로(인대강화주사) 주사

 

몸을 돌릴때 무릎 전면부가 아프다는 말을 했더니 

슬개골 문제네요 하면서 그쪽에도 주사를 푸슉.

두번째 주사도 무릎 주변의 열감과

몸이 전체적으로 더워지는 느낌이 있었습니다.

 

그리고 이상하리만큼 식욕이 폭발했습니다...

관련없겠지만... 

 

아 그리고 살도 왠지 1kg가 빠졌습니다.. 러닝을 한것도 아닌데.

잘먹고 살빠지다니 .. 

 

그리고 이제 한번 달려보라는 말을 들었습니다.

 

천천히 1분씩 달리고 걷고..

 

5 / 24 테스트 러닝전의 맛보기 달리기

프롤로 주사의 여파가 조금 있어서 ..
토요일이 아닌 일요일날 달리기로 정했는데..

 

그전에 혹시모르니 " 1분정도 달려보자 " 라고 생각했습니다.

 

걷기와 비슷할정도로 느리게 달려봤습니다.

무릎쪽의 뻐근함을 제외하면 크게 문제가 느껴지지않아 일요일 날 달리는데 문제가 없다고 느꼈던 것 같습니다.

 

 

5 / 25  테스트러닝

1분 달리기 + 2분걷기 *5 회

런데이 1주차 1회차 처럼 달려봤습니다.

 

거위발건염 부위가 아프지 않고 무릎 위쪽의 허벅지, 내측

이렇게 좀 찌릿한게 있었고 무릎 전면부가 약간 찌릿한게 있었습니다만

5회 달리는동안 빈도수는 매우낮았습니다.

 

 

5 / 26 세번째 체외충격파

어.. 두번째보다 더아파서 물어봤습니다.

 

"어 저번 3배보다 훨씬 더아픈데..."  라고 말을 했더니

 

물리치료사 : "지금 단계는 8단계입니다. 첫날이 1단계였습니다.. 꽤 강하게 하고있고 거의 마지막 치료에 가깝습니다."

 

 

5 / 28 런데이 복귀

4주차 첫번재 2분 30초 달리기 + 2분걷기 *5회

 

무릎에 약간의 뻐근함이 남아있었지만 달려봤습니다.

 

달릴만했고? 약간 무릎 주변. 허벅지나 종아리쪽의 자잘한 통증들이 느껴졌지만.

 

프롤로의 여파로 주변 조직까지 염증이 있을 수 있다라는 말을 들었습니다.

 

거위발건염 부분의 통증은 없었고 별 탈 없이 복귀에 성공했습니다.

 

-------------------------------------------------------------------------------------------------------------

 

 

복귀까지 총 2주 걸렸습니다.

 

프롤로(인대강화주사) 2회
체외충격파 좌측 3회 우측 1회

 

 

약간의 시림 증상이 있는 상태에서 병원에 갔습니다.

 

그런데도 복귀까지 2주나 걸린 걸 보면...

 

시림 증상을 무시하고 계속 달렸으면 어떻게 됐을지 상상이 안됩니다..

 

이상하면 바로바로 병원에 갑시다!

 

3주차

  1. 2분 달리기 + 2분 걷기 * 4 + 2분 달리기
  2. 2분 달리기 + 2분 걷기 * 5 + 2분 달리기
  3. 2분30초 달리기 + 2분 걷기 * 4 + 2분30초 달리기

 

3주차 첫번째 달리기

 

\

페이스를 8분까지 낮춰보려고 천천히 달리기에 집중했는데..

 

아직도 6분대입니다..

 

흠... 케이던스를 올리면서 페이스를 내리는게 너무 어렵습니다..

 

 

 

3주차 두번째 달리기

 

 

드디어 7분대에 왔습니다.

 

처음에는 무릎이 시큰거림이 있었는데

 

180이아닌 170bpm을 틀고 했더니 케이던스 평균이 10가량 늘었습니다.

 

기분이 매우 좋습니다.

3주차 세번째 달리기

모자이크가 있었구나..

 

어..

 

8분대로 뛰니까 숨도 차지않고 2분 30초를 매우 무난하게 달렸습니다..

 

그런데

 

무릎 안쪽이 아파서 찾아보니 거위발건염 인것 같습니다..

 

페이스를 낮춰서 달리는건 성공했지만..  쉬어야할것 같습니다.

 


 

4주차  달리기중단

 

수요일

무릎 안쪽이 계속 아파 정형외과에 갔더니

 

거위발건염 + 염증이 있었습니다

 

인대강화주사 처방받았습니다.. 

 

좌우 무릎 안쪽에 주사를 막.. 7~8번에 나눠서 맞았습니다.

 

목요일

체외 충격파 왼쪽 무릎 처방 + 물리치료

 

와 체외충격파 정말 아팠습니다.

 

두눈을 질끈 감을정도로 아팠습니다...

 

앞으로 조심스럽게 다치지 않게 달리는법을 더 공부해야 할 것 같습니다.

 

 

금요일

체외 충격파 오른쪽 무릎 처방 + 물리치료

 

어.. 생각보다 안아팠습니다..

 

이게 염증이 심할수록 아프다고 합니다(당연한건가..?)

 

다행히 오른쪽은 심하지 않아서  엄청 아프지는 않았습니다.

 

아마도 다음주까지 쉴 것 같습니다.

 

 

2주차

  1. 1분 30초 달리기 + 2분 걷기 * 4 + 1분 30초 달리기
  2. 1분 30초 달리기 + 2분 걷기 * 5 + 1분 30초 달리기
  3. 2분 달리기 + 2분 걷기 * 4 + 2분 달리기

 


2주차 첫번째 달리기

1주차 마지막부터 달리기가 1분 30초

생각보다 힘들었지만 두번째 달리는 1분 30초라 그런지 할만했습니다.

2분이 약간 걱정되지만 할만한 것 같습니다.

 

 

2주차 두번째 달리기

원래라면 화요일 달려야 했지만.. 비도오고 수요일이 예비군이였습니다.

그래서 3일 쉬고 달리게 되었습니다.

하지만 1분 30초에 꽤 익숙해진 상태라 할만했습니다.

마지막 5분 걷기에 추가로 1분30초를 더 달렸습니다.

 

 

2주차 세번째 달리기

어.. 2분 달리기가 생각보다 더 힘들었습니다.ㅋㅋㅋㅋ

마치 처음 1분달리기 할때처럼 숨이 차는게 느껴졌습니다.

 

1, 2번째 달리기엔 괜찮았지만 3번째부터 매우 숨이찼고

종아리가 뭉치고 아팠습니다.

그런데 4번째부터 숨이 조금 덜차고 종아리도 덜 아팠습니다

마지막 5번째 달리기도 생각보다 종아리도 덜 아팠습니다.

마지막 5분 걷기중 3분정도 걷기후 다시 2분 달리기를 했습니다..

 

생각보다 2분달리기가 힘들었기 때문에  3주차의 2분달리기에 대비할겸

조금 더 달렸습니다.

 


 

3분까지 30초씩 늘어나다   3분에서 4분으로 한번에 1분씩 늘어나던데

 

어우 벌써부터 걱정이됩니다...

 

그런데 재밌음!

 

뭔가 체력이 좋아지는게 느껴져 매우 기쁨!

 

 

그냥 체력을 기르고 싶었습니다.

 

그래서 시작한 달리기..

 

1주차

  1. 1분 달리기 + 2분 걷기 * 4 + 1분 달리기
  2. 1분 달리기 + 2분 걷기 * 5 + 1분 달리기
  3. 1분 30초 달리기 + 2분 걷기 * 4 + 1분 30초 달리기

 


1주차 첫번째 달리기

 

내가 마지막으로 숨차게 움직여본게 언제였을까..? 라는 생각을 가지고 시작했습니다.

 

1주차의 첫 달리기는 페이스라는걸 모르고 막 달리다 마지막에 지쳐서 힘들게 겨우겨우 완주했습니다.

 

그리고 비가 와서 이틀 쉬었습니다...  (근육통도 좀 있었습니다...)

 

 

 

1주차 두번째 달리기

 

첫번째 달리기와 다르게.. 매우 할만했습니다...

 

아주 약간의 근육통이 있었습니다만.. 이건 제가 운동을 너무 안해서 그런거라 생각하고 진행했습니다.

 

페이스도 안정되었고, 케이던스라는 것에 대해 배웠습니다

 

달리는게 재밌다고 느껴집니다... (말도안댐..)

 

 

1주차 세번째 달리기

 

어.. 1분 30초 생각보다 힘들었습니다..

 

자신만만했는데.. 오우.. ㅋㅋㅋㅋㅋ

 

맞바람이 심해서인지.. 달리는 느낌이 나지않아, 저도 모르게 페이스가 올라갔고..

 

맞바람 때문에 약간 숨쉬는데 불편함도 있었습니다..

 

그런데 어찌저찌 완주는 했습니다.

 

그리고 이 글을 쓰는 지금 근육통은 없습니다

 

막 끝났을땐 다리가 약한 후들거리는 느낌이 약간 있었는데.. 

 

지금은 내일 또 뛸까 싶은 생각이 듭니다.

 

 


 

달리기 시작하려고 운동화를 사면서, 준비만 열심히 하고 결국엔 안 할까 봐 걱정했지만..

 

막상 시작하고 달리니까 잡생각도 사라지고 좋은 것 같습니다.

 

이제 1주차 이긴 하지만.. 달리는게 재밌다고 느끼고 있고 불면증도 사라졌습니다.

 

취준생 생활에 좋은 활력소가 될 것 같습니다.

생각보다 사용방법이 어렵다 느껴 간단하게 정리해보고자 합니다.

 

Multer는 파일 업로드를 처리하는 미들웨어 입니다.

특히 multipart/form-data를 처리하는데 사용하고, 파일을 디스크 또는 메모리에 저장할 수 있습니다.

 

기본개념

multer를 사용하면 클라이언트라 form-data로 업로드한 파일을 서버에서 처리하고 저장할 수 있습니다.

 

storage: 파일 저장 방식(디스크 저장 or 메모리 저장)

destination : 파일이 저장될 폴더 지정

filename : 저장될 파일명 지정 (이름 충돌 방지)

limits : 파일 크기 제한 설정 가능

fileFilter : 특정 파일만 허용 가능 ( ex : 이미지 파일만 허용)

 

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, "uploads/");
    },
    filename(req, file, cb) {
      const ext = path.extname(file.originalname); // 이미지.png => 이미지 (날짜).png    이름중복방지
      cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
		//기존 파일명 + 현재 시간(중복 방지) + 확장자 형태로 저장
    },
  }),
});

 

  1. 파일 저장위치 : uploads/ 폴더에 저장
  2. 파일 이름 처리 : 
    • path.extname(file.originalname)    -> 파일 확장자 추출
    • path.basename(file.originalname, ext)  -> 확장자를 제외한 파일 이름 추출
    • Data.now() 를 추가하여 파일 이름이 중복되지 않도록 합니다
      (여러 사람이 이용하다보면 파일 이름 중복의 가능성이 있습니다)
    • (ex : image.png  -> image62375637545.png) 의 형식으로 저장됩니다.

 


 

Multer의 활용

 

1. 파일 업로드 (single())

<form action="/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="image" />
  <button type="submit">업로드</button>
</form>

 

app.post("/upload", upload.single("image"), (req, res) => {
  res.json({ file: req.file }); // 업로드된 파일 정보 응답
});

클라이언트가 image라는 이름으로 1개의 파일을 업로드하면 저장됨. (req.file 에 업로드된 파일 정보가 저장됩니다.)

* 여기서 "image"는 form애 있는 input의 name 을 의미합니다.

 

 

2. 다수의 파일 업로드( array() )

<form action="/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="images" multiple />
  <button type="submit">업로드</button>
</form>

form은 위와 동일 input의 name이 image => images로 변경

app.post("/upload-multiple", upload.array("images", 5), (req, res) => {
  res.json({ files: req.files });
});

images 라는 필드 이름으로 최대 5개의 파일을 업로드 가능

 

 

3. 다수의 필드로 파일 업로드 ( fields() )

<form action="/upload" method="POST" enctype="multipart/form-data">
  <input type="file" name="profile" />
  <input type="file" name="cover" />
  <button type="submit">업로드</button>
</form>
app.post(
  "/upload-fields",
  upload.fields([{ name: "profile", maxCount: 1 }, { name: "cover", maxCount: 5 }]),
  (req, res) => {
    res.json({ profile: req.files.profile, gallery: req.files.cover });
  }
);

profile 최대 업로드 : 1, cover 최대 업로드: 5

 

 

 

4. 파일 필터링 ( 이미지만 허용하는 예시)

<form action="/upload" method="POST" enctype="multipart/form-data">
    <input type="file" name="image" accept="image/*" required />
    <button type="submit">업로드</button>
  </form>
const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, "uploads/");
    },
    filename(req, file, cb) {
      const ext = path.extname(file.originalname);
      cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  fileFilter(req, file, cb) {
    if (!file.mimetype.startsWith("image/")) {
      return cb(new Error("이미지 파일만 업로드 가능합니다."), false);
    }
    cb(null, true);
  },
});

 

 

accept = "image/*" :  이미지 파일만 선택 가능하도록 제한

required : 파일을 선택하지 않으면 제출 불가능


 

Multer의 파일 처리과정

 

  1. 클라이언트가 form-data로 요청을 보냅니다(POST /upload)
  2. Multer가 요청을 가로채고 파일을 uploads/ 에 저장합니다 (uploads/ 는 예시)
  3. 파일 정보가 req.file 또는 req.files에 저장됩니다.
  4. 라우터에서 req.file을 이용해 응답하거나, db에 저장합니다.

'Node js' 카테고리의 다른 글

passport.js 정리하기  (0) 2025.02.14
mongoDB 에 대하여  (1) 2025.01.25
3. express 미들웨어 정리하기  (2) 2025.01.24
2. 노드의 특성  (0) 2025.01.07
1. Node.js 란?  (0) 2025.01.07

1. passport.js란?

  • passport.js는 Node.js에서 인증을 처리하기 위한 미들웨어로, 다양한 인증 전략을 제공합니다.
    인증을 처리하는 데 필요한 로직을 간단하게 구현할 수 있게 도와줍니다.

2. passport의 흐름

  1. passport.use로 전략 등록하기
    • 인증 전략의 개념 
      • 인증 전략은 사용자가 시스템에 접근하기 위한 인증방법을 정의하는 것 입니다.
        예를들어, 로컬 로그인, 카카오 로그인, 구글 로그인 등이 전략으로 제공됩니다.
    • passport.use 사용법
      • passport.use() 메서드는 인증 전략을 등록하는 함수입니다.
        등록된 전략은 이후 passport.authenticate()로 호출해 사용합니다.
    • 예시
      passport.use(
        new LocalStrategy(
          {
            usernameField: 'email', // 로그인 시 사용할 필드
            passwordField: 'password',
          },
          async (email, password, done) => {
            const user = await User.findOne({ where: { email } });
      	  //유져가 있고, password 와 user.password가 같다면
            if (user && bcrypt.compareSync(password, user.password)) {
              return done(null, user);
            } else {
              return done(null, false, { message: 'Invalid credentials' });
            }
          }
        )
      );

      인자값에 대해 정리를 해보자면,
      1. passport.use(strategy(option, callback));
       - strategy : 사용하고자 하는 인증 전략 (ex : LocalStrategy)
       - option : 전략에 필요한 옵션 설정 (ex : usernameField, passwordFiend, passReqToCallback)
       - callback : 인증을 처리하는 함수, 이 함수에서 done을 호출하여 인증결과를 반환합니다.

      2. callback(username, password, done);  , done(error, user|false, options?)
       - error : 인증 중에 발생한 에러 (에러가 발생하지않으면 null 또는 undefined
       - user : 인증 성공시 인증된 사용자 객체 (없으면 false)
       - options : 인증 실패 시 추가적인 정보 (ex {message : "Invalid credentials"})
  2. passport.authenticate로 인증 요청하기
    • 인증 요청의 과정
      • 사용자가 로그인 폼 형식에 맞춰 제출하면 passport.authenticate가 호출되고, 해당 전략에 맞는 인증 과정이 시작됩니다.
    • passport.authenticate 와 전략 선택
      • passport.authenticate("local")에서 "local"은 등록된 전략의 이름입니다.
      • local 전략이 사용되며 그에 맞는 인증 로직이 실행됩니다.
      • local 의 경우 passport-local 의 LocalStrategy를  kakao의 경우 passport-kakao 입니다.
        passport.authenticate("local") 은  passport.use( new LocalStrategy()) 을 실행
        passport.authenticate("kakao") 은  passport.use( new KakaoStrategy()) 을 실행

      • 저는 여기서 의문이 생겼습니다. authenticate에서 "local"은 어떻게 passport.use( new LocalStrategy())를 찾고 실행하는가 였습니다.
        passport.use("kakao", new KakaoStrategy(...)) , passport.use("local", new LocalStrategy (...)) 처럼
        "kakao"  "local 을 명시적으로 붙이지 않아도, 내부적으로 passport가 전략의 생성자를 보고 자동으로 매칭해주기 떄문이라고 합니다.
  3. serializeUser 로 세션에 사용자 정보 저장하기
    • 세션 관리의 필요성
      • 로그인한 사용자의 정보를 세션에 저장하여, 사용자가 로그인을 유지하고 인증된 상태를 지속적으로 사용할 수 있도록 합니다.
    • serializeUser의 역할과 사용법
      • serializeUser 는 로그인 한 사용자 정보를 세션에 저장할 떄 사용합니다. 
      • 보통 사용자 id만 저장하며, 이 정보는 deserializeUser 에서 사용합니다.
      • passport.serializeUser((user, done) => {
          done(null, user.id); // 사용자 정보를 세션에 저장
        });
        passport.use 에서의 callback이 가지고 있는 done과 흡사합니다.
        passport.use는 인증 시도 및 실패 처리가 이뤄지는 반면  serializeUser 에서는 인증이 성공한 후에 세션에 저장하는 과정이므로 실패 관련 정보가 없습니다.
        그렇기 때문에  user | false , option 이 없습니다.
  4. deserializeUser 를 이용해서 세션에서 사용자 정보 조회하기
    • 세션을 통한 인증 유지
      • 세션에 저장된 사용자 정보를 기반으로 인증된 상태를 유지합니다. 세션이 만료되거나 사용자가 로그아웃할때  까지 세션 정보를 참조합니다.
    • deserializeUser의 역할과 사용법
      • deserializeUser는 serializeUser를 통해 저장된 사용자 ID를 조회하여 실제 사용자 정보를 데이터베이스에서 가져옵니다. 로그인 후 매 요청시마다 호출되어 사용자 정보를 불러옵니다.
      • passport.deserializeUser((id, done) => {
            User.findOne({ where: { id } })
              .then((user) => done(null, user))
              .catch((err) => done(err));
          });


3. 결론

  • passport.js를 사용하면 전략을 등록하고 인증을 처리한 후, 세션을 이용해 인증된 사용자를 관리할 수 있습니다.
    • 세션을 통해 인증을 유지하며 serializeUser , deserializeUser를 사용하여 사용자정보를 효율적으로 관리합니다.
  • 전략 등록부터 인증까지의 전체 흐름
    • 전략 등록(passport.use)  -> 인증 요청(passport.authenticate) -> 세션 저장(serializeUser) -> 세션 조회 (deserializeUser) -> 인증유지

'Node js' 카테고리의 다른 글

파일 업로드 처리 (Multer)  (0) 2025.02.17
mongoDB 에 대하여  (1) 2025.01.25
3. express 미들웨어 정리하기  (2) 2025.01.24
2. 노드의 특성  (0) 2025.01.07
1. Node.js 란?  (0) 2025.01.07

1. mongoDB

mongoDB는 NoSQL 데이터베이스이고, 그  구조와 사용법이 JSON 형식과 유사하게 설계되어있습니다.

 

2.mongoDB와 JavaScript의 관계

 

1. JSON 과 BSON : mongoDB는 데이터를 JSON과 비슷한 BSON 형식으로 저장합니다.

자바스크립트 개발자에게는 친숙하게 느낄 수 있습니다.

 

2. JavaScript 기반 쿼리 : mongoDb의 셸에서 쿼리는 JavaScript 구문을 기반으로 작성합니다.

JavaScript 를 사용하는 것처럼 데이터를 조회하고, 조작할 수 있습니다.

 

3. Node.js와의 호환성 : mongoDB는 Node.js와 잘 어울리는 라이브러리(mongoose, mogodb)나 패키지를 제공하여 JavaScript로 쉽게 다룰 수 있습니다.

 

3. mongoDB의 NoSQL 에 대해

 

NoSQL의 특징

  • 관계형 데이터베이스(RDBMS)처럼 고정된 테이블 구조가 없습니다.
  • 데이터를 도큐먼트(document)로 저장하며, 각 도큐먼트는 키-값 쌍으로 구성됩니다.
  • 스키마가 유연하여 서로 다른 구조의 데이터를 한 걸렉션에 저장할 수 있습니다.
  • 수평확장(sharding)에 유리하며 대규모 데이터를 처리하기 적합합니다.

 

MySQL 과 NoSQL(몽고디비) 비교

MySQL NoSQL(몽고디비)
규칙에 맞는 데이터 입력
JOIN 지원
안정성, 일관성
용어(테이블, 로우, 칼럼)
자유로운 데이터 입력
JOIN 미지원 (aggregate로 비슷하게 가능)
확장성, 가용성
용어(컬렉션, 도큐먼트, 필드)

 

비정형 데이터에는 mongoDB가 사용하기 좋다

'Node js' 카테고리의 다른 글

파일 업로드 처리 (Multer)  (0) 2025.02.17
passport.js 정리하기  (0) 2025.02.14
3. express 미들웨어 정리하기  (2) 2025.01.24
2. 노드의 특성  (0) 2025.01.07
1. Node.js 란?  (0) 2025.01.07

express의 미들웨어는 요청과 응답 사이에 위치한 함수로, 주로 요청을 처리하거나. 응답을 수정하는 작업을 합니다.

각 미들웨어는 요청을 처리하고, next()를 호출하여 다음 미들웨어로 넘길지, 응답을 보낼지 결정할 수 있습니다.

 

  • 미들웨어는 app.use()로 설정합니다.
  • 요청이 들어오면 순차적으로 실행되며, 각각의 미들웨어가 요청을 수정하거나 처리합니다.

1. morgan("dev")

app.use(morgan("dev"));

기능

- morgan은 HTTP 요청에 대한 로깅을 처리하는 미들웨어입니다.

dev는 로깅 형식중 하나로, 개발환경에서 요청 URL, HTTP상태 코드, 응답시간을 콘솔에 출력합니다.

 

사용하는 이유

 - 요청과 상태를 쉽게 추적하기위해 사용되며, 요청이 서버에 들어올 때마다 콘솔에 로그가 찍혀 확인할 수 있습니다.

 morgan은 단순히 요청을 로그로 보여주며 next()를 호출하지 않아도 다음 미들웨어로 넘어갑니다.

 

 

2. express.static()

기능

 - 정적 파일 제공,

 - 이 미들웨어는 정적파일(HTML, CSS, 이미지, JavaScript 파일)을 제공하는 미들웨어입니다.

 - 서버에서 제공할 파일들이 특정 폴더에 있을 때, 해당 파일들을 URL 경로에 맞게 자동으로 제공해줍니다.

app.use(express.static(path.join(__dirname, "public")));

( __dirname : 현재 파일의 디렉토리를 의미)

path.join을 통해 디렉토리 안의 public 폴더를 지정하며, 폴더안의 파일을 클라이언트(브라우저)에게 제공할 수 있게 합니다.

 

3. express.json()

app.use(express.json());

 

기능

 - json 데이터를 파싱하는 미들웨어입니다.

클라이언트에서 JSON 형식으로 데이터를 전송하면, JavaScript 객체로 변환하여 req.body에 저장합니다.

 

요청 본문에 JSON 데이터가 있으면 파싱하고, next()를 호출하여 다음 미들웨어로 넘어갑니다.

(직접호출 하지 않아도 자동으로. 호출됨)

 

4. express.urlencoded({extended: boolean})

app.use(express.urlencoded({ extended: false }));

 

기능

 - URL 인코딩 된 폼 데이터를 파싱하는 미들웨어입니다.

false 옵션은 querystring 라이브러리를 사용하여 데이터를 처리합니다.  중첩된 객체나 복잡한 구조는 처리하지 않으며, 일반적인 폼 데이터는 파싱합니다.

(직접호출 하지 않아도 자동으로. 호출됨)

 

HTML 폼을 통해 전송된 데이터를 처리하기 위해 사용하며 사용자가 제출한 폼 데이터를 req.body에서 확인할 수 있습니다.

 


 

express 에서는 미들웨어가 위에서 아래로 순차적으로 실행됩니다. 각 미들웨어가 요청을 처리하거나, 요청을 수정하거나, 응답을 보내며, 그 후  next()가 호출되면 다음 미들웨어로 넘어갑니다. 
단, 정적 파일을 제공하거나 응답을 완료한 미들웨어는 더 이상 다음 미들웨어로 넘어가지 않습니다.

그렇기에 미들웨어의 순서는 매우 중요합니다.

 

'Node js' 카테고리의 다른 글

파일 업로드 처리 (Multer)  (0) 2025.02.17
passport.js 정리하기  (0) 2025.02.14
mongoDB 에 대하여  (1) 2025.01.25
2. 노드의 특성  (0) 2025.01.07
1. Node.js 란?  (0) 2025.01.07

문제 설명
과일 장수가 사과 상자를 포장하고 있습니다. 사과는 상태에 따라 1점부터 k점까지의 점수로 분류하며, k점이 최상품의 사과이고 1점이 최하품의 사과입니다. 사과 한 상자의 가격은 다음과 같이 결정됩니다.

한 상자에 사과를 m개씩 담아 포장합니다.
상자에 담긴 사과 중 가장 낮은 점수가 p (1 ≤ p ≤ k)점인 경우, 사과 한 상자의 가격은 p * m 입니다.
과일 장수가 가능한 많은 사과를 팔았을 때, 얻을 수 있는 최대 이익을 계산하고자 합니다.(사과는 상자 단위로만 판매하며, 남는 사과는 버립니다)

예를 들어, k = 3, m = 4, 사과 7개의 점수가 [1, 2, 3, 1, 2, 3, 1]이라면, 다음과 같이 [2, 3, 2, 3]으로 구성된 사과 상자 1개를 만들어 판매하여 최대 이익을 얻을 수 있습니다.

(최저 사과 점수) x (한 상자에 담긴 사과 개수) x (상자의 개수) = 2 x 4 x 1 = 8
사과의 최대 점수 k, 한 상자에 들어가는 사과의 수 m, 사과들의 점수 score가 주어졌을 때, 과일 장수가 얻을 수 있는 최대 이익을 return하는 solution 함수를 완성해주세요.

제한사항
3 ≤ k ≤ 9
3 ≤ m ≤ 10
7 ≤ score의 길이 ≤ 1,000,000
1 ≤ score[i] ≤ k
이익이 발생하지 않는 경우에는 0을 return 해주세요.

 


 

 

function solution(k, m, score) {
    var answer = 0;
    let arr = score.sort((a, b) => b - a); // 내림차순 정렬
    let box = [];
   
    arr.forEach((item,i) =>{
        box.push(arr[i])  
        
        // 박스에 사과가 m개 담겼다면 점수계산
        if(box.length === m){
            answer += Math.min(...box) * box.length;
            box=[];
        }
    })
    
    return answer;
}

중간에 발생한 문제점

처음에는 splice로 꺼내는 작업을 했더니 forEach가 멈춰버리는 일이 생겼습니다.
알아보니 forEach는 처음에 시작할때 배열의 길이와 요소를 고정된 상태로 순회한다는걸 몰랐습니다.

 

 


혹시 문제가 남은 사과까지 계산한다면..?

 

문제에서는 남은 사과는 계산하지 않습니다.

 

혹시라도 남은 사과를 계산을 했었다면

 

for문이나 while문으로짜고 splice로 잘라서 넣고 남은 arr.length가 m보다 작다면 arr의 요소를 더해서 계산하면 될 듯 싶습니다.

 

 

 

function solution(k, m, score) {
    let answer = 0;
    let arr = score.sort((a, b) => b - a);  

    // 상자 단위로 처리 (m개씩 꺼내서 상자 구성)
    while (arr.length >= m) {
        let box = arr.splice(0, m);  // m개씩 꺼내서 상자에 담기
        answer += Math.min(...box) * m;  // 최소 점수 * m (상자의 가격)
    }

    // 남은 사과가 있으면 마지막 상자에 대해 처리
    if (arr.length > 0) {
        let box = arr.splice(0, arr.length);  // 남은 사과들
        answer += Math.min(...box) * arr.length;  // 남은 사과들 가격 계산
    }

    return answer;
}

'개발공부 > 알고리즘' 카테고리의 다른 글

[Algorithm] 2차원 배열 최대합 구하기  (0) 2023.04.30
[Algorithm] 점수계산하기  (0) 2023.04.27
[Algorithm] 가위바위보  (0) 2023.04.27
[Algotithm] 큰 수 출력하기  (0) 2023.04.26
[Algorithm] 보이는 학생  (0) 2023.04.26

1. 이벤트기반

Node.js는이벤트를 기반으로 동작합니다.

이벤트가 발생했을 때 반응하도록 처리합니다.


2. 흐름

1. 콜백 함수 생성 : 이벤트가 발생했을 때 실행될 콜백 함수를 정의합니다.

2. 이벤트리스너 등록 : 특정 이벤트가 발생시 콜백함수가 실행되도록 이벤트 리스너를 등록합니다.

3. 이벤트 발생 : 이벤트가 발생하면 등록된 이벤트 리스너가 반응하며 지정된 콜백 함수를 실행합니다.

 

 


3. 블로킹과 논블로킹 I/O

Node.js는 기본적으로 비동기적이고 논 블로킹 방식으로 동작하며, 동기적이고 블로킹 방식으로도 동작할 수 있습니다.

  • 비동기(Asynchronous) : 다른 작업의 완료를 기다리지 않고 즉시 작업을 시작합니다.
  • 논블로킹(Non-blocking) : 작업을 실행할 때, 그 작업이 끝날때 까지 대기하지않고 계속해서 실행됩니다.
  • 동기(Synchronous) : 작업이 순차적으로 실행되며, 하나의 작업이 완료되어야 다음 작업을 시작합니다.
  • 블로킹(Blocking) : 작업을 실행할 때, 그 작업이 끝날 떄까지 다른 작업을 멈추거나 대기합니다.

Node.js의 비동기적, 논블로킹에 대해

Node.js는 기본적으로 비동기적이고 논블로킹 방식으로 설계되었습니다. 이것은 I/O 작업을 수행할 때 다른 작업들이 대기하지 않고 계속 실행될 수 있도록 합니다.

 

 

 

'Node js' 카테고리의 다른 글

파일 업로드 처리 (Multer)  (0) 2025.02.17
passport.js 정리하기  (0) 2025.02.14
mongoDB 에 대하여  (1) 2025.01.25
3. express 미들웨어 정리하기  (2) 2025.01.24
1. Node.js 란?  (0) 2025.01.07

+ Recent posts