https://yongku.tistory.com/entry/%EC%9E%90%EB%B0%94Java-Open-Associated-Perspective

 

자바(Java) Open Associated Perspective?

츄르사려고 코딩하는 코집사입니다. 자바(Java) 이클립스(Eclipse)에서 프로젝트를 생성하면 아래의 [그림1] 처럼 'Open Associated Perspective?'라는 문구가 뜬다. 자바(Java)에서의 Perspective는 무엇일까? 자

yongku.tistory.com

 

문제 잘 풀어놓고 이상한 곳에서 삽질했다

JAVA11에서 제출 시에 체크할 사항 정리해 보자

 

package problem_solve;

import java.util.Scanner;

public class Boj28701 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();
		int sum = (1+n)*n/2;
		
		System.out.println(sum);
		System.out.println(sum*sum);
		System.out.println(sum*sum);
	}
}

위는 문제 풀이 코드다

여기서 제출 전에 작업해 줄 것이 2가지 있다

 

1. package 지우기

2. class명 Main으로 수정

 

제출을 위해 수정한 코드는 아래와 같다

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		int n = sc.nextInt();
		int sum = (1+n)*n/2;
		
		System.out.println(sum);
		System.out.println(sum*sum);
		System.out.println(sum*sum);
	}
}

이진 탐색이란?

데이터가 정렬돼 있는 배열에서 특정한 값을 찾는 알고리즘이다

 

쉽게 대학생 때 술자리에서 소주 뚜껑에 쓰여있던 숫자로 했던 업다운 게임을 푸는 알고리즘이라고 생각하면 된다

 

이진 탐색은 소주 뚜껑에 1~10까지의 숫자가 쓰여있다고 가정할 때 정중앙인 5나 6을 먼저 질문하고

답이 아니라면 또다시 가능한 숫자 중에 정중앙에 있는 숫자를 질문하는 방식이다

 

이진 탐색 개념

그림으로 그려보면 아래와 같다

 

 

자, 2는 어디 있을까?

모든 숫자가 빠짐없이 나열되어 있으니 너무 당연해 보인다

그렇다면 숫자가 중간중간 빠져있다면 어떨까?

 

 

7은 어디에 있을까?

컴퓨터한테 앞에서부터 순서대로 찾으라고 시켜야 될까?

아니다 이건 너무 느리다

이진탐색을 활용해서 좀 더 빠르게 찾아보자

 

먼저 중간 지점(2개일 경우 둘 중 하나)을 먼저 확인하자

 

 

중간 지점의 값이 우리가 찾는 7인가?

그렇다면 찾은 것이고 아니라면 다음 작업을 진행한다

 

중간 지점의 값이 7보다 큰가?

크다면 왼쪽에 값 중에서 7을 다시 찾을 것이고

작다면 오른쪽에 값 중에서 7을 다시 찾을 것이다

 

이 경우엔 4<7이므로 오른쪽 값들을 보자

 

 

여기서부터 반복이다!

남아있는 값 중에서 중앙값을 다시 보자

 

 

7을 찾았나?

아니라면 7보다 큰가? 작은 가?

8>7이므로 이번엔 왼쪽을 보자

 

 

다시 반복한다!

남아있는 값 중에서 중앙값을 다시 보자

 

 

7을 찾았나?

네, 드디어 찾았다

이제 해당 값의 위치를 기억하면 된다

 

한글 코딩

이진 탐색을 실제로 코딩하기 전에 한글로 의사코딩을 해보자

 

datas = 테스트용 정수 배열 정의
findNum = 찾고 싶은 값

// 반복문을 돌며 각 영역에서 중간 값을 확인할 것이다
// 영역은 그때 그때 달라지므로 영역의 시작 위치와 마지막 위치를 알아야 한다
시작 위치, 마지막 위치 초기화
findIdx 찾은 위치를 저장할 변수
반복문 () {
    중간 위치 = (시작 위치 + 마지막 위치) / 2
    if (중간 값 == 찾는 값) {
    	찾았다!!
        findIdx = 찾은 위치
        break ;
    } else if (중간 값이 찾는 값보다 작은 경우) {	// 찾는 값이 중간 값보다 더 오른쪽에 있다
    	시작 위치 = 중간 값 + 1
    } else if (중간 값이 찾는 값보다 큰 경우) {		// else를 써도 된다
    	마지막 위치 = 중간 값 - 1;
    }
}

잘 찾았는지 출력해보기!

 

실제 코딩

package binary_search;

public class blogging01 {

	public static void main(String[] args) {

		int[] datas = {1, 2, 4, 7, 8, 10};
		int findNum = 7;
		
		int start = 0;
		int end = datas.length - 1;
		int findIdx, mid;
		
		while (true) {
			mid = (start+end)/2;
			if (datas[mid] == findNum) {
				findIdx = mid;
				break ;
			} else if (datas[mid] < findNum) {
				start = mid + 1;
			} else {
				end = mid - 1;
			}
		}
		
		System.out.printf("찾는 값: %d, 찾은 값: %d, 찾은 위치: %d\n", findNum, datas[findIdx], findIdx);
	}
}

 

잘 동작함을 확인할 수 있고

추가로 7이 없는 경우와 배열이 정렬되지 않은 경우에도 while문을 탈출할 수 있게 짜면 더 좋을 거 같다

끝!

 

for each 문을 사용하여 배열을 순회해 보자

public class Test02 {

	public static void main(String[] args) {

		int[] arr = new int[4];
		
		arr[0] = 7;
		arr[1] = 3;
		arr[2] = 9;
		arr[3] = 6;

		for (int num: arr) {
			System.out.println(num);
		}	
	}
}

 

배열에서 값을 num이란 변수로 하나씩 가져와서 루프를 돌고 있다

 

for문 대신에 for each 문을 쓰려면 값만 활용하는 상황이어야 한다

해당 값이 저장된 index나 특정 index의 값을 조회하는 건 어렵다

 

그리고 for문보다 for each 문이 성능이 좋기 때문에 간단한 코드인 경우에 더 선호될 거 같다

 

for each 문을 사용할 수 있는 자료구조는 iterable 인터페이스를 불러올 수 있어야 한다

iterable과 iterator에 대해서는 아래 블로그를 확인해 보자

 

https://coder-in-war.tistory.com/entry/Java-27-Iterable%EA%B3%BC-Iterator-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

 

[ Java ] 27. Iterable과 Iterator 인터페이스

Iterable vs Iterator 이 주제를 공부하게 된 이유는 Java로 알고리즘을 구현하면서 Iterator를 자주 사용했었는데 문득, Iterable과의 차이에 대해서 알지 못해 이번 기회에 학습하기 위해 기록을 시작한다

coder-in-war.tistory.com

 

	public static void main(String[] args) {
		int[] datas = new int[5];
		
		datas[0] = 2;
		datas[1] = 3;
		datas[2] = 1;
		datas[3] = 5;
		datas[4] = 4;
		
		int maxIndex = 0;	// 위치
		int max = 2;		// 값
		for (int i = 1; i < datas.length; i++) {
			if (max < datas[i]) {
				max=datas[i];
				maxIndex = i;
			}
		}
		System.out.printf("maxIdx: %d, maxNum: %d\n", maxIndex, max);

		
		/*
		 * maxIndex		max		i	i<5		max<datas[i]
		 * ===========================================================
		 * 0			2		1	T		T
		 * 1			3		2	T		F
		 * 						3	T		T
		 * 3			5		4	T		F
		 * 						5	F
		 * */
	}

 

위에 코드를 아래와 같이 단순화할 수 있다

`maxIndex`만 알면 최대값을 알 수 있기 때문!

 

	public static void main(String[] args) {
		int[] datas = new int[5];
		
		datas[0] = 2;
		datas[1] = 3;
		datas[2] = 1;
		datas[3] = 5;
		datas[4] = 4;
		
		int maxIndex = 0;	// 위치
		for (int i = 1; i < datas.length; i++) {
			if (datas[maxIndex] < datas[i]) {
				maxIndex = i;
			}
		}
		System.out.printf("maxIdx: %d, maxNum: %d\n", maxIndex, datas[maxIndex]);

		/*
		 * maxIndex		i		i<5		datas[maxIndex]<datas[i]
		 * ====================================================================
		 * 0			1		T		T
		 * 1			2		T		F
		 * 				3		T		T
		 * 3			4		T		F
		 * 				5		F
		 * */
		
	}

 

new는 자바의 예약어이자 연산자이다
객체를 생성할 때 사용한다

 

간단하게 new를 활용해서 int형 배열을 선언해 보자

int[] arr = new int[3];

 

int형 변수를 선언하고 초기화하는 코드와 비교해 보자

int num = 4;

 

위에 두 라인이 유사함을 알 수 있다

(자료형) (변수명) = (초기화 값);

 

다만 배열의 경우 객체이기 때문에 초기화를 위해 new 키워드를 사용해 주었다

 

 

이번에는 컴퓨터 내부에서 데이터를 메모리에 어떻게 저장하는지 살펴보자

우선 스택 메모리와 힙 메모리가 있다

(메모리에 대한 자세한 내용은 나중에 따로 포스팅해보자)

 

 

아래 코드의 경우 메모리에 다음과 같이 저장된다

int num = 4;

 

 

 

스택 메모리에 num이란 이름의 공간을 배정하고 값을 저장했다

 

new 연산자를 활용한 아래 코드는 어떻게 동작하는지 나눠서 살펴보자

int[] arr = new int[3];

 

위 코드는 우선 `new int[3]` 부분이 동작한다

힙 메모리에 공간을 배정한다

 

 

그 이후에 힙 메모리의 주소값을 스택 메모리 공간에 저장한다

 

 

그래서 arr을 그대로 출력하면 사람이 알아볼 수 없는 복잡한 주소값을 보게 된다

[문제] 다음 모양의 별을 찍어주세요!

 

*****
 ****
  ***
   **
    *

 

[코드 및 풀이] 풀이는 주석에!

package class06;

public class Test04 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		/*
		 * 3번 문제
		 * 
		 * 이 문제에서는 각 줄에서 필요한 "*"을 다 찍었다고 개행을 하고 넘어가지 않는다.
		 * " " 또는 "*"이 각 줄에서 정확하게 5번씩 나오는 특징이 있다.
		 */

		for (int a = 0; a < 5; a++) {		// 총 5줄 출력할 거다.
			for (int i = 0; i < 5; i++) {	// 각 줄에서는 " " 또는 "*"을 무조건 5번씩 출력해야 하기에 조건문은 i < 5 이다.
				if (a <= i) {				// i가 a보다 크거나 같은 경우에는 "*"을 찍고 그렇지 않으면 " "를 찍어 공백을 만든다.
					System.out.print("*");
				} else {
					System.out.print(" ");
				}
			}
			System.out.println();
		}
		
		/*
		 * 디버깅 표 
		 * 
		 * a	a<5		i	i<5		a<=i
		 * =================================
		 * 0	T		0	T		T
		 * 				1	T		T
		 * 				2	T		T
		 * 				3	T		T
		 * 				4	T		T
		 * 				5	F
		 * 1	T		0	T		F
		 * 				1	T		T
		 * 				2	T		T
		 * 				3	T		T
		 * 				4	T		T
		 * 				5	F
		 * 2	T		0	T		F
		 * 				1	T		F
		 * 				2	T		T
		 * 				3	T		T
		 * 				4	T		T
		 * 				5	F
		 * 3	T		0	T		F
		 * 				1	T		F
		 * 				2	T		F
		 * 				3	T		T
		 * 				4	T		T
		 * 				5	F
		 * 4	T		0	T		F
		 * 				1	T		F
		 * 				2	T		F
		 * 				3	T		F
		 * 				4	T		T
		 * 				5	F
		 * 5	F
		 * 
		 * */
	}

}
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner in = new Scanner(System.in);
		
		int n = in.nextInt();
		int[] v = new int[100];
		int num;
		
		for (int i = 0; i < n; i++) {
			num = in.nextInt();
			System.out.println(num);
			v[i] = num;
		}
		for (int i = 0; i < n; i++) {
			System.out.println(v[i]);
		}
		
		in.close();
	}

}
  • Scanner 및 배열 사용 숙달중..

 

https://codeup.kr/problem.php?id=1403&rid=0

 

배열 두번 출력하기

k개의 숫자를 입력받은 순서대로 한 줄에 하나씩 출력한다. 그리고 한번 출력이 다 되면 다시 한번더 출력한다.(총 2번)

codeup.kr

 

package problem_solve;

public class CodeUp1083 {
	
	/*
	 * 3 6 9 게임은?
	 * 여러 사람이 순서를 정해 순서대로 수를 부르는 게임이다.
	 * 만약 3, 6, 9 가 들어간 수를 자신이 불러야 하는 상황이면, 대신 "박수" 를 쳐야 한다.
	 * 33까지 진행했다면? "짝짝"과 같이 박수를 두 번 치는 형태도 있다.
	 * */

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		int one, ten;
		int cnt = 0;
		for (int i = 0; i < 100; i++) {
			one = i%10;
			ten = i/10;

			cnt = 0;
			if (one!=0 && one%3==0) cnt++;
			if (ten!=0 && ten%3==0) cnt++;
			if (cnt == 0) {
				System.out.println(i);
			} else if (cnt == 1) {
				System.out.println("박수");
			} else if (cnt == 2) {
				System.out.println("짝짝");
			}
		}
	}
}

 

실수 포인트!

- 1의 자리나 10의 자리가 0인 경우에 박수를 치지 않아야 한다

💡 일자별로 수업한 내용 중, 제가 모르거나 한 번 더 정리하면 좋은 내용을 모아 놓았습니다
이곳에서 키워드를 뽑아 별도로 포스팅할 예정입니다

 

🍚맛집 리스트

이거는 안 적어두면 무조건 까먹는다! 기록기록

  • 스매쉬 치즈버거 -> 치킨텐더 ㅈㅁㅌ
  • 호돌이 반점
  • 탄 -> 가성비 일식돈까스
  • 이화수 전통육개장 -> 웨이팅 적음
  • 연가 -> 가성비 한식 부페
  • 부어치킨 -> 싸다

 

많이 들어는 봤지만 한 번씩 내 손으로 정리해 보자!

  • Java -> 서버프로그래밍(JSP, Servlet) -> 웹(Spring)
  • 프론트 HTML, CSS + JavaScript
  • DB
  • 파이썬
  • 객체 지향 언어
  • 절차 지향 언어
  • 인터프리터 언어
  • 이클립스
  • 인텔리제이
  • JDK
  • 연산자 우선순위 (생소한 연산자 위주로)
  • 의사코딩, 수도 코딩

 

처음 듣는 생소한 친구들

  • 디버깅 표
  • 자바에서 static의 의미와 기능

 

내 지식과 다르거나 알쏭달쏭

  • JAVA에서는 파일도 자료형인가?

 

감으로 알던 걸 명확하게 정의된 개념

  • 무언가 반복되면, 코드 양을 줄일 수 있다는 의미다
  • 의사코딩 무조건 꼭꼭 하자!!

 

💬개발 마인드셋 강사님 띵언

주석 설명 중

신입에게 잘 만든 코드를 요구하지 않는다. 생각 있는코드를 원한다.

클라우드 환경에서 다양한 스터디를 진행할 수 있는 플랫폼 Katacoda를 이용해서 쿠버네티스를 공부하고 정리를 해보겠습니다

 

https://www.katacoda.com/contino/courses/kubernetes/pods

 

Pods | contino | Katacoda

Manage Pods, Labels and Namespaces

www.katacoda.com

 

용어정리

Pod

쿠버네티스에서 가장 작은 개념입니다. 하나 이상의 containers로 이루어져 있습니다.

 

Namespace

쿠버네티스 deployment 내부의 가상 cluster입니다. 하나의 쿠버네티스 cluster 내부에 여러 namespaces가 있을 수 있고 서로 간에 분리되어 있습니다. 특정 namespace 안에 pods를 실행함으로써, 그들은 조직화, 보안, pods의 성능으로 당신의 팀을 도울 수 있습니다.

 

namespace는 pods을 분리하여 업무량을 분산하고, 리소스 제약 조건을 설정할 수 있는 기능을 제공합니다. namespace를 고려할 수 있는 다양한 애플리케이션 환경에 매핑할 수 있습니다.

기본적으로 쿠버네티스는 몇 개의 미리 정의된 namespaces를 가지고 있습니다.

kube-system

이 namespace 안의 pods는 쿠버네티스가 작동하는데 필요합니다. 

kube-public

이 namespace는 쿠버네티스 cluster에 대한 부트스트래핑과 인증서 구성이 포함된 ConfigMap을 가지고 있습니다. 또한 이 namespace는 전체 cluster에서 보거나 읽을 수 있는 객체를 실행하는 위치로 다뤄집니다.

default

모든 객체들은 namespace를 특정하지 않으면 자동적으로 default namespace에 생성됩니다. default namespace는 삭제되지 않습니다. 

 

Label

label은 객체들에게 공급되곤 하는 key/value 쌍으로 이루어진 특성입니다. pods가 수행하는 작업을 보다 세밀하게 제어할 수 있으므로 labels을 활용하는 것이 좋습니다. label은 특정 객체를 쿼리하는데 사용할 수 있습니다.

 

Volume

volume은 데이터를 pod에 제공합니다

 

CICD 하면 빼놓을 수 없는 Jenkins를 도커로 설치해보겠습니다

Jenkins 공식 홈페이지에 가면 OS별 설치 가이드와 docker, k8s 설치 가이드를 지원합니다

 

여러 설치 방법 중 docker를 선택하면 장점은

  • 잦은 개발 서버 재부팅
  • Dockerfile, run 옵션 등으로 몇 가지 세팅 가능
  • 개발 서버에 여러 서비스가 동작하므로 환경 구분

등이 있습니다

 

Jenkins 서버 도커 설치 가이드: https://www.jenkins.io/doc/book/installing/docker/

 

Docker

If you have some experience with Docker and you wish or need to access your Docker container through a terminal/command prompt using the docker exec command, you can add an option like --name jenkins-tutorial to the docker exec command. That will access th

www.jenkins.io

 

설치 방식

Jenkins는 두 개의 docker container를 필요로 합니다

 

하나는 Jenkins 서버 컨테이너이고 나머지 하나는 dind 컨테이너입니다

dind란 "docker in docker"의 줄임말입니다

 

Jenkins는 docker image를 build 하여 DockerHub에 push를 하거나 run 하는 기능을 지원합니다

 

이 기능을 위해 Jenkins docker container 안에 docker를 설치해야 합니다

 

일반적으로 docker container 안에 docker를 설치하는 것은 권장되지 않습니다

 

하지만 Jenkins처럼 이런 상황을 필요로 하는 서비스를 위해 docker hub official image로 "dind"를 지원합니다

 

dind image: https://hub.docker.com/_/docker

 

Docker - Official Image | Docker Hub

We and third parties use cookies or similar technologies ("Cookies") as described below to collect and process personal data, such as your IP address or browser information. You can learn more about how this site uses Cookies by reading our privacy policy

hub.docker.com

설치 방법

dind image run for Jenkins

Jenkins 설치 가이드에 나온 dind 이미지를 run 하는 명령어가 나와있습니다

 

개발 서버가 재부팅될 때마다 편하게 run 하기 위해서 쉘 파일로 만들어둡시다

 

11번째 줄을 보시면 2376번 포트로 docker container 안에 docker를 사용할 수 있게 되어있습니다

잘 동작하는 것 같군요 :)

 

이제 본격적으로 Jenkins 서버를 위한 Dockerfile을 작성해봅시다

 

이것도 공식 설치 가이드에서 긁어오면 됩니다

Jenkins Dockerfile

build와 run은 각각 다음과 같이 하면 됩니다

Jenkins image build
Jenkins run

6번째 줄을 보면 dind container로부터 docker를 이용함을 확인할 수 있습니다

Jenkins build and run

잘 설치가 된 것 같으니, 브라우저로 확인해봅시다

Jenkins login 화면

사실 이 화면은 제가 한 번 설치를 끝냈었기에 뜨는 화면입니다

 

진짜 처음 설치를 하신다면 몇 가지 절차를 더 거쳐야 합니다

  • initial admin password 
  • plugin 설치
  • 초기 계정 생성

설치 가이드를 보고 차근차근 따라 하신다면 충분히 하실 수 있을 겁니다

 

ㅆㄱㄴ ㅎㅇㅌ:)

+ Recent posts