[웹 보안] CORS란?

보안 2019. 12. 25. 00:28
반응형
원문: https://dev.to/nicolus/what-you-should-know-about-cors-48d6

CORS는 Cross-Origin Resource Sharing의 줄임말이다. 

 

처음배우는 사람들에게는 CORS가 무엇때문에 사용되는지 헷갈릴때가 많다. 첫째로, CORS는 보안을 강화하기 위한 수단이 아니다. 사실 그의 정반대이다. CORS는 Same Origin Policy(Browser의 정책중 하나로 document나 script가 다른 domain과 교신하는 것을 막는다)를 피하기위함이다.

 

Same Origin Policy는 하나의 도메인에서 다른 도메인으로 요청하는 것을 막는다. 이렇게 하면 악성 웹사이트들이 다른 웹사이트들에게 요청보내는 것을 막을 수 있다. 이 정책은 브라우저에 적용되어 있기때문에 서버에서 보낸 요청이나 다른 HTTP 클라이언트(cURL / POSTman 등)에게는 적용되지 않는다. 서버는 이 요청들을 신뢰할 수 있는 도메인에서 보낸 요청이라고 생각하고 처리할 수 밖에 없다. 

 

SOP(Same Origin Policy)는 공격자가 요청을 보내는 것을 막기 위한 수단이 아니다(공격자들은 브라우저를 사용하지 않을 것이다..). SOP는 단지 정당한 사용자들이 본인도 모르게 보내는 요청들을 걸러주는 역할을 한다.

 

그래서 CORS는 일반적으로 SOP에 의해 막힐요청을 화이트리스트에 등록해 허용해주는 역할을 한다(예를 들자면 front-end app이 API에 요청을 보내는 것)

 

 

 

 

반응형
블로그 이미지

개발자_무형

,
반응형

Vanilla Javascript:

function DoPropertiesExist(parent, propertyNames, operator, isArray){
  let checkAND = true
  let checkOR = false

  propertyNames.forEach(prop => {
    //If Property exists
    console.log(prop)
    if (Object.prototype.hasOwnProperty.call(parent, prop) && parent[prop] != null) {
      if (isArray) {
        if (parent[prop].length == 0) checkAND = false
        else checkOR = true
      } else checkOR = true
    } else {
      checkAND = false
    }
  })

  if (operator == "AND") return checkAND
  else if (operator == "OR") return checkOR
}

parent에 검사하고 싶은 object,

propertyNames에는 확인하고 싶은 propertyNames들을 배열로 (ex: ["prop1","prop2","prop3"])

operator에는 "AND" 나 "OR"을

isArray에는 해당 property가 array인지 아닌지를 true / false로 넣어주면 빈 배열이 들어왔을 경우 걸러줍니다.

 

typescript 버전:

function DoPropertiesExist(parent: any, propertyNames: string[], operator: "AND" | "OR", isArray: boolean = false): boolean {
  let checkAND = true
  let checkOR = false

  propertyNames.forEach(property => {
    //If Property exists
    if (Object.prototype.hasOwnProperty.call(parent, property) && parent[property] != null) {
      if (isArray) {
        if (parent[property].length == 0) checkAND = false
        else checkOR = true
      } else {
        checkOR = true
      }
    } else {
      checkAND = false
    }
  })

  if (operator == "AND") return checkAND
  else if (operator == "OR") return checkOR
}
반응형
블로그 이미지

개발자_무형

,
반응형
원문: https://www.qwertee.io/blog/postgresql-b-tree-index-explained-part-1/
원문: https://en.wikipedia.org/wiki/B-tree

Index의 목적은 적은 양의 데이터를 찾을때 disk I/O를 줄이는 것이다. disk를 검색하는 작업은 O(n)이지만 index가 유용하기 위해서는 그보다 더 빨라야한다.

 

PostgreSQL의 default index는 B-Tree로 구성되며 좀 더 정확하게는 B+ Tree로 구성된다. B-Tree와 B+ Tree의 차이점은 key가 저장되는 방식에 있다. B-Tree에서는 각각의 Key들은 leaf node이든 non-leaf node이든 딱 1번만 저장되지만 B+ Tree는 모든 Key들은 leaf node에 존재하고 non-leaf node에도 존재할 수 있다. 

 

 

 

 

Leaf Nodes

Leaf Node는 table row을 가리키는 포인터를 가지고 있는 ROWIDkey를 가지고 있다. 각각의 leaf node사이에는 index key에 기반한 순서가 있다. 이 순서는 실제로 저장되는 physical order와는 독립적이다. physical order와 독립적이기 때문에 INSERT같은 작업을 하더라도 실제로 data를 옮기지 않고 몇개의 Pointer만을 업데이트하면 되기 때문에 작업을 빠르게 수행할 수 있다. 이렇게 logical order를 따라 저장되어 있기 때문에 오름차순과 내림차순 검색이 가능하다.

 

Internal Nodes(Non-leaf Nodes)

위의 사진을 보면 좀 더 쉽게 이해가 될 것 같은데 internal node에는 pre-define된 범위가 있다. 그리고 포인터들은 각각의 범위안의 노드들을 가리킨다. 즉 위의 예시에서 7보다 작은 key들이 모여져 있는 노드들을 가리키는 포인터, 7~16을 가리키는 포인터 16이상을 가리키는 포인터들이 있다.

 

보통 한묶음(노드)당 d~2d개의 key들로 구성이된다(d가 최소개수). 만약 2d개의 key들이 묶여있는데 한개가 추가된다면 d개로 이루어진 2묶음을 만들고, 2d+1개의 key들 중 중간값 1개를 부모 노드의 중간으로 올린다.

 

하나의 노드에서 파생되는 branch의 개수는 해당 노드에 포함된 key의 개수+1개이다.

 

B-Tree Search

위의 예시는 key 8을 찾는 예시이다.

 

1. 8은 root의 모든 key들보다 크므로 마지막 포인터를 타고 내려간다.

2. 첫번째 internal node(8)와 값이 같으므로 첫번째 포인터를 타고 내려간다.

3. 두번째 internal node(6)보다 값이 크므로 마지막 포인터를 타고 내려간다.

4. 이제 leaf node에 도달했기때문에 해당 leaf node부터 쭉 오른쪽으로 타고 가면서 찾고자 하는 값보다 큰 값이 나올때까지 검색한다.

 

 

 

 

 

 

반응형
블로그 이미지

개발자_무형

,
반응형

Database page:

Database에서 page는 DB가 data를 저장/관리하는 가장 기본적인 단위이다.

쉽게 비유하자면, 

Database
Page Page
Row Sentence

하지만 (DB마다 조금씩 다르겠지만), row는 page 용량의 반을 넘어갈 수 없다.

https://stackoverflow.com/questions/4401910/mysql-what-is-a-page

 

Clustered Index vs Non-clustered Index:

Clustered Index는 index에 저장되는 순서와 같은 순서로 disk에 저장되는 것이다. 따라서 clustered index는 1종류밖에 없다.

Non-clustered Index는 실제 물리적으로 저장되는 것과는 별도로 다른 리스트가 존재하는 것이다. 이 리스트는 물리적인 주소값을 저장하고 있는 포인터를 가지고 있다.

만약 모든 column을 반환하고 싶다면 주로 clustered index가 더 빠르다. 이유는 Non-clustered Index는 인덱스에서 테이블을 한번 더 찾아가야 되기 때문이다.

https://stackoverflow.com/questions/1251636/what-do-clustered-and-non-clustered-index-actually-mean

 

어떤 Column에 Index를 생성해야할까?

Primary Key를 가지는 새로운 테이블을 생성하게되면 clustered index가 자동으로 primary key의 column에 대해 생성되게 된다. 대부분의 경우에는 괜찮지만 가끔가다 가장 효과적이지 않은 경우도 있다.

 

Clustered Index로 사용되는 column은 unique하고 새로운 entry가 들어갈 때마다 값이 증가되는 column인것이 좋다. 그렇지 않을 경우 새로운 row가 insert될 때마다 index는 새로 정렬되어야 한다. 새로 입력된 row가 있어야될 위치를 찾기위해 data page를 새로 분리하고 위치를 옮기는 작업이 필요하다.

 

- 같은 맥락으로 자주 값이 변경되는 column도 Clustered Index로 사용되면 안된다. 매 업데이트때마다 재정렬을 해야되기 때문이다.

- 큰 데이터를 저장하는 column(BLOB, GUID)를 index를 사용하는 것은 sort할 때 비효율적이다.

 

https://www.sqlshack.com/poor-database-indexing-sql-query-performance-killer-recommendations/

 

 

 

 

 

반응형
블로그 이미지

개발자_무형

,
반응형
https://leopard.in.ua/2015/04/13/postgresql-indexes#.XfeTyugzZaR

Index는 추가적인 자료구조로서 아래의 목적들의 달성을 위해 도움이 된다:

1. 데이터 검색

2. Optimizer

3. JOIN

4. Relation: except/intersect를 위해 사용될 수 있다.

5. Aggregation: COUNT/MIN/MAX 등의 Aggregatation function들을 효율적으로 계산할 수 있게 해준다.

6. Grouping

 

Index Types: PostgreSQL에는 여러가지 Index타입들이 있으며 각각 다른 사용법을 가지고 있다.

 

B-Tree index: B-Tree는 CREATE INDEX를 하면 default로 생성되는 index이다. B-Tree의 B는 Balanced의 줄임말로서 트리의 양쪽이 거의 같은 양의 데이터를 가지도록 하는 것이 기본개념이다. B-Tree는 self-balancing 트리로서 sorted data를 유지하고, 검색, 순차적인 접근, 삽입, 삭제를 log시간안에 할 수 있는 자료구조이다. B-Tree는 큰 양의 데이터를 읽고 써야되는 경우에 용이하다.

https://en.wikipedia.org/wiki/B-tree

 

R-Tree index: R-Tree는 Rectangle-Tree의 줄임말이다. R-Tree는 주로 공간정보를 저장할 때 사용되는 트리다. 예를 들자면 지리좌표나, 다각형 좌표 등이다. R-Tree의 핵심 아이디어는 가까이 있는 객체들을 그들의 minimum bounding rectangle로 묶어 한단계 상위 계급인 트리로 표현하는 것이다. 모든 객체들은 이런 bounding rectangle에 포함되어 있고, 이 bounding rectangle과 intersect하지 않는 쿼리는 이 rectangle에 포함된 모든 객체들과도 intersect하지 않는다. leaf 레벨에서는 rectangle을 각각의 객체로 보고, 상위 레벨에서는 rectangle을 object들의 모음으로 본다.

 

https://en.wikipedia.org/wiki/R-tree
https://en.wikipedia.org/wiki/Minimum_bounding_rectangle

 

More:

Hash index

Bitmap index

GiST index

GIN index

반응형
블로그 이미지

개발자_무형

,
반응형
출처: https://www.elastic.co/guide/en/elasticsearch/reference/current/full-text-queries.html
출처: https://stackoverflow.com/questions/26001002/elasticsearch-difference-between-term-match-phrase-and-query-string

1. term

하나의 term을 찾는다. 이 term은 analyze 되지 않는다. 따라서 대소문자, 복수형 등이 다 구분된다

{ "user":"Bennett" }

{
  "query": {
    "term" : { "user" : "bennett" }
  }
}
//아무것도 리턴되지 않는다. (대소문자 구분)

 

2. match

가장 기본적인 search로 text, number, date, boolean을 사용할 수 있다. text는 검색하기전 analyze된다.

fuzzy matching을 지원한다(정확하게 일치하지않더라도 연관성이 있다고 판단하면 리턴).

GET /_search
{
    "query": {
        "match" : {
            "message" : {
                "query" : "this is a test"
            }
        }
    }
}

 

3. query_string

입력값을 analyze한다. 사용자가 명시적으로 ""로 둘러싸지않는이상 순서는 상관이 없다.

{ "foo":"I just said hello world" }
{ "foo":"Hello world" }
{ "foo":"World Hello" }

{
  "query": {
    "query_string": {
      "query": "hello World"
    }
  }
}
//얘는 3개를 다 리턴한다

{
  "query": {
    "query_string": {
      "query": "\"Hello World\""
    }
  }
}
//얘는 명시적으로 ""로 싸여져 있기 때문에 match_phrase와 동일하게 처음 2개만을 리턴한다.

query_string과 match의 차이점은 AND와 OR같은 연산자를 사용할 수 있다. 

query_string은 syntax를 먼저 parse한 뒤에 split을 하고 analyze를 한다.

GET /_search
{
    "query": {
        "query_string" : {
            "query" : "(new york city) OR (big apple)",
            "default_field" : "content"
        }
    }
}

주의할 점: query_string은 invalid syntax에 대해 에러를 반환하므로 AND와 OR과 같은 query syntax를 지원해야되는 것이 아니라면 match를 사용하거나 좀 더 덜 엄격한 simple_query_string을 사용하는 것이 낫다.

 

4. Intervals

matching rules를 사용하여 쿼리한다. 여러개의 term들이 원하는 간격안에 존재하는지 쿼리한다.

아래의 쿼리는 "hot"과 "porridge"사이에 10단어 이상 간격이 없으면서 중간에 "salty"가 없어야 된다.

POST _search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "match" : {
          "query" : "hot porridge",
          "max_gaps" : 10,
          "filter" : {
            "not_containing" : {
              "match" : {
                "query" : "salty"
              }
            }
          }
        }
      }
    }
  }
}

 

5. match_phrase

입력값을 analyze한다. 그리고 다음의 조건을 충족하는 document를 찾아서 반환한다.

- 모든 term들이 field에 존재해야한다.

- 모든 term들이 입력된 순서에 맞게 존재해야된다.

{ "foo":"I just said hello world" }
{ "foo":"Hello world" }
{ "foo":"World Hello" }

{
  "query": {
    "match_phrase": {
      "foo": "Hello World"
    }
  }
}
//1번째 2번째만 리턴된다. 3번째는 순서가 틀림

 

6. match_boolean_prefix

마지막 term을 제외한 모든 term은 term query에 사용된다. 마지막 term은 prefix query에 사용된다.

따라서 아래의 match_bool_prefix는 그 밑의 term과 prefix로 이루어진 query와 동일하다

GET /_search
{
    "query": {
        "match_bool_prefix" : {
            "message" : "quick brown f"
        }
    }
}

GET /_search
{
    "query": {
        "bool" : {
            "should": [
                { "term": { "message": "quick" }},
                { "term": { "message": "brown" }},
                { "prefix": { "message": "f"}}
            ]
        }
    }
}

match_phrase_prefix와 상당히 유사하지만 match_phrase_prefix는 입력값을 phrase로 보고 쭉 이어진 하나로 검색을 하는 반면, match_boolean_prefix는 term단위로 검색을 하기때문에 서로 떨어져 있어도 가능하고, 순서가 뒤섞여있어도 가능하다.

 

7. match_phrase_prefix

위에서 언급했던 것처럼 입력값을 하나의 뭉텅이로 검색한다 따라서:

     - quick brown fox (O)

     - two quick brown ferrets (O)

     - the fox is quick and brown (X)

 

8. multi_match

multi_match는 multi query를 바탕으로 여러 field를 동시에 쿼리할 수 있도록 한다.

GET /_search
{
  "query": {
    "multi_match" : {
      "query" : "this is a test",
      "fields" : [ "subject^3", "*_name" ] 
    }
  }
}

위의 코드처럼 subject 필드에 3배의 가중치를 줄 수 있으며 field이름에 * wildcard를 사용할 수 있다.

 

만약 field가 명시되어 있지 않다면 index.query.default_field로 설정된 field에서 검색하고, 이 default_field는 따로 명시하지 않았다면, index의 field는 term query를 수행할 수 있는 모든 field를 추출하여 수행한다.

 

multi_match가 어떻게 작동할지는 type 파라미터에 따라 결정된다.

 - best_fields: 여러개의 field들 중에서 입력값 단어들 중 가장 많은 단어를 가지고 있는 하나의 field의 점수를 사용

 - most_fields: 여러개의 field들의 점수를 산출한뒤 합산하고 field의 개수로 나눈 평균점수를 사용한다

 

 - phrase / phrase_prefix: best_fields와 똑같지만 match_phrase / match_phrase_prefix를 match대신 사용

 

 - cross fields: 여러개의 field가 동시에 만족되야할 경우(예: 성과 이름이 다른 field에 들어가있을때). query string을 individual term으로 analyze한 뒤에 마치 하나의 field를 검색하는 것처럼 모든 field를 살펴본다. 

(위의 best_field와 most_field와는 달리 어느 하나의 field에 모든 term이 존재하면 된다)

(주의: cross_fields에는 fuzziness가 사용될 수 없다)

 

tie_breaker: 점수가 산정되는 방식을 결정한다:

     - 0.0 : 모든 field 중 가장 높은 점수를 가진 field의 점수를 선택

     - 1.0 : 모든 field의 점수를 합함

     - 0.0 < n < 1.0: 가장 높은 field의 점수 + (n * 나머지 matching field 점수)

 

 

반응형
블로그 이미지

개발자_무형

,
반응형
본문은 Node.js Design Patterns - Mario Casciaro 를 번역/정리한 글입니다.

Blocking I/O

- 기존의 Blocking I/O를 웹서버에 사용하게 되면 동시에 여러 접속을 처리하기 위해 각각의 커넥션을 별도의 쓰레드로 분리를 하여야한다. 이렇게 각가의 쓰레드가 하나의 커넥션만을 처리하게 되면 실제로 일을 하는 시간보다 기다리는 시간이 훨씬 많아지게 된다. 그리고 쓰레드를 여러개 사용하는것은 메모리를 많이 잡아먹고 Context Switch를 발생시키므로 효율적이지 않다.

 

Non Blocking I/O

- Non-blocking I/O에서는 system call이 데이터를 읽고 쓰는것을 기다리지 않고 만약 그시점에 처리할 것이 없다면 바로 반환해버린다.

 

Busy Waiting

- Non-blocking I/O에서는 여러 커넥션을 병렬적으로 처리하기 위한 방법 중 가장 간단한 방법으로 리소스를 polling(수시로 체크)하는 busy-waiting이라는 방법이 있다. 아래의 pseudo 코드 방식으로 작동한다:

resources = [socketA, socketB, socketC];
while(!resources.isEmpty()) {
	for(i=0;i < resources.length; i++){
    	resource = resources[i]
        var data = resource.read();
        if (data == NO_DATA_AVAILABLE)
        	continue;
        if (data == RESOURCE_CLOSED)
        	resources.remove(i);
        else
        	consumeData(data)
    }
}

이런방식을 사용하면 동시에 여러개의 접속을 하나의 쓰레드에서 처리할 수 있다. 하지만 이러한 Polling 알고리즘들은 CPU를 너무 낭비한다.

 

Synchronous Event Demultiplexer

- 이를 효율적으로 해결한 방법이 Synchronous Event Demultiplexer 또는 Event Notification Interface이다.

socketA, pipeB;
watchedList.add(socketA, FOR_READ)
watchedList.add(pipeB, FOR_READ)
while( events = demultiplexer.watch(watchedList)){
	foreach(event in events){
		data = event.resource.read()
        if(data == RESOURCE_CLOSED)
        	demultiplexer.unwatch(event.resource)
        else
        	consume(data)
	}
}

1. 여기서 핵심은 demultiplexer.watch(watchedList)인데, demultiplexer가 watchedList를 계속 보면서 다음으로 넘어가지않고 Block하고 있다가 watchedList 중 하나라도 준비가 된다면 다음 foreach문으로 넘어간다.

2. 이 foreach문이 실행될때는 각각의 event들이 준비가 되었다는것이 보장이 되어 처리될때 block이 되지않는다.

3. 모든 event가 처리되고 나면 다시 demultiplexer가 block하며 새로운 event가 발생할때까지 기다린다.

이 일련의 과정을 event loop라고 한다.

 

따라서 정리하자면 각각의 쓰레드에서 커넥션을 1개씩 잡고 있는게 아니라 event demultiplexer가 여러개의 커넥션을 보고있다가 event가 발생하면 이를 모아서 전달해주는데, 이 모여진 event들은 blocking되지 않고 바로 처리할 수 있기 때문에 1개의 쓰레드로 처리가 가능하게 된다.

 

이 방식을 차용하면 쓰레드가 기다리는 idle time이 획기적으로 줄게되고 single thread로 운용이 가능해지기 때문에 race condition이나 multi-thread synchronization같은 문제를 겪지않고 더 직관적이게 병렬처리가 가능해진다.

 

The Reactor Pattern

Reactor 패턴은 앞에서 소개한 알고리즘의 특화된 버전이다. 핵심이 되는 아이디어는 각각의 I/O에 핸들러를 붙이는 것이다(Node.JS에서는 Callback). 그리고 이 핸들러들은 event가 발생하면 호출되어 event loop에 의해 처리된다.

 

Reactor패턴이 처리하는 방식은 다음과 같다:

1. Application은 Event demultiplexer에게 새로운 요청을 보냄으로서 새로운 I/O를 생성한다. Application은 요청을 보낼때 event가 발생하면 호출될 Handler를 설정하여 보낸다. 이 작업은 Non-Blocking이다.

2. I/O 작업이 끝나면 Event Demultiplexer는 새로운 event를 Event Queue에 삽입한다.

3. 이 때가 되면 Event Loop가 Event Queue를 순회한다.

4. 이벤트가 발생하면, 각각에 적용된 핸들러가 호출된다.

5. 어플리케이션 코드의 일부인 핸들러는 본인의 작업이 완료되면 Event Loop에게 control을 다시 넘겨준다. 

6. Event Queue에 있는 모든 작업이 완료되면 Event Demultiplexer가 다음 사이클을 시작할때까지 block 된다.

 

Node.js의 Non-Blocking Engine - libuv

I/O operation은 같은 OS안에서도 resource의 종류에 따라 상당히 다르게 처리될 수 있다. 예를 들자면 Unix의 regular filesystem은 non-blocking operation을 지원하지 않는다. 따라서 non-blocking처럼 행동하게 만들기 위해서는 event loop 밖에 별도의 thread를 사용하여 처리하게 된다. 이렇게 다양한 운영체제에서 Event Demultiplexer를 지원하기 위해서는 high-level abstraction이 필요했다. 그래서 메이저 OS들을 지원하기 위해 Node.js core team은 libuv라는 C 라이브러리를 만들게 되었다.

 

The Callback Pattern

Javascript는 callback을 나타내기 위한 최적의 언어이다. Function은 class object로서 쉽게 변수에 할당될 수 있고, argument로 전달되거나 return으로 반환될 수도 있다. 그리고 closure를 사용하면 function이 생성된 환경을 쉽게 접근할 수 있다. 즉, asynchronouse operation이 생성된 context를 언제 callback이 불러지던 접근할 수 있다.

 

Callback은 다른 함수에 인자로 전달되는 함수로서 함수의 작업이 끝나면 작업의 결과물과 함께 호출되는 함수이다.

이런 방식은 함수형 프로그래밍에서는 Continuation-Passing style(CPS)라고 불리며 Asynchronous operation에서만 사용되는 개념은 아니다. 단지 이 방식은 작업의 결과물을 caller에게 바로 반환하는 것이아니라 다른 함수에게 전달하는 방식을 뜻할 뿐이다.

 

반응형
블로그 이미지

개발자_무형

,
반응형

------국내------

네이버:

https://d2.naver.com/

불러오는 중입니다...

우아한형제들:

http://woowabros.github.io/

 

우아한형제들 기술 블로그

이 블로그는 배달의민족, 배민라이더스, 배민상회 등 Food Tech를 선도하는 우아한형제들 기술조직의 성장 일기를 다루는 블로그입니다./

woowabros.github.io

카카오: 

https://tech.kakao.com/

 

kakao Tech

카카오는 사람과 사람, 사람과 기술을 한층 가깝게 연결함으로써, 어제보다 더 나은 세상을 만들어 갑니다.

tech.kakao.com

VCNC(쏘카/비트윈):

http://engineering.vcnc.co.kr/

 

VCNC Engineering Blog

모빌리티 플랫폼 타다, 국민 커플앱 비트윈 개발사 VCNC의 엔지니어링 블로그입니다. 우리의 서비스를 개발하면서 있었던 어려움이나 얻은 경험들을 공유하고자 합니다.

engineering.vcnc.co.kr

티몬:

https://tmondev.blog.me/

 

티몬의 개발이야기 : 네이버 블로그

더 나은 서비스를 고민하는 티몬 플랫폼의 뒤쪽 세상 이야기!

blog.naver.com

라인:

https://engineering.linecorp.com/ko/blog/

 

Blog - LINE ENGINEERING

작년 1월에 LINE에 입사했고, 믿기 힘들게도 어느덧 입사한 지 2년이 다 되어 갑니다. 이 글을 쓰며 회사란 참 시간이 빨리 흘러가는 무서운 공간이라는 것을 다시 한 번 느낍니다. 근 2년간 제가 LINE이라는 회사에 다니며 신입 개발자의 시선으로 바라본 회사의 모습과, 또 그 속에서 느낀 점을 자유롭게 적어보았습니다.

engineering.linecorp.com

클래스101:

https://class101.dev/ko/

 

Home

신나는 코딩세상

class101.dev

토스트:

https://meetup.toast.com/

 

TOAST Meetup - NHN 기술 블로그

기술을 공유하고 함께 성장해가는 개발 문화, NHN이 추구하는 가치입니다.

meetup.toast.com

레진코믹스:

https://tech.lezhin.com/

 

레진 기술 블로그

프리미엄 웹툰 서비스 - “레진코믹스” 를 만들고 있는 레진엔터테인먼트가 운영하는 기술 블로그입니다. 글로벌 콘텐츠 플랫폼을 만들면서 익힌 실전 경험과 정보, 최신 기술, 팁들을 공유하고 있습니다. 훌륭한 개발자님들을 계속 모시고 있으니 편하게 지원해주세요!

tech.lezhin.com

스포카:

https://spoqa.github.io/

 

Spoqa 기술 블로그

스포카 크리에이터의 경험과 배움을 공유합니다.

spoqa.github.io

 

------해외------

 

 

페이스북:

https://engineering.fb.com/

 

Facebook Engineering

News about Infrastructure Systems, Open Source, Connectivity, Data Center Engineering, and Developer Tools

engineering.fb.com

링크드인:

https://engineering.linkedin.com/blog

 

Blog | LinkedIn Engineering

Co-authors: Todd Palino, Samir Jafferali, Kurt Andersen, and Carolyn Blood LinkedIn hosted its 4th annual SRE[in]con conference in late October that brought together over 700 LinkedIn site engineers, as well as partners from Microsoft, Github, Drawbridge a

engineering.linkedin.com

인스타그램:

https://instagram-engineering.com/

 

Instagram Engineering

Stories from the people who build @Instagram.

instagram-engineering.com

드롭박스:

https://blogs.dropbox.com/tech/

 

Dropbox Tech Blog

One of the biggest challenges of the mobile developer community at Dropbox in 2018 was our custom build system. Our build system was slow, hard to use, and didn’t support some use cases which were out of scope of the original design. After 4 months of work

blogs.dropbox.com

마이크로소프트:

https://techcommunity.microsoft.com/t5/custom/page/page-id/Blogs

 

Blogs - Microsoft Tech Community

Recent Blog Articles

techcommunity.microsoft.com

트위터:

https://blog.twitter.com/engineering/en_us.html

 

English (US)

Information from Twitter's engineering team about our tools, technology and services.

blog.twitter.com

넷플릭스:

https://medium.com/netflix-techblog

 

Netflix TechBlog – Medium

Learn about Netflix’s world class engineering efforts, company culture, product developments and more.

medium.com

아마존:

https://developer.amazon.com/blogs

 

Join the Conversation and Chat with the Newest Alexa Prize Socialbots

Amazon Apps & Services Developer Portal

developer.amazon.com

구글:

https://developers.googleblog.com/

 

Google Developers Blog

News and insights on Google platforms, tools, and events.

developers.googleblog.com

이베이:

https://tech.ebayinc.com/

 

Tech Blog - eBay Inc.

eBay technologists recently showed off a distributed transaction protocol called GRIT, for distributed ACID (atomicity, consistency, isolation, durability) transactions across microservices with multiple underlying databases. By: Gene Zhang, Mohammad Roohi

tech.ebayinc.com

페이팔:

https://medium.com/paypal-engineering

 

PayPal Engineering – Medium

The PayPal Engineering Blog.

medium.com

에어비엔비:

https://medium.com/airbnb-engineering

 

Airbnb Engineering & Data Science – Medium

Creative engineers and data scientists building a world where you can belong anywhere. http://airbnb.io.

medium.com

 

반응형
블로그 이미지

개발자_무형

,