문제 설명

문제 링크

[프로그래머스[Level2] 주식가격]
(https://school.programmers.co.kr/learn/courses/30/lessons/42584)

접근 방법

  1. 스택/큐
  2. 첫번째 원소를 기준으로 나머지 원소들보다 작은 경우 answer 에 푸시!
function solution(prices) {
    var answer = [];
    let len = prices.length;

    let idx = 0;

    while(len --) {

        let price = prices[idx];

        let cnt = 0;

        for(let i=idx+1;i<prices.length;++i){
            cnt++;
            if(price > prices[i]) break;
        }

        answer.push(cnt);

        idx++;
    }
    return answer;
}

DB연동이나 회사 내부에서 ip때문에 고생하여 자세하게 알고자 정리하고자합니다.

IP란?

  • 인터넷 프로토콜(Internet Protocol)의 약자로, 인터넷이 통하는 네트워크에서 어떤 정보를 수신하고 송신하는 통신에 대한 규약을 의미함

  • IP는 OSI의 Layer 3(Network Layer)와 Internet Protocol Suite의 Layer 3(Internet Layer)에 위치하는 프로토콜

정리

  • 쉽게 말해, 택배를 보낼 때, 받는 사람과 보내는 사람의 주소를 적어서 보낸다. 이때의 받는 사람이 주소를 확인하여 본인에게 온 택배가 맞는지의 작업이라고 생각하시면 됩니다.

공인IP주소

  • 공인IP란 실제 다른 컴퓨터와 통신할 때 쓰는 IP주소이며 IPv4에서는 '1.0.0.0' ~ '223.255.255.255' 까지가 여기에 해당됨.

  • 쉽게 말해, 고유한(유일한) IP 주소 ( 검색창에 내 ip 주소를 검색하면 나오는 IP)

그럼 어디에 쓰일까요?

  • 공인IP를 알고 있다고 해서 통신이 가능한 것은 아닙니다. 공인IP 주소를 사용하는 경우에는 특정 포트를 열어주어 외부에서 접근이 가능하게 하여 사용한답니다.

사설IP주소

  • 사설IP란 와이파이, 학교 공용 컴퓨터 등을 보면 192.168.XXX.XXX 처럼 아이피가 거의 사설 아이피인것을 확인 할 수 있습니다. 그 외에도 공유기를 사용하는 가정용 컴퓨터에서도 심심치 않게 볼 수 있음.

그럼 어디에 쓰일까요?

  • 공인IP 처럼 사설IP를 통신할 외부 컴퓨터에 알려줘도 접근이 불가능합니다.
    예를 들어) 개똥이의 친구 A는 같은 건물의 회사에 다니고 친구 B는 다른 건물의 회사에 다닙니다. 친구 A는 개똥이에게 사설IP를 알려주면 같은 사설망을 사용하고 있어 접속을 할 수 있지만, 친구 B는 접속할 수 없습니다.
    일상 생활로 비유를 들면, 집에 공유기 하나에 3개의 랜선이 연결되어.. 3개의 컴퓨터가 있다면 같은 사설망에 있어 192.168.XXX.XXX라는 주소를 알려주면 접근이 가능합니다. 하지만 옆집에 사는 친구가 접근하려면 공인 IP를 알려줘야 사용이 가능합니다.

localhost

  • localhost란 컴퓨터 네트워크에서 사용하는 루프백 주소로, 자신의 컴퓨터를 의미한다. 즉, 컴퓨터의 네트워크 기능을 시험하기 위해 '가상으로 인터넷망에 연결되어 있는 것처럼 할당하는 인터넷 주소'

  • IP주소는 127.0.0.1

외부에서 접근이 가능할까요?

  • 나만이 유일하게 사용할 수 있다고 생각하면 됩니다.
  • 같은 집에 사는 사람도 접속할 수 없음.

localhost(로컬호스트) 참고
IP란? 참고

'CS(Computer science) > 네트워크' 카테고리의 다른 글

[Computer Science] OSI 7 Layer  (0) 2024.03.05

 개발을 진행하면서 CRUD만 작성을 하다보니깐 에러를 처리하는 부분이 마음에 들지 않아서!!
특히, catch부분에 ctrl + c , ctrl + v 로 500에러만 나타내주기 보다는 각각의 상황에 맞춰 에러를 핸들링 해주고 싶었습니다.
 구글링을 통해서 best practice를 찾아보고 적용하면서 부족한 부분이 무엇인지에 대해서도 알 수 있었습니다.
next()의 동작과 app.js의 플로우와 app.use를 세밀하게 더 살펴볼 수 있었고 제 코드에 적용할 수 있었던 기회였습니다!

controlloer/user.controller.js

const userService = require('../services/user.service');
const HttpStatusCode = require('../config/httpStatusCode');

module.exports = {
    findAllUser: async (req, res) => {
        try {
            const user = await userService.read();
            if (user.length !== 0) return res.status(400).send({ statusCode: 400, message: "Bad Request" });
            return res.status(200).send({ data: user, statusCode: 200 });
        } catch (error) {
            res.status(500).send({ statusCode: 500, message: "Server Error" });
        }
    }
}

 

결과  

위의 controller의 에러 처리

구글링을 통해 Error Best Practice 찾아봐서 내 코드에 적용해보기

config/httpStatusCode.js

const HttpStatusCode = {
    OK: 200,
    BAD_REQUEST: 400,
    NOT_FOUND: 404,
    INTERNAL_SERVER: 500,
}

module.exports = HttpStatusCode;

error/error.js

const HttpStatusCode = require('../config/httpStatusCode');

class BaseError extends Error {

    constructor(name, httpCode, description, isOperational) {
        super(description);
        Object.setPrototypeOf(this, new.target.prototype);

        this.name = name;
        this.httpCode = httpCode;
        this.isOperational = isOperational;

        Error.captureStackTrace(this);
    }
}
//free to extend the BaseError
class APIError extends BaseError {
    constructor(name, httpCode = HttpStatusCode.INTERNAL_SERVER, isOperational = true, description = 'internal server error') {
        super(name, httpCode, isOperational, description);
    }
}

module.exports = { BaseError, APIError };

 

 

 

middlewares/errorHandler.js

function logError(err) {
    console.error(err)
}

function logErrorMiddleware(err, req, res, next) {
    logError(err)
    next(err)
}

function returnError(err, req, res, next) {
    res.status(err.statusCode || 500).send(err.message)
}

function isOperationalError(error) {
    if (error instanceof BaseError) {
        return error.isOperational
    }
    return false
}

module.exports = {
    logError,
    logErrorMiddleware,
    returnError,
    isOperationalError
}

자 그러면, 기존의 Controller에 적용을 하기 전에 app.js에서 middleware를 app.use()를 통해 등록해줍니다.

const express = require('express');
const userRouter = require('./routes/userRouter');
const logger = require('./logger/logger');
const { APIError } = require('./errors/error');
const { logError, returnError, logErrorMiddleware } = require('./middlewares/error1');


const app = express();

app.use(express.json());

app.use('/user', userRouter);
app.use(APIError);
app.use(logError);
app.use(logErrorMiddleware)
app.use(returnError);
app.use(logHandler);

app.listen(3030, () => {
    logger.info('server is running!');
});

Controller에 적용해보기

const userService = require('../services/user.service');
const HttpStatusCode = require('../config/httpStatusCode');
const { APIError } = require('../errors/error');

module.exports = {
    findAllUser: async (req, res, next) => {
        try {
            const user = await userService.read();
            if (user.length !== 0) throw new APIError("Bad Request", HttpStatusCode.BAD_REQUEST, true, "Bad Request");
            return res.status(200).send({ data: user, statusCode: 200 });
        } catch (error) {
            next(error);
        }
    }
}

 

결과 

예제 적용한 후의 결과
log

참고 사이트 : https://sematext.com/blog/node-js-error-handling/

상황 

MySQL1044 Error

"Access denied for user 'root'@'%' to database 'logintest'
Local에서 작업을 한 뒤에 AWS EC2로 인스턴스를 만들어 옮기는 작업 중에 API를 실행하는 중에 에러가 발생하였습니다.

이유

"DB에 접속 권한이 없다" 라는 이유 때문에 에러가 발생한 것입니다.

해결

grant all privileges on [데이터베이스명.테이블명] to [사용자@호스트] identified by '패스워드';

FLUSH PRIVILEGES;

를 통해서 접속 권한 설정 후 해결 

문제 설명

문제 링크

[프로그래머스[Level2] 마법의 엘리베이터]
(https://school.programmers.co.kr/learn/courses/30/lessons/148653)

접근 방법

  1. 그리디 알고리즘
  2. JS는 /(나누기) 사용시 소수점 아래의 값까지 다 나오기 때문에 floor를 적절하게 활용해주어야함.
  3. -1,1,-10,10,-100,100 등과 같이 버튼이 구성되어 있다. => 17 같은 경우는 20으로 0층을 내려가는 것이 더 빠름.
  4. 그래서 5보다 큰경우, 5인 경우, 5보다 작은 경우를 나눠서 구분지어 If문을 구성

    코드

function solution(storey) {
    var answer = 0;
    answer = makeResult(storey);
    return answer;
}

function makeResult(storey){
    let num = storey;
    let answer =0;
    while(num!=0){
        let tmp = num%10;
        if(tmp>5) {
            num+=(10-tmp);
            answer+=(10 - tmp);
        }
        else if(tmp == 5&&Math.floor(num/10)%10>=5) {
            num+=10-tmp
            answer+=10-tmp;
        }
        else {
            answer+=tmp;
        }
        num =Math.floor((num/10));
    }
    return answer;
}

문제 설명


문제 링크

프로그래머스[Level1] 신고 결과 받기

접근 방법

(key,value) 형식의 문제로 접근함.

  1. id_list.map을 통해 userList를 key,value로 만들어 줍니다.
    => userList 는 신고당한 사람들이 key로 value에는 신고를 한 사람들을 저장해줍니다.
  2. report.map 을 통해 report로 부터 받은 string을 split 하여 가공 가능한 자료로 바꾸어 줍니다.
    => user_id,report_id 로 신고한 사람과 신고 당한 사람을 각각 분류
  3. "한 유저를 여러번 신고할 수도 있지만, 동인한 유저에 대한 신고 횟수는 1회로 처리됩니다." 의 조건을 해결
    => userList[신고당한 사람]이 신고한 사람이랑 같지 않게 조건식을 만들어 줍니다.
  4. userList(신고 당한 사람)의 length 가 k의 값과 같거나 클 때 -> 해당 userList[key]에 해당하는 value는 object 형식이기 때문에 for문이나 map을 사용하여 id_list.indexOf()를 이용해 answer인덱스에 해당하는 값을 더해줍니다.

코드

function solution(id_list, report, k) {
    const answer = new Array(id_list.length).fill(0);
    let userList = [];
    id_list.map((value)=>{
        userList[value]= [];
    })
    report.map(value=>{
        const [user_id,report_id]=value.split(' ');
        if(!userList[report_id].includes(user_id))userList[report_id].push(user_id);
    })
    for(const key in userList){
        if(userList[key].length>=k){
            userList[key].map(v=>{
                answer[id_list.indexOf(v)]++;
            })
        }
    }
    return answer;
}

+ Recent posts