A. Ahahahahahahahaha

n / 2 이하로만 뽑으면 됐다. 0과 1밖에 안나오기 때문에 0이 n / 2 이상 개수가 있었으면 n / 2개만큼의 0을 출력해주면 되고 0이 n / 2 미만이었다면 1이 n / 2 + 1 개 있다는 것이므로 1을 n / 2 + 1 만큼 출력하면 되는 문제였다.

B. Big Vova

안그래도 영어라 읽기 힘든데 무려 한 문단이 문제와 관련없었다. 맨 앞에 오는 숫자는 반드시 a 배열중에서 가장 큰 숫자여야 했다. GCD(b1)에서 그 수 자체가 c1이 되는데 사전순으로 가장 크게 될려면 가장 큰 숫자가 왔어야 하기 때문이다.

처음에 풀면서 n^2에 gcd까지 구하는 풀이가 생각났는데 n제한이 10^5인줄 알고 이 방법을 쓰지 않고 다른 걸 찾다가 시간을 많이 썼다. 10^3인걸 잘 봤으면 이렇게 풀고 빨리 끝냈을 수 있을 것 같다.

C. Chocolate Bunny

크기가 다른 두 숫자를 순서 바꿔서 한번 씩 mod연산 하면 둘 중 작은 값이 두 숫자 중 작은 값이다. 이를 이용해서 풀 수 있었다.

const input = require('fs').readFileSync('/dev/stdin').toString().split('\n');
// const input = require('fs').readFileSync('./input.txt').toString().split('\n');

let a = [];
let b = [];
let z;
const bs = (left, right) => {
  const mid = Math.floor((left + right) / 2); 
  if(left > right) {
    return 0;
  }
  let tval = a[mid]; 
  if(tval > z) {
    return bs(left, mid-1);
  } else if(tval < z){
    return bs(mid+1, right);
  } else {
    return 1;
  }
}

for(let i=0;i<Number(input[0]);++i) {
  a = input[i*4+2].split(' ').map(x => parseInt(x));
  b = input[i*4+4].split(' ').map(x => parseInt(x));
  a.sort();
  for(const v of b) {
    z = v;
    console.log(bs(0, Number(input[i*4+1]-1)));
  }
}
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int arr[1000010];
int cmp;
int bs(int left, int right) {
  int mid = (left + right) / 2;
  if(left > right) {
    return 0;
  }
  int tval = arr[mid];
  if(tval > cmp) {
    return bs(left, mid-1);
  } else if(tval < cmp) {
    return bs(mid+1, right);
  } else {
    return 1;
  }
}

int main(void) {
  int t;
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> t;
  while(t--) {
    int a, b;
    cin >> a;
    for(int i=0;i<a;++i) {
      cin >> arr[i];
    }
    sort(arr,arr+a);
    cin >> b;
    for(int i=0;i<b;++i) {
      cin >> cmp;
      cout << bs(0,a-1) << '\n';
    }
  }
}

js로 똑같이 구현해도 시간초과가 났다. 질의응답에서 데이터 입력이 많아 입력속도가 중요하다고 하는데 javascript로 어떻게 올려야 할지 모르겠다.

'알고리즘' 카테고리의 다른 글

백준 2210 숫자판 점프 c++  (0) 2020.09.15
백준 2933 미네랄 C++ 풀이  (0) 2020.09.12
[javascript] b1072.js  (0) 2020.09.03
[프로그래머스] 정수삼각형 c++ 재귀로 풀기  (0) 2020.07.04
[DC] 백준 1992 쿼드트리  (0) 2018.04.29

개요

보통 자주 사용하는 body-parser나 morgan등 예제 코드를 통해

app.use( ... ) 

...에 적용할 미들웨어를 넣으면 이렇게 body-parser나 morgan 같은 라이브러리가 적용되는 마법같은 것으로 알고 있었다. 이번에 공부를 해서 마법이 아니라 기술로 만들어 보고자 한다.
(모르면 마법, 알면 기술 - 이고잉)

미들웨어의 매우 간단한 의미

만약 만든 서버에서 접속을 하면 반드시 A기능과 B기능을 실행해야 한다고 가정하자.

미들웨어를 사용하지 않으면

app.get('/', (req, res) => {
  console.log("A 기능 실행");
  console.log("B 기능 실행");
  console.log("다음 동작");
})

app.get('/hello', (req, res) => {
  console.log("A 기능 실행");
  console.log("B 기능 실행");
  console.log("다음 동작 hello");
})

...

모든 라우터마다 위와 같이 A기능과 B기능을 실행하는 코드를 위에 적어줘야 한다.

미들웨어를 사용하면

app.use((req, res, next) => {
  console.log("A 기능 실행");
  next();
})

app.use((req, res, next) => {
  console.log("B 기능 실행");
  next();
})

app.get('/', (req, res) => {
  console.log("다음 동작");
})

app.get('/hello', (req, res) => {
  console.log("다음 동작 hello");
})

위와 같이 app.use를 통해 app.get ... 라우터 실행 전에 수행해야할 동작을 미리 지정해 두어 훨씬 깔끔하게 코드 작성이 가능해진다.

좀 더 구체적인 미들웨어

참고 : https://expressjs.com/en/guide/using-middleware.html

미들웨어는 총 5가지 타입으로 나뉜다.

'웹 프로그래밍 > node.js' 카테고리의 다른 글

Express-session 동작 및 활용  (0) 2020.09.15
Express 구조  (0) 2020.08.31
const input = require('fs').readFileSync('/dev/stdin').toString().split('\n');
// const input = require('fs').readFileSync('./input.txt').toString().split('\n');

const bs = (left, right, z) => {
  const mid = Math.floor((left + right) / 2); 
  if(left >= right) {
    return mid;
  }
  let tval = Math.floor(((Y + mid) / (X + mid))* 100);
  if(tval > z) {
    return bs(left, mid, z);
  } else {
    return bs(mid+1, right, z);
  }
}

let a = input[0].split(' ');
const X = Number(a[0]);
const Y = Number(a[1]);
const Z = Math.floor((100 * Y / X));
let result = 0;
result = bs(0, 100000000001, Z);
if(result == 100000000001) {
  result = -1;
}
console.log(result);

풀이

Lower bound 알고리즘으로 풀 수 있었다.이분 탐색이랑 유사하지만 조건 만족할 때에는 mid를 증가시키지 말고 만족 안할 때 mid를 증가시켜 탈출 조건에서 조건 만족시켰던 것 중 가장 먼저 나오는 답을 return 한다.

문제였던 것

// 입력 X = 50, Y = 29 일때
console.log(100 * Y / X);
console.log(Y / X * 100)

//output
58
57.999999999...

위와 같이 차이가 있었다.

'알고리즘' 카테고리의 다른 글

백준 2933 미네랄 C++ 풀이  (0) 2020.09.12
백준 2776 CPP, js  (0) 2020.09.04
[프로그래머스] 정수삼각형 c++ 재귀로 풀기  (0) 2020.07.04
[DC] 백준 1992 쿼드트리  (0) 2018.04.29
[DC] 백준 1074 Z  (0) 2018.04.29

B. Power Sequence

https://codeforces.com/contest/1397/problem/B

처음에 너무 난해했다. 모든 경우를 다 하지 않고 어떻게 구할 수 있는지 고민을 많이 했다. 고민을 하던 중에 c가 2만 되더라도 n이 10^5는 고사하고 n이 30만 되도 10^9를 넘어 사실상 c가 1일때만 10^5만큼 해봐야하고 그 이상일 땐 정말 적은 양만 탐색해보면 되는 문제였다.

C. Multiples of Length

https://codeforces.com/contest/1397/problem/C

어떻게 풀어야 할지 감이 안왔다. 정렬 후 세그먼트 트리로 풀 수 있을까 생각해봤는데 그렇게 하더라도 경우의 수가 너무 많았다. 도저히 생각이 안나서 다른사람 코드를 봤는데 너무 간단해서 허무했다. 1~n-1까지 각 값에 n-1을 곱해 더하면 arr[i] * (n-1) + arr[i] 하면 1~n-1까지의 값이 모두 arr[i] * n 이 되고 n~n까지는 구간의 길이가 1이라 무엇이든 곱해도 되니 arr[last] * (n-1) + arr[last] 로 arr[last] * n 을 만든다. 마지막으로 1~n까지에 -1 * arr[i] * n으로 더해주면 모두 0을 만들 수 있었다. 코드포스식 쉬운 문제들은 이런식의 접근을 해야겠다는 생각을 했다.

D. Stoned Game

https://codeforces.com/contest/1397/problem/D

그리디인건 알겠는데 또 감이 안왔다. 백준에 많은 돌 게임 문제가 있었는데 이건 좀 유형이 다르고 DP로 풀 수 있는 문제였다. 다른 사람의 풀이를 보고 감을 잡고 풀 수 있었다. 먼저 가장 간단하게 생각하면 돌 개수 총 합이 홀수개면 T가 이기고 짝수면 HL이 이긴다. 여기서 변수는 T나 HL이 뽑은 게 마지막 남은 pile이어서 돌이 남았더라도 뽑을 수 없게 되면 돌의 개수와 상관없이 그 돌을 점유하고 있던 플레이어가 이긴다. 이러한 상황은 T만 만들 수 있다. 이 상황이 나오려면 가장 큰 pile이 나머지 pile의 모든 합보다 크면 T가 그 pile만 계속 점유하면 이기기 때문에 이 경우를 예외처리하고 이외에는 짝수홀수 경우로 답을 구했다.

폴더 구조

node.js의 웹 프레임워크인 Express를 Express답게 쓰기 위해 조사했다. Express Reference에서는 Express generator를 사용해서 빠르게 앱 스켈레톤을 구성할 수 있게 해준다. 위의 사진은 Express generator를 통해 생성한 스켈레톤 앱의 구조이다.

npm install -g express-generator

명령어를 통해 설치한 후

express —view=pug myapp (pug는 템플릿 엔진. ejs를 사용할 수도 있다)

를 통해 스켈레톤 앱을 생성한다.

빌드

빌드는 npm start 명령어를 통해 빌드한다.
package.json파일의 "script"키 값으로 "start" 명령시 빌드 명령어가 앱 생성과정에서 함께 들어가있다.

"scripts": {
  "start": "node ./bin/www"
},

bin폴더

// bin/www
const app = require('../app');
const http = require('http');
const port = 3000;
app.set('port', port);

const server = http.createServer(app);
server.listen(port);

www파일을 요약하면 위와 같다. 서버가 실행되는 코드가 들어있다.

app.js

const express = require('express');
const app = express();
const path = require('path');

const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');

app.set('view engine', 'pug');
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use(express.static(path.join(__dirname, 'public')));

module.exports = app;

app.js파일을 요약하면 위와 같다. 미들웨어들을 연결하고 exports해서 www에서 실행시킬 수 있도록 한다.

routes폴더

// index.js
const express = require('express');
const router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

routes폴더 내에 있는 파일들을 요약하면 위와 같다. 해당하는 URL이 들어올 때 처리할 동작을 기술할 수 있다. res.render('index', ... ) 에서 index는 views폴더 내의 index.pug파일을 의미한다.

views폴더

//index.pug
doctype html
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    h1= title
    p Welcome to #{title}

views폴더 내에 있는 파일을 요약하면 위와 같다. 보여질 html파일을 기술한다. 이번엔 템플릿 엔진으로 pug를 사용해서 pug파일이 있고 ejs를 사용할 수도 있다.

public폴더

public폴더에는 정적인 파일을 두고 가져다 쓸 수 있는 폴더이다. app.js 파일에 app.use(express.static(path.join(__dirname, 'public')));
코드를 통해서 정적인 파일을 가져다 쓸 수 있도록 해두어서 사용 가능하다.

'웹 프로그래밍 > node.js' 카테고리의 다른 글

Express-session 동작 및 활용  (0) 2020.09.15
Express 미들웨어 매우 간단한 개념  (0) 2020.09.03

1월 ~ 3월

회사에 합격을 해서 입사 전까지 아무 걱정없이 신나게 놀았습니다. 코로나 때문에 좀 아쉬웠지만 덕분에 집에만 있어야 해서 책 2~3권 더 읽을 수 있었던 것 같습니다.

작년 8월까지만 해도 취업할 생각은 전혀 없었고 학부연구생 생활을 재밌게 하며 대학원 진학을 준비하고 있었는데 "부자 아빠 가난한 아빠" 란 책을 읽고 그냥 돈을 빨리 모으는게 훨씬 좋겠다는 생각을 하고 취업을 했습니다.

취업을 해서 돈을 벌면 돈을 잘 굴려야 하니까 미리 공부해 두기 위해 주식과 돈 관련된 책을 위주로 많이 읽었습니다. 15권정도 읽은 것 같은데 14권째 책을 읽은 것의 결론은 월 100만원 정도 쓰고 10년 정도 열심히 모으고 투자를 하면 그 이후에는 일을 안하고 하고싶은 일하며 살 수 있겠다 였습니다.

 

15권중에 14권째로 그 결론을 냈는데 15번째 책으로 생각이 180도 바뀌었습니다. "부의 추월차선"이라는 책이었는데 머릿말부터 뒷통수를 한 대 맞은 느낌이 들었습니다.

부자가 되기 위해 일, 저축, 무조건적인 절약, 8%의 주식 수익률 따위에 매몰된 월급쟁이. 대학에 가고, 좋은 성적을 받고, 졸업하고, 좋은 직업을 갖고, 수익의 10%를 주식에 투자하고, 최대한 퇴직연금에 투자하고, 신용카드를 없애고, 쿠폰을 모으고... 그러면 당신이 65세쯤 되었을 때 언젠가 부자가 될 것이다.

14권의 책을 읽으면서 열심히 모으고 투자해서 부자가 되면 되겠다 생각을 했는데 65세. 엄청 잘해서 20년 앞당긴다고 해도 45세. 이 때 부자가 된다면 무슨 의미가 있을까 다시 생각해 보게 되었습니다. 평생에 가장 팔팔한 나이에 아끼고 참고 살아야 하는게 맞는건가 싶었습니다.

 

4월 ~ 부스트캠프 알기 전

4월 ~ 7월 중순까지 회사에 다녔습니다. 회사에서 직무를 정할 때 사업부, 팀을 1지망, 2지망 등으로 선택해서 배치받았는데 정말 운 좋게도 1지망으로 썼던 사업부와 팀에 배정받았습니다. 그리고 원래라면 신입사원 교육을 입사후부터 6개월간 받게 되는데 이번에는 코로나 영향으로 집합 교육이 제한되어서 2개월 간 현업에 배치 되었다가 이후에 교육을 진행을 했습니다.

현업에 있는동안 일을 배우고 하면서 신입사원이기 때문에 대단한 일을 배우고 한 것이 아니라 업무를 100% 이해하고 판단한 것은 아니지만 여러가지 생각을 했고, 최대한 빨리 이직을 해야겠다는 생각을 했습니다.

회사에서 하게 된 일은 입사 지원서를 낼 때부터 하게 될 것이라 예상했던 일을 하게 됐습니다. 하드웨어를 이해하고 잘 동작할 수 있도록 C언어로 펌웨어를 개발하는 일이었습니다. 전자공학을 전공하면서 하드웨어를 이해하는 것을 정말 재미있게 공부했고, 소프트웨어쪽을 연계전공하며 코딩하는 것도 좋아했는데 둘 다 할 수 있는 정말 좋은 기회이자 하고싶은 일을 하며 살 수 있는 좋은 직장에 오게 됐다고 생각했습니다. 배치된 파트도 굉장히 최신 기술을 다루는 쪽이라 정말 재밌을 것 같았습니다. 추가적으로 정말 좋고 능력있는 직장동료들. 자유로운 출퇴근시간, 대기업 복지, 느껴지는 긍정적인 사회적 시선들 정말 만족했습니다.

그럼에도 이직을 생각하고 퇴직을 하게 된 계기는 회사를 다니면서, 또 10년 뒤를 봤을 때 아쉬울 것 없는 좋은 인생을 산 것일까 생각해봤을 때 "아니다" 라고 생각했습니다.

공부하게 되는 기술이 너무 최신기술에 재직하는 기업에 맞춰진 것을 개발하다 보니 회사 밖에선 크게 쓸모 없는 기술이 된다는 생각이 들었습니다. 하게 될 일이 흥미는 있지만 잡고 계속하는게 성공하는 것과 점점 멀어진다고 생각했습니다.

또 "부의 추월차선"의 영향으로 그 최신기술을 열심히 공부할 역량으로 좀 더 범용적이고 강력한 기술(지금은 웹 프론트 엔드라 생각합니다) 이나 창업 아이템에 역량을 쏟는다면 훨씬 더 큰 성공을 얻을 수 있는데 허튼 곳에 역량을 쏟게 되는 것이 아닌지 의구심이 들었습니다.

또 하드웨어가 좋냐 소프트웨어가 좋냐 둘 중 하나를 고르라고 한다면 전 소프트웨어쪽입니다. 맡게된 일은 C언어로만 프로그램을 만드는데 딱히 소프트웨어적인 일을 한다는 생각이 들지 않았습니다. 이건 10년이 아니라 1년만 지나더라도 그동안 공부했던 소프트웨어적 지식이 다 사라질 것 같았습니다.

이런 저런 고민하면서 1년 내에 규모가 작더라도, 연봉이 낮더라도 IT기업으로 이직해야겠다는 목표를 가지고 퇴근 후 따로 SW공부를 했습니다.

부스트캠프 알게된 후 ~ 부스트캠프 챌린지 수료

사실 위와 같은 고민을 하면서 네이버나 카카오 같은 IT기업에 가고 싶었지만 현실적으로 불가능하다고 생각했습니다. 취업준비를 하면서 가장 중요하다고 생각했던 건 직무 관련 경험인데, SW쪽 경험은 크게 없었기 때문이었습니다. 준비를 해서 비교적 입사가 쉽고 도전적인 일을 많이 할 수 있는 곳을 찾아 이직해야겠다는 생각을 했습니다.

그러던 중 친구의 추천으로 부스트캠프를 알게 되었습니다. 부스트캠프 교육 프로그램 설명과 후기를 읽어봤는데 정말 하고 싶었습니다. 가장 마음에 들었던 것은 멤버십의 그룹 프로젝트였습니다. 신입 지원자 입장에서 직무관련경험을 쌓기 정말 좋은 기회로 보였습니다. 그리고 이 경험을 쌓는다면 네이버와 카카오같은 IT기업에 입사하기 위한 직무관련 경험으로 충분히 경쟁력있는 경험으로 쓸 수 있을 것 같다고 생각했습니다.

부스트캠프 지원을 위해서는 자기소개서와 프로젝트 경험을 제출해야 했는데 낼 만한 프로젝트 경험이 없어서 이 부분은 공백으로 냈고 자기소개서를 공을 들여 썼습니다. 문항이 4개정도에 1000자씩이 었던 것 같은데 네 문항 모두 1000자 가까이 취준생이 된 것처럼 열심히 작성해서 냈습니다.

제출을 하고 두 번의 코딩테스트 결과보다 서류합격을 기다리는게 훨씬 떨렸던 것 같습니다. 프로젝트 경험 뭐라도 긁어서 냈으면 하는 아쉬움이 정말 컸고 경력사항에 재직중이라는 걸 기재했는데 재직중인 사람을 굳이 뽑을 필요가 있을까 하고 떨어뜨리진 않을까 불안감도 컸습니다. 다행히 서류 합격을 하고 두 번의 코딩테스트도 무사히 통과해서 챌린지 과정에 입과하게 되었습니다. 그리고 정말 감사하게도 멤버십에 합격하게 되었습니다.

생각들

최종 입과 발표가 나고 바로 퇴직절차를 밟았습니다. 회사 입사하고 한 건 교육받은 것 밖에 없어 바로 퇴사하게 되면 회사와 팀원에게 입히는 피해가 큰데도 다들 좋게 말씀해주셔서 정말 감사하고 죄송했습니다.

잘 다니던 회사를 그만두고 하고싶은 걸 한다고 부모님 속을 많이 썩이게 된 것 같은데 그래도 응원해 주셔서 감사합니다.

하게된 선택에 개인적으로는 아무 후회가 없고 실패하더라도 충분히 감당할 수 있지만 이래저래 주위 사람들에게 걱정거리가 된 것 같아 어깨가 무거운 것 같습니다. 그래도 그 중압감에 교육에 더 진지하고 절실하게 하고 있습니다.

회사를 포기하고 하게된 선택에서 최고의 시나리오는 챌린지 합격 → 멤버십 합격 → 네카라등의 좋은 IT기업 or 엄청난 성장을 할 수 있을 것 같은 스타트업 입사 인데 멤버십 합격까지 다행히 이뤄내서 다행입니다. 가장 필요하다고 생각했던 그룹 프로젝트까지 할 수 있는 자격이 생겼으니 이후 과정이 잘 안되더라도 했던 선택에 후회가 있을 것 같진 않습니다.

다음 주부터 멤버십 시작인데 하게된 선택이 무겁고, 노력에 따라 얻을 수 있는게 천차만별로 달라져 보이는 이 기회를 잘 활용할 수 있도록 열심히 해야겠습니다.

'이야기' 카테고리의 다른 글

Front-End 개발자가 되고싶은 이유  (0) 2020.08.14

해커와 화가

해커와 화가를 읽다.

책을 하나 읽게 되었습니다. 해커와 화가라는 책입니다. 2003년에 집필된 꽤 오래된 책 입니다. 15개의 저자의 에세이를 책으로 만들어 집필한 것으로 알고 있는데, 가장 영향을 많이 받은 챕터는 "02 / 해커와 화가 : 해커는 화가, 소설과 건축가와 같은 예술 창조자다" 와 "05 / 또 하나의 길 : 웹 기반 소프트웨어가 준 두번째 기회" 였습니다.

02 해커와 화가 - 재미있어 보였다.

챕터 2 해커와 화가에서 저자가 말하는 것은 프로그래머도 결국 예술가와 같다는 것이었습니다. 예술가와 과학자는 차이점이 있습니다. 과학자는 무언가 만들기전에 철저하게 과정을 설계하고 준비하고 시작합니다. 반면에 예술가가 어떤 그림을 그릴 때에는 완벽한 무언가를 설계하고 시작하기 보다는 우선 그림 그리기를 시작하고 봅니다. 그리고 마음에 들지 않는 부분은 조금씩 지우고 새로 그리고 이렇게 다듬고 발전시키며 예술을 완성시킵니다.

프로그래머가 완벽한 설계를 하고 그에 따라 프로그래밍을 하는 것이 맞는지, 아니면 예술가처럼 일단 코딩을 시작하고 고쳐가는게 맞는지. 옳다 그르다는 잘 모르겠습니다. 하지만 분명한 건, 후자(예술가처럼)로 코딩을 하면 매우 재밌다고 생각합니다. 내가 생각한대로 짰는데 그대로 동작하면 그대로 재밌고, 그렇게 동작 안하면 왜 동작안하는지 찾고, 이해하고, 디버깅에 성공해서 원하는 동작대로 만들면 성취감이 있습니다.

경우에 따라 다르겠지만 매우 신뢰성 높고, 엄청 많은 사람이 협력해야 하는 프로그램을 작성해야 할 때, 예술가처럼 프로그래밍하면 문제가 있을 순 있어 보입니다. 이런 상황에서는 완벽한 설계를 하고 코딩하는게 좋아 보입니다. 반대로 스타트업이나 빠르게 무언가를 만들어내야하는 상황에서는, 시간이 생명인 스타트업에서 완벽한 설계를 하다가 망해버리고 말 겁니다. 여기선 예술가처럼 프로그래밍 해야겠죠.

책을 읽고 전 예술가적인 프로그래머를 지향하기로 했습니다. 이유는 무엇보다 재미있기 때문입니다. 예술가적인 프로그래머가 되려면 Front-End가 적합하다고 생각합니다. Back-End는 빠른 Develop보다 훨씬 중요한 게 신뢰성입니다. 이 분야에선 완벽한 설계가 더 중요할 것 같습니다. 반면에 Front-End는 내가 개발한 것을 확인하기가 비교적 쉽고 문제가 잘 보입니다. 그래서 예술가처럼 조금씩 다듬어 더 좋은 프로그램을 만들어 내는 방식이 가능합니다.

05 또 하나의 길 - 비전 있어 보였다.

다시 한번 강조하고 싶은데, 이 책은 2003년에 집필되었습니다. 저자는 이 챕터에서 웹 기반 소프트웨어의 비전을 예측했습니다. 웹 기반 소프트웨어는 웹 브라우저를 실행할 수 있는 Device이기만 하면 어디서든 구동 가능하다는 장점이 있습니다. 한번 Develop하면 PC, 스마트폰(Android, IOS)등등 한번에 배포할 수 있습니다. 이런 엄청난 강력함이 있지만 겉으로 보기에는 매우 큰 제약이 있어 보입니다. Desktop App(Excel, Word 등등) 같은 무거워보이는 프로그램은 웹 기반에서 돌린다는 건 예전에는 상상도 못할 일이었습니다.

지금은 구글에서 무려 무료로 스프레드시트나 문서작성도구를 웹 기반으로 작성할 수 있도록 합니다. 이 도구들은 심지어 한 문서에 여러사람이 접속해서 문서를 동시에 수정하는 것도 가능하게 해줍니다. 웹 기반의 프로그램이기 때문에 비교적 쉽게 구현할 수 있었다고 생각합니다.

앞으로 10년 뒤에 세상은 또 어떻게 바뀌어 있을까요. 저는 네이티브로 남아있을 수 밖에 없는 몇 안되는 앱을 제외하고는 모두 웹 기반 앱으로 이주하거나 새로운 웹 앱이 생겨날 것 같습니다. 웹 기반 앱의 가장 큰 단점은 성능인데, 크롬브라우저의 성능이 계속 향상되면 일반 PC만큼 성능을 낼 수 있도록 빠르게 동작할 것이라 예상합니다. 그러면 굳이 네이티브로 만들 필요 없이 웹 기반으로 개발하는 것이 당연하게 될 것 같습니다.

이런 웹 기반 세상에서 가장 필요한 기술은 무엇 일까요? 저는 Front-End 개발이라고 생각합니다. 단순히 사용자의 눈에 보이는 것만 디자인 하는 것을 넘어, 크롬 브라우저 기반으로 예를들어 Excel작업을 할 수 있도록 복잡한 기능들을 구현할 수 있는 실력있는 개발자가 많이 필요해 질 것입니다. 그리고 이런 역할을 할 수 있는 사람은 Front-End 개발자라고 생각합니다. Desktop App 개발자들이 각 타겟 OS와 PC 성능에 맞추어 개발하듯이 웹 기반 앱 개발자들은 구글 크롬 브라우저의 성능을 최대한으로 사용해 빠르게 동작하는 앱을 만들어 내야 합니다. 실력있는 웹 Front-End 개발자는 지금보다도 훨씬 많이 필요할 것입니다.

성공을 위한 가장 강력한 도구

내가 어떤 좋은 아이디어가 있는데 이를 서비스하기 위해 가장 좋은 도구중 하나는 웹 앱 개발하는 능력이라고 생각합니다. 멋진 아이디어가 생각났을 때 빠르게 개발해서 시험해보고, 또 다른 아이디어를 시험해보고 반복한다면 어느 순간 세상을 바꾸는 멋진 앱을 만들어 낼 수 있다고 생각합니다. 가장 중요한 건 우선 서비스가 가능한 무언가를 만들 수 있는 능력이 있어야 한다는 것이고, 그 다음으로는 빠르게 개발할 수 있어야 한다는 게 중요한 것 같습니다. Front-End 기반 웹 앱 개발능력은 이 두 가지를 모두 충족하는 강력한 도구라고 생각합니다. 열심히 공부해서 실력있는 개발자가 되어 세상을 바꾸는 멋진 웹 앱을 개발하고 싶습니다.

'이야기' 카테고리의 다른 글

2020년 8월까지 회고  (0) 2020.08.27

 

#include <string>
#include <vector>

using namespace std;

int dp[510][510];
vector<vector<int> > *arr;

void init() {
    for(int i=0;i<510;++i) {
        for(int j=0;j<510;++j) {
            dp[i][j] = 0;
        }
    }
}

int dfs(int depth, int idx) {
    if(depth == arr->size()) {
        return 0;
    }    
    if(dp[depth][idx] != 0) {
        return dp[depth][idx];
    }
    
    dp[depth][idx] = max((*arr)[depth][idx] + dfs(depth + 1, idx), 
    			(*arr)[depth][idx] + dfs(depth + 1, idx + 1));    
 
   
    return dp[depth][idx];
}

int solution(vector<vector<int>> triangle) {
    arr = &triangle;
    init();
    int answer = 0;
    answer = dfs(0,0);
    return answer;
}

'알고리즘' 카테고리의 다른 글

백준 2776 CPP, js  (0) 2020.09.04
[javascript] b1072.js  (0) 2020.09.03
[DC] 백준 1992 쿼드트리  (0) 2018.04.29
[DC] 백준 1074 Z  (0) 2018.04.29
[DC] 백준 2261 가장 가까운 두 점  (0) 2018.04.29

Javascript Function

한 번 정의하면 몇번이든 실행할 수 있고 호출할 수있는 자바스크립트 코드 블럭

        function printprops(o) {
            for(var p in o) {
                console.log(p + " : " + o[p] + "\n");
            }
        }
        var arr = [1,2,3,4,5];
        printprops(arr);

Output :

함수 이름은 옵션

함수 정의 표현식에서 함수 이름은 옵션이다.
한 번 사용되고 마는 함수에서 특히 유용.

        var ten = (function(x) {return 10});
        console.log(ten);
        console.log(ten(100));

Output :

함수 선언문은 hoisted 된다.

어디에 함수 선언문이 있든 맨 위로 끌어올려(hoisted) 진다.
하지만 표현식으로 정의된 함수는 변수에 할당되기 전 까지는 참조할 수 없다.

리턴 값이 없는 함수를 procedure라고도 함.

중첩 함수

        function hypotenuse(a, b) {
            function square(x) {return x * x};
            return Math.sqrt(square(a). square(b));
        }

문장으로 선언되는 함수는

함수 내에 함수 중첩가능
but 반복문 내부, 조건문, try / catch / finally 또는 with문 안에 들어갈 수 없다.

표현식은

코드 어디든 위치 가능

함수 호출

  1. 일반적인 함수형태
  2. 메서드 형태
  3. 생성자
  4. call() 과 apply() 메서드를 통한 간접 호출

일반적인 함수 형태

호출 표현식

  • 함수 객체로 평가되는 함수 표현식
  • 여는 괄호
  • 콤마로 구분된 0개 이상의 전달인자 표현식
  • 닫는 괄호

함수 내의 this

  • 일반적인 함수 형태로 사용하려 했으면 this 쓰지 않음
  • strict mode 가 적용되었는지 판단 여부를 위해 사용 가능
    • 엄격모드 X -> global 객체
    • 엄격모드 O -> undefined
var strict = (function() {return !this;}());

메서드 호출

대부분 . 을 사용
[] 도 사용가능

        var calculator = {
            operand1: 1,
            operand2: 1,
            add: function() {
                this.result = this.operand1 + this.operand2;
            }
        }
        calculator.add();
        console.log(calculator.result);
        calculator["add"]();
        console.log(calculator.result);

Output :

메서드 사용 -> 해당 객체에 무언가를 한다는 사실을 나타내는 세련된 방법.

+a : this 키워드의 scope

        var o = {
            m: function() {
                var self = this;
                console.log(this === o); // true
                f();
                function f() {
                    console.log(this === o); // false
                    console.log(self === o);
                }
            }
        }
        o["m"]();

Output :

생성자 호출

new keyword -> 생성자 호출

인자가 없으면 두 문장은 완전히 같은 것.

        var o = new Object();
        var o = new Object;

생성자 함수는 보통 return 사용하지 않음.
함수의 마지막에서 객체를 반환, 혹은 return만 명시 되어있으면 거기서 객체 반환
기본 자료형 값(primitive value)을 반환하면 무시되고 새로생성된 객체가 호출 표현식 값.

간접 호출

call() -> 자신에게 주어진 전달인자를 호출할 함수의 전달인자로 사용
apply() -> 값 배열을 전달인자로 사용.

두 메서드 모두 호출 때 this 값을 명시적으로 지정 가능. -> 어떤 함수든지 특정 객체의 메서드로 호출할 수 있다는 의미

함수 전달인자와 매개변수

Javascript는 함수 매개변수타입, 전달인자 개수, 전달하는 인자의 타입 모두 검사하지 않음.
이를 프로그래머가 관리하는 방법들.

생략 가능한 매개변수

본래 정의된 것 보다 적으면 -> 나머지는 undefined
이렇게 두지 말고 생략된 매개변수에는 기본값을 주는 코드를 쓰자.

        function getPropertyNames(o, /*optional*/ a) {
            if(a == undefined) a = [];
            //or a = a || []
            // || -> 첫번째가 true나 true로 반환되는 값이면 그 값 return, 그렇지 않으면 뒤에 것 return
            for(var property in o) {
                a.push(property);
            }
            return a;
        }

가변길이 전달인자 목록 : Arguments객체

본래 정의된 것 보다 많을 때.

        function f(x, y, z) {
            if(arguments.length != 3) {
                throw new Error("인자개수가 3이 아닙니다.")
            }
        }

이렇게 해도 좋지만 javascript의 기본동작인

  • 빠진 인자는 undefined
  • 추가된 인자는 무시
    로도 잘 동작하게 구현 가능.

argument 객체를 직접 수정시

        function g(x) {
            console.log(x);
            arguments[0] = null;
            console.log(x);
        }

엄격모드가 아니면 값 변경, 엄격모드 시 값 변경되지 않음.

callee와 caller 속성

엄격모드에서는 사용 못함.
callee -> 프로퍼티가 현재 실행되고 있는 함수를 참조, 이름없는 함수를 재귀적으로 호출하는데 유용
caller -> 비표준. 이 함수를 호출한 함수를 참조. 호출 스택에 접근할 수 있도록 해줌.

객체의 프로퍼티를 전달인자로 사용하기

easycopy({from : a, to : b, length : 4});

값으로서의 함수

        function square(x) {return x * x};
        var s = square;
        square(4);
        s(4);

        var o = {square: function(x) {return x * x}};
        var y = o.square(16);

        var a = [function(x) {return x*x; }, 20];
        a[0](a[1]);

자신만의 함수 프로퍼티 정의하기

C 에서의 static 지역변수 역할

uniqueInteger.counter = 0;
function uniqueInteger() {
    return uniqueInteger.counter++;
}

함수 이름을 배열처럼 다룸

        function factorial(n) {
            if(isFinite(n) && n>0 && n == Math.round(n)) {
                if(!(n in factorial)) {
                    factorial[n] = n * factorial(n - 1);
                }
                return factorial[n];
            }
            else return NaN;
        }
        factorial[1] = 1;

네임스페이스로서의 함수

javascript 는 단위 block 내에 유효한 변수를 정의하는 방법을 제공하지 않음.
간단한 임시 네임스페이스 처럼 작동하는 함수를 정의하는 기법 사용.

        function mymodule() {
            // 모듈의 지역변수로 사용해서 전역을 어지럽히지 않음
        }
        mymodule(); // 함수 실행 필수

        // 하나의 프로퍼티 선언도 과하다면
        (function() {
            // 모듈 코드가 위치
        }()) // 바로 호출하고 끝냄. function앞 뒤 괄호는 반드시 필요 -> 표현식임을 알림

클로저

함수 객체, 함수의 변수가 해석되는 유효범위(변수 바인딩의 집합) 을 아울러 클로저라고 함
모든 자바스크립트 함수는 클로저.
-> 함수는 객체이고 함수 자신과 관련된 유효범위 체인을 가지고 있기 때문.

클로저는 자신을 정의한 바깥쪽 함수에 바인딩된 지역변수를 포착한다.

        var scope = "global";
        function checkscope() {
            var scope = "local";
            function f() {return scope;};
            return f;
        }
        checkscope()() // local 출력

EX) Counter

내부변수는 private. 오직 count와 reset을 통해서만 제어가능

        function counter() {
            var n = 0;
            return {
                count: function() {return n++;}, 
                reset: function() { n = 0; }
            }
        }

        var c = counter(), d = counter();
        console.log("c : ", c.count());
        console.log("d : ",d.count());
        c.reset()
        console.log("c : ",c.count());
        console.log("d : ",d.count());

Output:

Function 생성자

  • 동적으로 자바스크립트 함수를 생성하고 실행 시간에 컴파일 되는 것을 가능하게 한다.
  • 이걸로 생성하는 함수는 언제나 최상위 레벨 함수로, lexical scoping을 사용하지 않는다.

     

    var f = new function("x", "y", "return x*y);
    // 마지막 인자는 함수의 몸체 텍스트

 

'웹 프로그래밍 > Javascript' 카테고리의 다른 글

Javascript Scope, 변수  (0) 2020.06.23
Javascript Array  (0) 2020.06.23
JavaScript Property  (0) 2020.06.21
JavaScript Object 생성  (0) 2020.06.19
Javascript 세미콜론  (0) 2020.05.30

+ Recent posts