[Web Development] CSR (Client-Side Rendering)과 SSR (Server-Side Rendering) 이해하기

웹페이지를 브라우저에서 렌더링하는 방식에는 크게 두 가지, CSR (Client-Side Rendering)과 SSR (Server-Side Rendering)가 있습니다. 이 두 방식은 사용자에게 웹페이지를 어떻게 제공하는지에 대한 핵심적인 차이를 보입니다. 이 포스트에서는 CSR과 SSR의 개념, 작동 방식, 장단점을 통해 두 기술을 살펴보겠습니다.

해당 포스트에서 언급하는 렌더링은 웹 브라우저에서 HTML을 이용해 실제 사용자 인터페이스를 그리는 과정을 뜻하는 것이 아니며, 서버 혹은 클라이언트 단에서 템플릿 엔진이 HTML을 생성하는 것을 의미합니다.

CSR (Client-Side Rendering)

CSR은, 말 그대로 클라이언트 측에서 웹페이지를 렌더링하는 방식을 의미합니다. 사용자가 웹사이트에 요청을 보내면 서버는 HTML 파일과 JavaScript 파일을 클라이언트에게 보냅니다. 클라이언트의 브라우저는 이 파일을 사용하여 웹페이지를 구성하고 렌더링합니다.

CSR 작동 방식

출처 : https://www.solutelabs.com/blog/client-side-vs-server-side-rendering-what-to-choose-when

  1. 사용자가 웹사이트를 요청합니다.
  2. 이 요청은 CDN(Content Delivery Network)에 도달합니다.
  3. CDN은 HTML 파일과 JavaScript에 대한 링크를 클라이언트로 전송합니다. 클라이언트는 HTML을 먼저 다운로드하고 이후 JavaScript를 다운로드합니다. 이때, SSR과 달리 사용자는 아직 웹페이지를 볼 수 없습니다.
  4. 브라우저는 JavaScript를 다운로드 합니다.
  5. JavaScript 파일이 완전히 다운로드되면, 해당 JavaScript가 실행됩니다. 이는 필요한 데이터를 서버에 요청하는 API를 호출하게 됩니다. 이 단계에서 사용자는 화면에 placeholder(데이터가 로드될 공간)를 보게 됩니다.
  6. 이제 서버는 API 요청에 응답하여 필요한 데이터를 제공합니다.
  7. 클라이언트는 이 데이터를 받아 placeholder에 채워넣습니다. 이제 웹페이지는 완전히 로드되어 사용자와 상호작용이 가능해집니다.

CSR의 장점

  • 서버 부하 감소 : 모든 렌더링 작업이 클라이언트에서 이루어지므로 서버 부하가 감소합니다.
  • 사용자와의 상호작용에 좋음 : 브라우저에서 직접 렌더링을 수행하기 때문에 동적인 사용자 인터페이스를 쉽게 구현할 수 있습니다.

CSR의 단점

  • 초기 로딩 시간이 길 수 있음 : 모든 자원을 다운로드 받아야 하기 때문에 초기 로딩 시간이 길어질 수 있습니다.
  • SEO 문제 : 웹 크롤러가 JavaScript를 완전히 해석하지 못하는 경우 페이지의 내용을 제대로 인식하지 못할 수 있습니다. (이 내용을 다른 포스트에서 추가로 다룰 예정입니다.)

참고 : Google Web Fundamentals – JavaScript Start-up Optimization

SSR (Server-Side Rendering)

반면에, SSR은 서버에서 웹페이지를 렌더링하는 방식입니다. 사용자가 웹사이트에 접속 요청을 보내면, 서버는 해당 요청에 맞는 HTML을 렌더링하고 이를 클라이언트에게 보냅니다. 클라이언트는 받은 HTML을 그대로 화면에 표시합니다.

SSR 작동 방식

출처 : https://www.solutelabs.com/blog/client-side-vs-server-side-rendering-what-to-choose-when

  1. 사용자가 웹사이트를 요청합니다.
  2. 이번에는 서버가 중요한 역할을 합니다. 서버는 ‘렌더링 준비가 된’ HTML 파일을 생성합니다. 이는 서버가 모든 리소스를 확인하고 필요한 HTML 컨텐츠를 컴파일하여 만들내는 과정을 말합니다.
  3. 클라이언트에게 전송되는 HTML은 이미 렌더링이 준비된 상태이므로, 클라이언트는 이를 즉시 화면에 렌더링합니다. 그러나 이 시점에서는 JavaScript가 아직 로드되지 않았으므로, 사이트는 아직 사용자 조작이 불가능합니다.
  4. 클라이언트는 이제 JavaScript를 다운로드합니다.
  5. JavaScript가 다운로드되는 동안, 사용자는 컨텐츠는 볼 수 있지만 사이트를 조작할 수는 없습니다. 이때 사용자의 조작은 저장되어 있다가 이후에 처리됩니다.
  6. 브라우저는 다운로드된 JavaScript를 실행합니다.
  7. 이제 JavaScript도 성공적으로 컴파일되었으므로, 이전에 저장된 사용자 조작이 실행됩니다. 웹 페이지는 이제 완전히 상호작용 가능한 상태가 됩니다.

SSR의 장점

  • 초기 로딩 시간이 짧음 : 필요한 HTML만 받아서 화면에 표시하면 되므로 초기 로딩 시간이 짧습니다.
  • SEO 향상 : 웹 크롤러가 HTML을 바로 인식할 수 있어서 검색 엔진 최적화(SEO)에 유리합니다.

SSR의 단점

  • 서버 부하 증가 : 모든 요청마다 새로운 HTML을 렌더링해야 하므로 서버 부하가 증가할 수 있습니다.
  • 사용자와의 상호작용에 제약: 모든 페이지 변경 요청마다 서버에 요청을 보내고 응답을 기다려야 하므로 사용자 경험에 제약이 생길 수 있습니다.

참고 : Google Search Central – Understand the JavaScript SEO basics

카테고리: Web Development | 댓글 남기기

[Web Development] CORS (Cross-Origin Resource Sharing) 이해하기

CORS 개요

CORS는 Cross-Origin Resource Sharing의 약자로, 다른 출처(origin)에서 자원을 공유할 수 있도록 하는 메커니즘입니다. 웹 페이지가 다른 도메인의 자원에 접근하려고 할 때, 보안상의 이유로 브라우저는 동일 출처 정책(Same-Origin Policy)을 적용합니다. 이 정책은 웹 페이지가 자신과 동일한 출처에서만 리소스를 로드하도록 제한합니다. 그러나 CORS를 사용하면 웹 애플리케이션은 이 제한을 우회하고 다른 도메인의 리소스에 접근할 수 있습니다.

CORS 작동 방식

CORS는 HTTP 헤더를 사용하여 도메인 간에 자원을 공유할 수 있도록 합니다. 웹 애플리케이션은 HTTP 요청을 보낼 때 ‘Origin’ 헤더를 포함하여 요청을 보냅니다. 이 헤더는 요청이 시작된 웹 페이지의 출처를 나타냅니다. 서버는 이 헤더를 확인하고, ‘Access-Control-Allow-Origin’ 헤더를 응답에 포함하여 해당 출처에서의 요청을 허용할지 결정합니다.

CORS 작동 방식

CORS의 중요성

CORS는 웹의 중요한 보안 메커니즘입니다. 웹 애플리케이션은 종종 다른 도메인의 API를 사용하여 데이터를 가져오거나, CDN(Content Delivery Network)을 통해 이미지나 스크립트를 로드합니다. 이러한 도메인 간의 자원 공유는 웹의 핵심 기능 중 하나이지만, 동일 출처 정책 없이는 보안 위협이 될 수 있습니다.

CORS는 어떤 리소스가 허용되고 어떤 리소스가 차단되는지를 결정하는 규칙을 제공합니다. 이 규칙은 웹 애플리케이션의 HTTP 응답 헤더에 의해 설정됩니다.

예를 들어, 웹 애플리케이션 A가 다른 도메인의 리소스에 접근하려고 할 때, 그 도메인의 서버는 ‘Access-Control-Allow-Origin‘ 헤더를 사용하여 웹 애플리케이션 A의 접근을 허용할 수 있습니다. 이 헤더가 없거나 웹 애플리케이션 A의 출처를 허용하지 않는 값이 설정되어 있으면, 브라우저는 리소스에 대한 접근을 차단합니다.

동일 출처 정책(Same-Origin Policy)이 없다면, 웹 애플리케이션은 다음과 같은 보안 위협에 노출될 수 있습니다.

  • 사이트 간 스크립팅 공격 (Cross-Site Scripting, XSS): 악의적인 스크립트가 웹 애플리케이션에 삽입되어 사용자의 데이터를 탈취하거나 조작하는 공격입니다. 동일 출처 정책이 없다면, 악의적인 스크립트가 다른 도메인에서 로드되어 실행될 수 있습니다.
  • 사이트 간 요청 위조 공격 (Cross-Site Request Forgery, CSRF): 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행동을 하도록 만드는 공격입니다. 동일 출처 정책이 없다면, 웹 애플리케이션은 다른 도메인의 요청을 받아들일 수 있으므로 CSRF 공격에 취약해집니다.

CORS(Cross-Origin Resource Sharing)는 이러한 보안 위협을 방지하면서도 필요한 경우 다른 도메인의 자원을 안전하게 사용할 수 있도록 하는 메커니즘입니다. CORS는 브라우저가 서버에게 자원을 요청할 때 추가적인 HTTP 헤더를 사용하여, 서버가 다른 도메인의 자원 요청을 허용하는지를 확인합니다.

CORS 스펙 문서

CORS에 대한 자세한 사항은 W3C의 공식 스펙 문서를 참조하시면 됩니다. 이 문서는 CORS의 작동 방식, HTTP 헤더의 사용 방법, 에러 처리 방법 등에 대한 자세한 정보를 제공합니다.

WC3 : Cross-Origin Resource Sharing

동일 출처(origin) 확인

CORS에서 동일 출처(origin)를 판단할 때, scheme, host, port 요소가 모두 동일한지 검사를 합니다. 이 중 한가지 라도 다르다면 동일한 출처(origin)으로 판단하지 않습니다.

Understanding "same-site" and "same-origin"

The Web Origin Concept – Origin of a URI

WebSocket을 활용한 실시간 채팅 앱을 구현하면서, 해당 개념을 깊게 이해하지 못해 애를 먹었는데요. 로컬에서 정상 동작하던 채팅 앱을 서버에 배포하면서, JavaScript 단에서 SockJS 생성시에 403 Forbidden 응답 코드가 리턴되었습니다.

결과적으로 서버단에서 registerStompEndpoints 메서드에 EndPoint를 추가하는 코드에 .setAllowedOrigins으로 특정 도메인을 허용하면서 문제를 해결하였습니다. (환경 변수 HOST_ENDPOINT를 통해 도메인을 참조합니다.)

예를 들어 https://chat.example.com 도메인으로 요청하는 경우, JavaScript 단에서 SockJS 생성시에 http 혹은 https에 따라, ws 혹은 wss 프로토콜로 업그레이드(wss://chat.example.com)를 합니다.

이런 경우에, scheme(프로토콜)이 변경되어 CORS에 의해 동일 출처(origin)가 아닌 것으로 판단되기 때문에 403 Forbidden 응답 코드가 리턴되었던 것입니다.

카테고리: Web Development | 댓글 남기기

[C] qsort() 함수

C언어에서 배열을 정렬하는 방법 중 하나는 표준 라이브러리 함수인 qsort()를 사용하는 것입니다. qsort()는 C 언어의 표준 라이브러리 중 하나인 stdlib.h 헤더 파일에 정의되어 있으며, 퀵 정렬 알고리즘을 기반으로 합니다. 이 함수는 배열의 요소 타입에 상관없이 정렬을 수행할 수 있습니다.

qsort() 함수의 원형은 다음과 같습니다.

여기서 ptr는 정렬할 배열을 가리키는 포인터, count는 배열에 있는 요소의 개수, size는 배열의 각 요소의 크기를 바이트 단위로 나타내며, comp는 비교 함수를 가리키는 포인터입니다.

다음은 qsort() 함수를 사용하여 정수 배열을 오름차순으로 정렬하는 예제입니다.

이 코드는 compare()라는 비교 함수를 사용하여 qsort() 함수를 호출합니다. compare() 함수는 두 개의 void 포인터를 인자로 받아, 이를 int 포인터로 형 변환한 후에 참조하여 두 정수를 비교합니다. 이 함수는 첫 번째 정수가 두 번째 정수보다 작을 경우 음수를, 같을 경우 0을, 큰 경우 양수를 반환합니다. 이렇게 하면 qsort() 함수는 이 비교 함수를 사용하여 배열을 오름차순으로 정렬할 수 있습니다.

그런데 qsort()는 정수 배열뿐만 아니라 문자열 배열도 정렬할 수 있습니다. 다음은 qsort() 함수를 사용하여 문자열 배열을 알파벳 순으로 정렬하는 예제입니다.

이 코드는 compare_strings()라는 비교 함수를 사용하여 qsort() 함수를 호출합니다. compare_strings() 함수는 두 개의 void 포인터를 인자로 받아, 이를 문자열 포인터로 형 변환한 후에 참조하여 두 문자열을 비교합니다. 이 함수는 첫 번째 문자열이 두 번째 문자열보다 사전 순으로 앞설 경우 음수를, 같을 경우 0을, 뒤설 경우 양수를 반환합니다. 이렇게 하면 qsort() 함수는 이 비교 함수를 사용하여 배열을 알파벳 순으로 정렬할 수 있습니다.

카테고리: C, Programming | 댓글 남기기

[Kotlin] Array와 IntArray의 차이점

Kotlin에서 정수 배열을 선언할 때, Array<Int>IntArray를 사용할 수 있습니다. 두 타입 모두 정수 배열을 나타내지만, 둘 사이에는 몇 가지 중요한 차이점이 있습니다.

1. 표현 방식

Array<Int>는 일반적인 배열로, 각 요소는 Int 객체입니다. 반면에 IntArray는 원시 타입 배열로, 각 요소는 원시 타입 int입니다.

예를 들어, 다음과 같이 각각 선언할 수 있습니다.

2. 메모리 사용량

Array<Int>는 각 요소가 객체이므로 IntArray보다 더 많은 메모리를 사용합니다. IntArray는 원시 타입을 사용하므로 메모리 효율성이 더 높습니다.

3. 성능

Array<Int>는 박싱(Boxing)과 언박싱(Unboxing) 과정이 필요하므로 IntArray보다 성능이 떨어질 수 있습니다. IntArray는 원시 타입을 사용하므로 이러한 과정이 필요 없습니다.

박싱(Boxing)이란 원시 타입의 값을 객체로 변환하는 과정을 의미합니다. 예를 들어, int 타입의 값을 Integer 객체로 변환하는 것이 박싱입니다. 반대로 언박싱(Unboxing)은 객체에서 원시 타입의 값을 추출하는 과정을 의미합니다.
이러한 박싱과 언박싱 과정은 추가적인 메모리와 CPU 시간을 소비하므로 성능에 영향을 줄 수 있습니다. 따라서 가능하다면 원시 타입을 사용하는 것이 성능 향상에 도움이 될 수 있습니다.

4. 결론

Array<Int>는 자바의 Integer[]와 호환되며, IntArray는 자바의 int[]와 호환됩니다.

따라서 성능과 메모리 효율성이 중요한 경우 IntArray를 사용하는 것이 좋습니다. 그러나 객체 지향적인 특성이나 일반적인 배열과의 호환성이 필요한 경우 Array<Int>를 사용하는 것이 좋습니다.

이러한 차이점을 이해하면 Kotlin에서 배열을 더 효과적으로 사용할 수 있습니다. 어떤 상황에서 어떤 타입의 배열을 사용할지 결정하는 데 이 정보가 도움이 되길 바랍니다.

카테고리: Kotlin, Programming | 댓글 남기기

[BOJ 백준] 19532번 : 수학은 비대면강의입니다 – Kotlin[코틀린]

문제

자세한 문제 내용은 ‘수학은 비대면강의입니다‘를 클릭하세요.

풀이

이 문제는 브루트 포스 알고리즘을 이용하거나, 2차 방정식의 특성을 이용하여 풀 수 있습니다.

브루트 포스 알고리즘을 사용한다면, x와 y 값이 -999에서 999까지의 범위로 주어졌으므로, 모든 경우를 탐색하며 대입한 값을 확인해봅니다.

연립방정식을 사용한다면 다음의 풀이 과정을 거칩니다.

주어진 연립방정식은 다음과 같습니다.

 ax + by = c \\ dx + ey = f

가감법을 사용하여 이 연립방정식을 풀기 위해서는 먼저 한 변수를 제거해야 합니다. 이를 위해 두 방정식을 적절히 곱하여 두 방정식의 x 또는 y의 계수를 동일하게 만들 수 있습니다.

예를 들어, x의 계수를 동일하게 만들기 위해 첫 번째 방정식에 d를 곱하고, 두 번째 방정식에 a를 곱합니다.

 adx + bdy = cd \\ adx + aey = af

이제 두 방정식을 빼면 x 항이 사라집니다:

 (bdy - aey) = (cd - af)

이를 y에 대해 정리하면, 아래와 같은 식으로 정리됩니다.

 y = (cd - af) / (bd - ae)

x 또한 동일한 과정을 통해 식을 정리합니다.

테스트 코드

프로덕션 코드

브루트 포스 알고리즘 사용

연립방정식 풀이 사용

결과

제출번호 62098145가 브루트 포스 알고리즘을 사용한 코드를 제출한 결과이고, 제출번호 62098191가 연립방정식을 사용한 코드를 제출한 결과입니다. 연립방정식을 사용한 코드가 메모리 사용량이나 처리 시간에서 조금 더 좋은 성능을 보이고 있습니다.

실행 결과

카테고리: BOJ(백준) | 댓글 남기기 | 편집
카테고리: BOJ(백준) | 댓글 남기기

[BOJ 백준] 1193번 : 분수찾기 – Kotlin[코틀린]

문제

자세한 문제 내용은 ‘분수찾기‘를 클릭하세요.

풀이

주어진 문제는 무한히 큰 배열에 나열된 분수들 중에서 주어진 순서(X번째)에 해당하는 분수를 찾는 문제입니다. 주어진 순서에 따라 분수들이 지그재그 순서로 나열되어 있습니다.

문제를 해결하기 위해서는 각 분수의 위치와 값 사이의 규칙을 이해하는 것이 중요합니다. 이 문제에서는 다음과 같은 규칙을 발견할 수 있습니다:

  • 분수의 위치(row, column)를 기준으로 다음과 같이 값(numerator, denominator)을 구할 수 있습니다:
    • 분자(numerator) = row – (column – 1)
    • 분모(denominator) = column
  • 분수의 위치(row, column)을 기준으로 해당 위치까지의 분수 개수(total)를 구할 수 있습니다:
    • total = (row + column – 1) * (row + column) / 2

따라서, 주어진 순서 X에 해당하는 분수를 찾기 위해 다음과 같은 절차를 수행할 수 있습니다:

  1. 분수의 위치(row, column)를 찾기 위해, X에 해당하는 분수 개수(total)를 구합니다. 이를 위해 total 변수를 1부터 증가시키며 X보다 작거나 같은 total 값을 찾습니다.
  2. X와 total의 차이를 구하여 delta 변수에 저장합니다. (delta = X – total)
  3. delta가 홀수인 경우, 분수의 위치는 (delta + 1, column – delta)입니다. 분수의 값은 위에서 언급한 규칙에 따라 계산합니다.
  4. delta가 짝수인 경우, 분수의 위치는 (column – delta, delta + 1)입니다. 분수의 값은 위에서 언급한 규칙에 따라 계산합니다.

위의 절차를 따라 구현하면 주어진 순서 X에 해당하는 분수를 찾을 수 있습니다.

테스트 코드

프로덕션 코드

결과

실행 결과

카테고리: BOJ(백준) | 댓글 남기기

[BOJ 백준] 1934번 : 최소공배수 – Kotlin[코틀린]

문제

자세한 문제 내용은 ‘최소공배수‘를 클릭하세요.

풀이

이번 문제는 주어진 두 자연수 A, B의 최소공배수를 구하는 문제입니다. 최소공배수는 최대공약수를 통해 구할 수 있는데, 그 공식은 다음과 같습니다.

최소공배수(LCM) = (첫 번째 수 × 두 번째 수) / 최대공약수(GCD)

최소공배수는 두 수를 곱한 값에 최대공약수를 나눈 결과입니다. 이 공식은 두 수가 서로소(공약수가 1인 경우)인 경우에도 사용될 수 있습니다.

이 문제를 풀기위해서는 최대공약수를 구하는 알고리즘을 알아야 합니다. 최대공약수를 구하는 알고리즘은 여러가지가 있지만, 여기서는 유클리드 호제법을 이용해 문제를 풀어보기로 했습니다.

유클리드 호제법(Euclidean algorithm) : 최대공약수를 구하는 간결한 알고리즘

숫자 이론에서 최대공약수(GCD, Greatest Common Divisor)는 두 개 이상의 숫자의 공통된 약수 중 가장 큰 수를 의미합니다. 유클리드 호제법은 오래된 알고리즘으로, 두 숫자의 최대공약수를 효과적으로 찾는 방법을 제공합니다. 이 알고리즘은 매우 간결하며 효율적이어서 널리 사용되고 있습니다.

유클리드 호제법은 두 개의 숫자를 가지고 작업하며, 각 단계에서 나머지 연산을 사용합니다. 두 숫자를 A와 B라고 가정해봅시다. A를 B로 나눈 나머지를 R이라고 합시다. 이때, A와 B의 최대공약수는 B와 R의 최대공약수와 같습니다. 이 아이디어를 재귀적으로 적용하여 최대공약수를 찾을 수 있습니다.

다음은 유클리드 호제법의 단계를 보여주는 간단한 예시입니다. 우리는 270과 192의 최대공약수를 구하려고 합니다.

  • 270을 192로 나눕니다. 나머지는 78입니다.
  • 192를 78로 나눕니다. 나머지는 36입니다.
  • 78을 36으로 나눕니다. 나머지는 6입니다.
  • 36을 6으로 나눕니다. 나머지는 0입니다.
  • 나머지가 0이 되면, 이전 단계의 나누는 수가 최대공약수입니다. 따라서 270과 192의 최대공약수는 6입니다.

유클리드 호제법은 숫자의 크기에 관계없이 적용될 수 있으며, 계산 속도가 빠르기 때문에 널리 사용됩니다. 또한, 이 알고리즘은 다른 숫자 이론 문제에도 응용될 수 있습니다. 예를 들어, 최소공배수(LCM, Least Common Multiple)를 구하는 문제에도 사용될 수 있습니다.

테스트 코드

프로덕션 코드

결과

실행 결과

카테고리: BOJ(백준) | 댓글 남기기

[BOJ 백준] 2164번 : 카드2 – Kotlin[코틀린]

문제

자세한 문제 내용은 ‘카드2‘를 클릭하세요.

풀이

문제는 간단합니다. 큐에 1부터 n까지의 카드를 넣고, 큐에서 가장 위에 있는 카드를 버리고 그 다음 카드를 맨 뒤로 옮기는 작업을 반복합니다. 이 과정을 큐에 카드가 하나 남을 때까지 반복한 후, 남은 카드를 출력하면 정답이 됩니다.

문제 풀이에 사용될 자료구조는 선형 자료 구조 중에서도 양쪽 끝으로 데이터를 추가 혹은 삭제할 수 있는 Deque가 적합합니다. Kotlin Collection 에서는 ArrayDeque가 있기 때문에, 해당 Collection 을 이용해 문제를 풀어보기로 했습니다.

추가로, MutableList를 이용해 문제를 푸는 경우, 실제 채점 시에는 시간 초과가 발생합니다. 이는 MutableList가 기본적으로 링크드 리스트로 구현되기 때문인데요. 링크드 리스트는 각 노드들이 연결되어 있어서, 원소를 추가하거나 제거할 때마다 각 노드를 탐색하고 연결을 수정해야 합니다. 따라서 원소가 많아질수록 탐색 시간이 늘어나게 되어 실행 속도가 저하됩니다.

테스트 코드

프로덕션 코드

결과

실행 결과

카테고리: BOJ(백준) | 댓글 남기기

[Jenkins] trackingSubmodules 옵션에 관하여

사건의 발단

얼마전 부터 회사에서 관리하는 미들웨어 repository에서 일부 모듈들을 git submodule로 분리하여 관리하기 시작했습니다.

이와 대응해 Jenkins 파이프라인(Groovy 스크립트)에도 submodule과 관련된 스크립트를 추가했는데요. 최근 submodule 들이 parent repository에 커밋된 해시 코드가 아니라 최신 으로 체크아웃 받아져서 빌드되는 것을 확인되었습니다.

각 submodule에 최신으로 커밋된 수정사항들이 문제가 없어서 릴리즈에는 문제가 없었는데, 수정된 내용 중에 일부 플랫폼에는 아직 반영되면 안되는 사항들이 추가된 것을 로그 분석 중에 우연히 확인한 것이었습니다.

문재 해결

결론적으로, trackingSubmodulestrue에서 false로 변경하여 해결하였습니다.

구체적으로, 위의 코드에서 사용되는 플러그인 클래스 ‘SubmoduleOption’은 다음과 같은 옵션을 지원합니다.

  • disableSubmodules: Git 서브모듈 기능을 비활성화할지 여부를 설정합니다.
  • parentCredentials: 부모 Git 저장소의 자격 증명을 사용하여 서브모듈을 가져올지 여부를 설정합니다.
  • recursiveSubmodules: Git 서브모듈을 재귀적으로 처리할지 여부를 설정합니다.
  • reference: Git 서브모듈을 업데이트할 때 사용할 참조를 설정합니다.
  • trackingSubmodules: Git 서브모듈을 추적할지 여부를 설정합니다.
카테고리: Memo | 댓글 남기기

[Review] 넥스트스텝 교육콘서트 2기 간단 후기

교육정보

페어 프로그래밍 장점

  • OR 법칙으로 인해 50% 이상 버그가 감소 (나와 상대방이 놓치는 부분을 서로 확인)
  • 전문가들의 경험적 인지 작업을 효과적으로 배울 수 있음
  • 갈등이 드러나므로 오히려 팀워크가 향상됨
    • 페어 프로그래밍은 팀의 최소 단위(2명)이기 때문에, 갈등이 더 빨리 들어나고, 더 빨리 보완됨
  • 짝 용기가 생김

페어 프로그래밍의 도입시기는 언제가 좋을지?

  • 두렵거나, 지겹거나…
  • 페어 프로그래밍의 범위에는 문서 작성도 포함된다!

페어 프로그래밍 하는 방법

  • 역할 분리! : 내비게이터, 드라이버
    • 내비게이터 : 직접 운전대를 잡고 운전하는 역할
    • 드라이버 : 전체 지도를 보며 목적진에 다다르는 길을 안내
  • 중요한 것은 한 역할을 너무 오래하지 않고, 빈번하게 교대 (과몰입 방지)

페어 프로그래밍 시 주의할 점

  • 수평관계 유지 → 원활한 의사 소통

TDD

  • 켄트백은 2가지 모자를 동시에 쓸 수 없다고 말한다 → 기능 추가와 리팩토링을 동시에 하지 말라는 뜻
    • 노란 모자(안전모),  → Add function
    • 갈색 모자(진짜 모자) → Refactoring

리팩토링을 해야하는 순간 (마틴 파울러가 말하는 리팩토링의 순간)

  • 쓰레기 줍기 리팩토링 , Yuck! : 나쁜 코드, 코드 스멜이 나는 경우
  • 이해를 위한 리팩토링 , Comprehension : 내가 짠 코드가 아니거나 너무 오래 전에 짠 코드의 기억을 되살리는 경우
  • 준비를 위한 리팩토링, Preparatory : 기능을 쉽게 추가하도록 만들기

글쓰기를 통한 퍼스널 브랜딩

  • 처음 부터 많은 양이 길을 쓰려고 하지 말고, 점차 쓰는 양을 늘려 나가라.
  • 기술적인 얘기를 할 때, 나의 의견이 들어가는 것이 좋다. → “~을 생각해 보았다.”
카테고리: Memo | 댓글 남기기