생각대로 되지는 않았고

고쳐야 하는 곳이 많지만 일단은 이렇게 올렸습니다.

버스 정원이 왜 저따구로 되는지 모르겠지만 다시 고치러 돌아오도록하겠습니다.

일단 Spring이랑 자바 강의부터 마스터하러 갑니다...

 

Transport

public class transport { //상위 클래스 대중교통

    String number; //번호
    int gas = 100; //주유량: 주어진 기본값
    int speed = 0; //속도: 주어진 기본값
    int speedChange; //속도 변경
    String status = ""; //주행 상태
    int passengerMax; //최대 승객 수
    int fee; //요금



    //getter, setter

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public int getGas(int i) {
        return gas;
    }

    public int setGas(int gas) {
        this.gas = gas;
        return gas;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getSpeedChange() {
        return speedChange;
    }

    public void setSpeedChange(int speedChange) {
        this.speedChange = speedChange;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getPassengerMax() {
        return passengerMax;
    }

    public void setPassengerMax(int passengerMax) {
        this.passengerMax = passengerMax;
    }

    public int getFee(int now2) {
        return fee;
    }

    public void setFee(int fee) {
        this.fee = fee;
    }



    //메서드

    //운행 시작
    public void start(){
        System.out.println("운행 시작");
    }

    //속도 변경
    public int changeSpeed(int change){
        this.speedChange = change;
        return change;
    }

    //상태 변경
    public String statuschange(String statusChange){
        this.status = statusChange;
        return statusChange;
    }

    //max passenger call
    public int callPassengerMax(){
        return passengerMax;
    }

    //주유 하기
    public int addgas(int addgas){
        return this.gas += addgas;

    }










}

Bus

public class Bus extends transport{

    int passengerNow=0; //현재 승객 수

    Bus() {}; //기본 생성자 선언



    //getter, setter
    public int getPassengerNow() {
        return passengerNow;
    }

    public int setPassengerNow(int passengerNow) {
        this.passengerNow = passengerNow;
        return passengerNow;
    }



    //승객 탑승 가능 여부
    public boolean boardingcheck(){
        return super.callPassengerMax() >= passengerNow;
    }

    //승객수 추가


    //승객 탑승
    //탑승가능체크도 다 따로 케이스 만들어서 해보자
    public int boarding(int passenger) {


        if ((passengerNow += passenger)<= super.callPassengerMax()){
            if (status.equals("운행중")) {

                System.out.println("승객 " + passenger + "명이 탑승하였습니다");
                System.out.println("총 탑승 승객: " + this.passengerNow + "명");
            }


        } else {
        System.out.println("정원이 초과되었습니다.");
        }
    return this.passengerNow;
    }





    // 잔여 승객 수
    public int available(int passengerNow){
        return super.callPassengerMax()-this.passengerNow;
    }

    //버스 요금
    public int busfee(int passengers){
        return this.fee = (passengers*1000);
    }




    //주유 알람
    //연료가 10이상일때 운행 가능
    boolean leftFuel() {
        return this.gas >= 10;
    }

    boolean isRunning() {

        if(!status.equals("운행중")){  //운행 종료 시 차고지행
            super.setStatus("차고지행");
        }

        if(leftFuel()) {    //운행중 연료 체크
            System.out.println("주유량이 " +this.gas + " 남았습니다." );
            return true;
        }

        if(!leftFuel()) {   //주유량이 떨어지면 차고지행
            System.out.println("주유가 필요합니다.");  //경고메세지
            super.setStatus("차고지행");
        }

        return true;
    }

    //속도 변경
    public int speedChange(int speedChange){
        if(leftFuel()){
            speed += speedChange;
        }
        System.out.println("현재 주행속도는 "+speed+"km/hr 입니다.");
        return speed;
        }











}

Taxi

public class Taxi extends transport {

    String destination="";
    int basicDistance;
    int distancetoDes;

    int basicfee =3000; //기본요금

    int passengerNow;

    Taxi() {};

    Taxi(
            String number,
            int gas,
            int speed,
            String destination,
            int basicDistance,
            int distancetoDes,
            int fee,
            int basicfee,
            int passengerMax,
            String status,
            int passengerNow

    ){
        this.number =number;
        this.gas = 100;
        this.speed = 0;
        this.destination = destination;
        this.basicDistance =1000;
        this.distancetoDes = distancetoDes;
        this.fee = 1000;
        this.basicfee = basicfee;
        this.status = "일반";
        this.passengerMax = 4;
        this.passengerNow = passengerNow;

    }

    //getter setter


    public String getDestination() {
        return destination;
    }

    public void setDestination(String destination) {
        this.destination = destination;
    }

    public int getBasicDistance() {
        return basicDistance;
    }

    public void setBasicDistance(int basicDistance) {
        this.basicDistance = basicDistance;
    }

    public int getDistancetoDes() {
        return distancetoDes;
    }

    public void setDistancetoDes(int distancetoDes) {
        this.distancetoDes = distancetoDes;
    }

    public int getBasicfee() {
        return basicfee;
    }

    public void setBasicfee(int basicfee) {
        this.basicfee = basicfee;
    }

    public int getPassengerNow() {
        return passengerNow;
    }

    public void setPassengerNow(int passengerNow) {
        this.passengerNow = passengerNow;
    }



    //메서드

    //택시 요금 계산
    public int finalFee(int distancetoDes){
        int finalFee = basicfee+fee*(distancetoDes-basicDistance);
        System.out.println("최종 요금은 "+finalFee+"입니다.");
        return finalFee;
    }

    //탑승 가능 여부
    public boolean boardingcheck(){
        return passengerNow==0;
    }

    //승객수 추가
    public int addPassenger(int addPassenger){
        this.passengerNow += addPassenger;
        return this.passengerNow;
    }

    //승객 탑승
    public int boarding(int passenger){
        while(boardingcheck()){
            if(status.equals("운행")){
                System.out.println("승객"+addPassenger(passenger)+"명이 탑승하였습니다");
                System.out.println("총 탑승승객: "+passengerNow+"명");
                super.setStatus("운행 중");
            }
            break;
        }
        if(!boardingcheck()){
            int overPassenger = (addPassenger(passenger)+passengerNow)-passengerMax;
            System.out.println(overPassenger+"명 초과");
            System.out.println("탑승 불가");
            super.setStatus("탑승 불가");
        }
        return passengerNow;
    }

}

Operation

import java.util.Scanner;

public class Operation {
    public static void main(String[] args) {


        Scanner scanner = new Scanner(System.in);

        System.out.println("이동수단을 선택해주세요.");
        System.out.println("1. 택시 타기");
        System.out.println("2. 버스 타기");
        System.out.print("선택 >>");

        int option =0;
        option = scanner.nextInt();


        while(true){

            if(option==2){

                Bus bus1 = new Bus(); //새로운 버스 1
                bus1.setNumber("항해99");
                String bus1Number = bus1.getNumber();

                Bus bus2 = new Bus(); //새로운 버스 2
                bus2.setNumber("헤엘666");
                String bus2Number = bus2.getNumber();

                System.out.println("버스 2대 중 선택해주세요.");
                System.out.println("1. 항해99");
                System.out.println("2. 헤엘666");

                int option2 =0;
                option2 = scanner.nextInt();



                if(option2==1){
                        int passnum1 = bus1.getPassengerNow();
                        bus1.setPassengerMax(30);
                        bus1.setStatus("운행중");
                        int pass1 = 2;
                        bus1.boarding(pass1);
                        int passengerNow = bus1.getPassengerNow();
                        System.out.println("잔여 승객 수는 "+ bus1.available(pass1)+"명 입니다.");

                        int busfee1 = bus1.busfee(pass1);
                        System.out.println("버스 요금은 "+busfee1+"원 입니다.");
                    System.out.println();
                    System.out.println();

                    System.out.println("버스 기사가 주유량을 체크합니다.");

                    int gas1 = bus1.setGas(50);
                    bus1.isRunning();

                    System.out.println("버스 기사가 차고지로 향합니다.");
                    bus1.statuschange("차고지행");
                    System.out.println();
                    System.out.println("-----차고지-----");
                    int addgas1 = bus1.addgas(10);
                    System.out.println("주유량이 "+ addgas1+ "로 변했습니다.");

                    bus1.statuschange("운행중");
                    System.out.println();
                    System.out.println("다음 정류장에 도착했습니다.");
                    int pass2 = 45;

                    bus1.boarding(pass2);

                    System.out.println("정원초과여서 정류장을 지나칩니다.");
                    System.out.println();
                    System.out.println("다음 정류장에 도착했습니다.");

                    int pass3 = 5;
                    bus1.boarding(pass3);

                    int now2 = bus1.getPassengerNow();
                    System.out.println(now2);

                    System.out.println("잔여 승객 수는 "+ bus1.available(now2)+"명 입니다.");

                    int busfee2 = bus1.busfee(pass3);

                    System.out.println("버스 요금은 "+busfee2+"원 입니다.");

                    int minusgas = bus1.addgas(-55);
                    System.out.println("주유량이 " + minusgas + "로 변했습니다.");
                    bus1.isRunning();
                    System.out.println(bus1.getStatus());









                    }
                }


            break;

            }


        }


    }

문제1. 윷놀이

우리나라 고유의 윷놀이는 네 개의 윷짝을 던져서 배(0)와 등(1)이 나오는 숫자를 세어 도, 개, 걸, 윷, 모를 결정합니다. 네 개 윷짝을 던져서 나온 각 윷짝의 배 혹은 등 정보가 주어질 때 도(배 1개, 등 3개), 개(배 2개, 등 2개), 걸(배 3개, 등 1개), 윷(배 4개), 모(등 4개) 중 어떤 것인지를 결정하는 프로그램을 작성하세요.

문제 풀이

[0,0,1,0] 0의 개수에 따라서 도,개,걸,윷,모 가 정해집니다.

0의 개수를 세서 각각의 경우의 수를 만들어주었습니다.

 

보자마자 쉽다는 생각이 드는 문제였습니다.

public class yutNori {
    public String solution(int[] arr1) {
       
        //0(배)의 개수에 따라서 정해진다. 도, 개 , 걸, 윷, 모

        String answer = "";
        int bae =0;

        for(int i=0; i<arr1.length; i++){
            if (arr1[i]==0){
                bae++;
            }

        if(bae==0){
             answer = "모";
        }
        if(bae==1){
            answer = "도";
        }
        if(bae==2){
            answer = "개";
        }

        if(bae==3){
            answer = "걸";
            }

        if(bae==4){
            answer = "윷";
            }

        }

        return answer;

    }

    public static void main(String[] args) {
    yutNori method = new yutNori();
    int[] s = {1,0,0,0};
        System.out.println(method.solution(s));




    }
}

 

문제2. Triangular Output aka. 피라미드 별찍기

피라미드 별찍기

위처럼 입력 값(int)에 따라 피라미드 모형을 별을 찍는 것을 구현합니다.

 

문제 풀이

1. 한 줄에 찍힌 별의 개수가 홀수 인 것을 알 수 있습니다.

2. 2*i+1 개씩 한 줄에 찍힙니다. 

3. for문을 이용해서 앞에 빈칸과 *을 찍어줍니다.

 

public class TriangularOutput {

        public void solution(int star) {
            //star는 피라미드의 층수
            //for문을 사용해서 *입력
            //2의배수에 +1 값이 한층당 *의 수
            //앞의 빈 칸만 만들어 주면 됨

            for (int i = 0; i <star ; i++) {

                for(int blank =1; blank<star-i; blank++) {
                    System.out.print(" "); //빈 칸 출력
                }

                for(int stars =0; stars<2*i+1; stars++){
                    System.out.print("*"); //* 출력; 별의 개수는 홀수
                }

                System.out.println(); //층 바꾸기
            }

        }

        public static void main(String[] args) {
            TriangularOutput method = new TriangularOutput();
            int star = 9;
            method.solution(star);
        }
    }

빈칸의 개수는 층수(i) -1 이고, 별의 개수는 층수(i) *2 +1 입니다.

 

반복문을 돌리면 피라미드가 완성됩니다.

 

 

문제3. 상하좌우 큰 수 찾기

5x5 2차원 배열이 주어질 때 어떤 원소가 상하좌우에 있는 원소보다 클 때 해당 위치에 * 을 표시하는 프로그램을 작성하세요. 경계선에 있는 수는 상하좌우 중 존재하는 원소만을 비교합니다.

 

문제 풀이

i'll get back to this

오늘 오전에 언어 스터디를 했는데 조원분이 너무 멋진 객체지향 예제(보러가보세요!)를 보여주셔서 자극을 받아 바로 만들어 봅니다. 저는 식당 메뉴 별로 가격을 정하고 판매량 입력 후 매출 정산하는 프로그램을 만들어 보려고 합니다.

 

객체지향 예제

필드 선언

public class restaurantRevenue {
    //필드 선언
    private int price;
    private int revenue;
    private String menu;

    private int sold;

    //기본 생성자

    restaurantRevenue () {}



    //매개변수를 가진 생성자
    public restaurantRevenue(String menu, int price, int sold, int revenue) {
        this.menu = menu;
        this.price = price;
        this.sold = sold;
        this.revenue = revenue;
    }

    // getter setter 단축키 cmmd + N
    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public int getRevenue() {
        return revenue;
    }

    public void setRevenue(int revenue) {
        this.revenue = revenue;
    }

    public int getSold() {
        return sold;
    }

    public void setSold(int sold) {
        this.sold = sold;
    }

    public String getMenu() {
        return menu;
    }

    public void setMenu(String menu) {
        this.menu = menu;
    }
}

 

 

메뉴 입력 프로그램 만들기

import java.util.Scanner;

public class revenueExample {
    private Scanner scanner = new Scanner(System.in);

    private restaurantRevenue newMenu = null; //새 메뉴가 저장될 객체

    public revenueExample (){}; //기본 생성자

    public void display() { //메뉴화면 메소드

        int option = 0;

        do {
            System.out.println("=====*메뉴입력하기*=====");
            System.out.println("1. 메뉴입력");
            System.out.println("2. 판매량입력");
            System.out.println("3. 매출보기");
            System.out.println("0. 종료하기");
            System.out.print("선택>>");



            option = scanner.nextInt();

            switch (option) {
                case 1:
                    System.out.println(entermenu());
                    break;
                case 2:
                    System.out.println(sold());
                    break;
                case 3:
                    System.out.println(revenue());
                    break;
                case 0:
                    System.out.println("프로그램 종료!");
                    break;
                default:
                    System.out.println("다시 입력해주세요 -_-^");
            }


        }


        while (option != 0);
    }
    public String entermenu(){ //메뉴입력하기
        System.out.println("=====메뉴입력=====");
        System.out.print("메뉴명> ");
        String menu = scanner.next();
        System.out.print("가격> ");
        int price = scanner.nextInt();

        newMenu = new restaurantRevenue(menu, price,0,0);

        return "메뉴명:"+menu+" 가격: "+price+"원";
    }

    public String sold(){
        System.out.println("=====판매량입력=====");
        System.out.print("메뉴명> ");
        String menu = scanner.next();
        System.out.print("판매량> ");
        int sold = scanner.nextInt();

        if(menu.equals((newMenu.getMenu()))){
            newMenu = new restaurantRevenue(menu, newMenu.getPrice(), sold, sold* newMenu.getPrice());
            return "메뉴명: "+ menu + " 판매량: "+sold;
        }else {
            return "메뉴정보가 없습니다.";
        }


    }

    public String revenue(){
        System.out.println("=====매출보기=====");
        System.out.print("메뉴명> ");
        String menu = scanner.next();

        if(menu.equals((newMenu.getMenu()))) {
            return "메뉴명 " + menu + " 매출: " + newMenu.getRevenue();
        } else{
            return "메뉴정보가 없습니다.";
        }

    }

    public static void main(String[] args) {
        revenueExample revenue = new revenueExample();
        revenue.display();
    }

}


 

 

결과

=====*메뉴입력하기*=====
1. 메뉴입력
2. 판매량입력
3. 매출보기
0. 종료하기
선택>>1
=====메뉴입력=====
메뉴명> pasta
가격> 25000
메뉴명:pasta 가격: 25000원
=====*메뉴입력하기*=====
1. 메뉴입력
2. 판매량입력
3. 매출보기
0. 종료하기
선택>>2
=====판매량입력=====
메뉴명> pasta
판매량> 12
메뉴명: pasta 판매량: 12
=====*메뉴입력하기*=====
1. 메뉴입력
2. 판매량입력
3. 매출보기
0. 종료하기
선택>>3
=====매출보기=====
메뉴명> pasta
메뉴명 pasta 매출: 300000
=====*메뉴입력하기*=====
1. 메뉴입력
2. 판매량입력
3. 매출보기
0. 종료하기
선택>>2
=====판매량입력=====
메뉴명> rice
판매량> 40
메뉴정보가 없습니다.
=====*메뉴입력하기*=====
1. 메뉴입력
2. 판매량입력
3. 매출보기
0. 종료하기
선택>>3
=====매출보기=====
메뉴명> risotto
메뉴정보가 없습니다.
=====*메뉴입력하기*=====
1. 메뉴입력
2. 판매량입력
3. 매출보기
0. 종료하기
선택>>0
프로그램 종료!

Process finished with exit code 0

 

매우 간단하지만 굿 실습이었습니다.

문제1.

기원이는 오늘 항해99를 시작했다. 성격이 급한 기원이는 항해 1일 차부터 언제 수료를 하게될 지 궁금하다. 항해 1일 차 날짜를 입력하면 98일 이후 항해를 수료하게 되는 날짜를 계산해주는 알고리즘을 만들어보자.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Main {
    public String solution(int month, int day) {
        String answer = "";
        LocalDate date = LocalDate.of(2022, month, day);
        LocalDate newDate = date.plusDays(98);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M월 dd일");
        answer = dateTimeFormatter.format(newDate);
        
        return answer;
    }

    public static void main(String[] args) {
        Main method = new Main();
        System.out.println(method.solution(1, 18));
    }

java.time.LocalDate 와 

java.time.format.DateTimeFormatter 를 import하면 쉽게 풀 수 있는 문제였습니다.

 

.plusDay() 메소드를 이용하여 날짜를 더합니다.

 

DateTimeFormatter.ofPattern()을 사용해서 "M월 dd일" 형식으로 출력합니다.

 

 

문제2.

지용이는 항해에서 한 주 동안 공부 기록을 남길 알고리즘을 만들어보기로 결심했다. 항해의 체크인 페이지에는 몇가지 조건이 있는데 이를 만족하는 알고리즘을 만들어보자.
체크인과 체크아웃은 항상 정시에 진행한 것으로 가정한다.
체크아웃을 할 때 익일 시간은 24+a 로 계산한다.
즉 새벽 2시는 24+2 인 26으로 표기한다.
체크인 페이지는 체크아웃이 새벽 5시 정각이나 새벽 5시를 넘어가면 체크아웃을 깜빡한 것으로 간주한다.
따라서 새벽 5시가 넘어가 체크아웃을 하게 되면 자동으로 체크아웃을 오후 9시(21시)로 한 것으로 처리한다.
public class Main {
    public int solution(int[] arr1, int[] arr2) {
        int answer = 0;
        for(int i=0; i<arr2.length; i++){
            if( arr2[i]>=29){
                answer += 21-arr1[i];
            }else {
                answer += arr2[i] -arr1[i];
            }
        }

        return answer;
    }

    public static void main(String[] args) {
        Main method = new Main();
        int[] arr1 = {9, 9, 9, 9, 7, 9, 8};
        int[] arr2 = {23, 23, 30, 28, 30, 23, 23};
        System.out.println(method.solution(arr1, arr2));
    }
}

 

문제3.

문자열 s에는 공백으로 구분된 숫자들이 저장되어 있습니다. str에 나타나는 숫자 중 소수의 최대값과 소수가 아닌 수의 최소값을 찾아 이를 "(최소값) (최대값)"형태의 문자열을 반환하는 함수, solution을 완성하세요.

예를들어 s가 "2 3 4 5"라면 "4 5"를 리턴하고, "15 3 10 9 7 8"라면 "8 7"을 리턴하면 됩니다.

소수 찾기가 어렵습니다... 매니저님 오시면 여쭤봐야겠음..

여쭤봤습니다...

 

import java.util.concurrent.LinkedTransferQueue;

public class primeNumbers {

    public String solution(String s) {
        String answer = "";
        //1은 소수가 아니다
        //2를 제외한 짝수도 소수가 아니다.
        //제곱근(sqrt) 범위 나누기법이란?
        //소수 여부를 검사할 수에 대해서 그 값의 제곱근을 기준으로 그 곱은 대칭적으로 곱이 일어나므로 
        //제곱근 이하의 작은 값까지만 검사를 하면 나머지는 검사를 할 필요가 없다는 방법으로 검사할 데이터를 제곱근 개 이하로 줄 일 수 있는 방법

        //소수 중 최대값
        //소수가 아닌 수 중 최소값 

        int primeMax = 0;
        int nonPrimeMin = Integer.MAX_VALUE;

        String[] numbers = s.split(" "); //

        for (String number : numbers) {
            int num = Integer.parseInt(number);
            if (numbercheck(num)) {
                if (num > primeMax) {
                    primeMax = num;
                }
            } else {
                if (num < nonPrimeMin) {
                    nonPrimeMin = num;
                }
            }
        }
        return nonPrimeMin + " " + primeMax;
    }

    private boolean numbercheck(int num) {
        //1이하는 소수가 아님
        if (num <= 1)
            return false;
        //2는 소수지만 2로 나누어지는 수는 소수가 아님
        if (num % 2 == 0)
            return num == 2;

        //3부터 소수 검사; 제곱근 이하의 수로 나누어지면 소수
        for (int i = 3; i < Math.sqrt(num); i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }


    public static void main(String[] args) {
        primeNumbers method = new primeNumbers();
        String s = "97 75 88 99 95 92 73";
        System.out.println(method.solution(s));
    }
}

 

13. 2016년

2016년의 날짜를 입력하면 요일을 출력하기

 

public class year_2016 {
    public static void main(String[] args) {
        int a = 0;
        int b = 0;
        String answer = "";
        String[] day = {"FRI","SAT","SUN","MON","TUE","WED","THU"};
        int[] date = {31,29,31,30,31,30,31,31,30,31,30,31};
        int select = 0;

        for(int i = 0; i < a-1; i++){
            select += date[i];
        }
        select += b - 1;

        answer = day[select % 7];
        
        System.out.println(answer);
    }
}

위에는 클래스를 따로 Import 하지 않고 풀었을 때의 풀이입니다.

2016년 개별 월의 마지막 날짜를 구해서 해당 날짜만큼을 8일

import java.time.LocalDate;
import java.util.Scanner;

public class year_2016 {
    public static void main(String[] args) {
        int a = 0;
        int b = 0;
        Scanner scanner = new Scanner(System.in);
        a = scanner.nextInt();
        b = scanner.nextInt();
        String answer = "";
        LocalDate date = LocalDate.of(2016, a,b);
        System.out.println(date); // 2016-5-24
        answer = date.getDayOfWeek().toString(); //요일은 String 타입으로 변환해야한다.
        System.out.println(answer); // TUESDAY
        System.out.println(answer.substring(0,3)); //.substring 메서드 사용해서 앞 3글자만 출력
    }
}

 

LocalDate.of() 메서드를 사용하면 쉽게 날짜를 구할 수 있습니다.

사용하기 위해서

 

import java.time.LocalDate;

 

LocalDate.of(year, month, day)

 

.getDayOfWeek() 메서드를 사용하면 요일을 구할 수 있습니다.

 

단, String 타입으로 변환을 해줘야 합니다.

 

.toString() 을 사용하거나 

String.valueOf() 를 사용해서 타입 변환을 해줍니다.

 

 

 

14. 나중에 떨어지는 숫자 배열

1. 배열의 길이를 구해서 조건값 찾기

2. 각 인덱스를 divisor 나눈 나머지 값 구하기 %divisor

3. 한번 길이를 정한 배열은 변경할 수 없기 때문에... 나머지가 0인 index의 수를 세기 count++

4. count 길이만큼의 배열 만들기 answer []

5. 나머지가 0이면 해당 Index값을 반환한 값을 answer [] 에 넣기

6. if else %divisor !=0 인 경우 count []에 -1 을 담기

7. 오름차순으로 배열하기 Arrays.sort 사용하기

 

import java.util.Arrays;

public class numberArray {
    class Solution {
        public int[] solution(int[] arr, int divisor) {
            int count =0;

            for(int i =0; i<arr.length; i++){
                if(arr[i]%divisor==0){
                   count++;
                }
            }
            int[] answer = new int[count];
            count=0;                        //count 값 초기화 (변수명 바꿔도 상관x)
            for (int i=0; i<arr.length; i++){
                if(arr[i]%divisor==0){
                    answer[count] = arr[i]; //answer index [0]번째부터 값 넣어주기
                    count++;
                }
            }
            if(answer.length==0){
                answer = new int[1];
                answer[0] =-1;
            }

            Arrays.sort(answer);
            return answer;
        }

    }
}

 

 

 

15. 내적

1. for 문 이용해서 풀면 간단하다.

public class naejuk {
    public static void main(String[] args) {
        int answer = 0;
        int[] a ={1,2,3,4};
        int[] b ={-3,-1,0,2};
        for(int i=0; i<a.length; i++){
                answer +=(a[i]*b[i]); //()괄호를 해줘야 answer에 곱한 값이 들어간다.
            }
        System.out.println(answer);
        }

    }

 

16. 문자 내 p와 y의 개수

1. 문자열을 배열로 전환한다. char[] toCharArray(): 문자열을 문자배열로 변환해서 반환을 사용해본다.

2. p 또는 P의 개수(int p)와 y또는 Y의 개수(int y)를 센다.

3. 두 값이 같으면 true를 리턴한다. 아니면 false를 리턴한다.

import java.util.Arrays;
import java.util.Scanner;

public class py {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        int p =0;
        int y =0;
        char[] arr = s.toCharArray();
        System.out.println(Arrays.toString(arr));
        for(int i=0; i<arr.length; i++){
            if(arr[i]=='p'|| arr[i]=='P'){
                p++;
            }
        }
        System.out.println(p);
        for(int i=0; i<arr.length; i++){
            if(arr[i]=='y'|| arr[i]=='Y'){
                y++;
            }
        }
        System.out.println(y);
        boolean answer = true;
        if(p==y){
            answer = true;
        }else{
            answer = false;
        }
        System.out.println(answer);
    }
}

 

소문자와 대문자를 || 로 넣었는데 그냥 처음부터 

 

.toUpperCase()를 써서 굳이 || 를 안쓰게 할 수도 있었습니다.

 

.filter() 메서드라는 게 있네요. 아래는 좋아요를 가장 많은 풀이 입니다.

class Solution {
    boolean solution(String s) {
        s = s.toUpperCase();

        return s.chars().filter( e -> 'P'== e).count() == s.chars().filter( e -> 'Y'== e).count();
    }
}

 

 

17. 문자열 다루기 기본

1. 길이 확인하기: s.length !=4 && s.length !=6 이면 false return

3. 문자인지 아닌지 확인하기 .charAt()과 for 문 사용하기   

 

import java.util.Scanner;

public class stringControl {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        boolean answer = true;
        if(s.length() !=4 && s.length() !=6){
            answer = false; //길이가 4와 6이 아니면 false
        }
        for(int i=0; i<s.length(); i++){
            if(s.charAt(i)<'0'|| s.charAt(i)>'9'){ //0보다 작거나 9보다 크면 false; char 이기 때문에 문자로 비교
                answer = false;
            }
        }
        System.out.println(answer);
    }
}

 

생각보다 쉽게 풀어졌는데 프로그래머스에 제출 코드는 조금 변형했습니다.

s.length를 에러로 인식해서 새로 변수를 선언했습니다.

그리고 && 대신 || 를 사용해봤습니다.

 

class Solution {
    public boolean solution(String s) {
        boolean answer = false;
        int length = s.length();
        if(length==4 || length==6){
            answer = true;
        }
        for(int i=0; i<length; i++){
            if(s.charAt(i)<'0'|| s.charAt(i)>'9'){
                answer=false;
            }
        }
        return answer;
    }
}

 

가장 좋아요를 많이 받은 풀이는 try, catch 문을 사용했습니다. 아직 안배운 부분이라 생각치 못했네요.

 

class Solution {
  public boolean solution(String s) {
      if(s.length() == 4 || s.length() == 6){
          try{
              int x = Integer.parseInt(s);
              return true;
          } catch(NumberFormatException e){
              return false;
          }
      }
      else return false;
  }
}

 

 

18. 서울에서 김서방 찾기

1. kim 값을 찾는다. if문 사용 seoul[i].equals("kim"), System.out.println(i);

2. 해당 Index가 몇번째인지 알아내기 

class Solution {
    public String solution(String[] seoul) {
        String answer = "";
        int length = seoul.length;
        for(int i =0;i<length; i++){
            if(seoul[i].equals("Kim")){
                answer = "김서방은 "+i+"에 있다";
            }
        }
    
        return answer;
    }
}

- 대문자 소문자 확인하기

- String 비교 할 때는 .equals() 메소드 사용하기

 

Arrays.asList().indexOf();

가장 좋아요를 많이 받은 풀이 입니다.

Arrays.asList() : Array를 List처럼 사용할 수 있게 해주는 클래스 

.indexOf() 메소드를 사용했습니다.

이번주 월요일에 정식으로 부트캠프를 시작했고 벌써 첫번째 주의 마지막날이 되었습니다. 월요일에는 아무것도 모르는 백지상태에 가까웠다면, 이제는 JWT를 이용해서 회원가입, 로그인, 로그아웃을 구현할줄 알게 되었고, Github을 이용해서 팀 프로젝트를 완성했습니다. Rest API 형식을 따라서 API 설계도 해보고 MongoDB를 이용해서 DB 설계도 경험했습니다. flask의 Blueprint를 사용해서 효율적으로 분업을 했고 후에 merge할 때 충돌이 한번도 발생하지 않았습니다. 

항해99 1주차 회고

JWT를 활용한 로그인, 로그아웃, 회원가입 구현

  • JWT을 사용하는 이유
    • 쿠키를 받아 토큰을 발급해서 로그인 정보 확인
    • 쿠키는 브라우저에만 존재
    • 같은 도메인이면 쿠키가 유지됨
    • 로그아웃 하려면 쿠키 삭제하면 됨
    • 보안상 더 낫다고 함
  • Hash 함수 사용 이유
    • 비밀번호의 암호화
    • Sha 256, Sha 512 를 많이 사용함
  • unix time: 1970년 1월 1일로부터 몇 초 지났는지

TIL 221114

 

TIL 부트캠프 정식 시작 JWT 로그인 구현하기 221114

드디어 오늘이 항해99 부트캠프 정식 시작일입니다. 지난주는 pre-onboarding 기간으로 주특기 언어인 Java를 공부하는 시간을 가졌습니다. 오늘부터 새로 배정된 조에서 미니 프로젝트를 진행합니다

pizzathedeveloper.tistory.com

 

아이디 중복확인

function id_overlap_check() {
    let userid = $('#user_id').val()
    if (userid == '') {
        alert('아이디를 입력해주세요.'); //공백인 경우
    } else {
        $.ajax({
            type: "GET",
            url: "/join/check?user_id=" + userid, //get 할 때 url은 "/url"+찾는값
            data: {},
            success: function (response) {
                alert(response['message']);
                if (response['success'] == false) {
                    let input = document.getElementById("user_id");
                    input.value = null; //input 값 없앰
                } else{$('.user_id').attr("check_result", "success");
                    $('.id_overlap_button').hide(); //중복확인버튼 없앰
                         }
                }
        });
    }
}

 

중복확인 필수로 하지 않으면 회원 가입이 되지 않게 만들기

 

.attr () 메소드를 이용해서 확인 되면 =="success" 로 변경이 되게 구현했습니다.

function join() {
    if ($('.user_id').attr("check_result") == "fail") {
        alert("아이디 중복체크를 해주시기 바랍니다.") //중복체크가 안되어 있을 때
    }
    else if ($('.name_input').val() == '') {
        alert("닉네임을 입력해주시기 바랍니다."); //닉네임 input 이 없을때
        $('.user_name').focus();
    } else if ($('.pw_input').val() == '') {
        alert('비밀번호를 입력해주세요.')
        $('.user_pw').focus(); //pw input이 공백인 경우
    } else {
        $.ajax({
            type: "POST",
            url: "/join/join",
            data: {
                id_give: $('#user_id').val(),
                pw_give: $('#user_pw').val(),
                name_give: $('#user_name').val()
            },
            success: function (response) {
                if (response['result'] == 'success') {
                    alert('회원가입이 완료되었습니다.')
                    window.location.href = '/login'
                } else {
                    alert('다시 시도하세요.')
                }
            }
        })
    }}
 

TIL 221116

 

TIL Merge 하고 다시 작업하기 아이디 중복확인 기능 로그인 JWT token 221116

오늘은 아침에 일어나는 게 너무 힘들었는데 막상 또 일어나서 컴퓨터 앞에 앉으니까 열정이 샘솟았습니다. 제가 어제 걱정하고 씨름했던 오류가 말끔히 해결이 되었거든요. 껐다 켰다는 진리

pizzathedeveloper.tistory.com

 

로그아웃 기능 구현하기

JWT 를 브라우저에서 지워주면 됩니다.

토큰은 클라이언트에서 저장하기 때문입니다.

jquery를 사용했습니다.

 

$.removeCookie('쿠키이름');

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.js"></script> //필요한 페이지에 이거 복붙해주세요.
    <title>logout</title>
    <script>
        function logout(){
        $.removeCookie('mytoken');
        alert('로그아웃!')
        window.location.href='/login'
      } //로그아웃 버튼 만들어서 붙이시면 됩니다
    </script>
</head>
<body>

<button onclick="logout()">로그아웃 하기</button>
</body>
</html>

 

미니프로젝트 '제2의 항해 매니저' github

https://github.com/sooni2/HanghaeManager

 

GitHub - sooni2/HanghaeManager

Contribute to sooni2/HanghaeManager development by creating an account on GitHub.

github.com

제 리포지토리에 올린 첫 프로젝트입니다.

뛰어난 조원분들과 함께해서 제가 기여한 부분이 메인은 아니지만 나름 맡은 역할을 다 했습니다.

제가 기획한 프로젝트가 채택되어서 기획쪽도 재미가 있다고 생각했습니다.

늘 저는 아이디어는 많습니다.

 

 

첫 코드리뷰를 진행하다

오늘은 함께 첫 프로젝트를 진행한 조원들과 함께 코드리뷰를 진행했습니다. 

 

- 백에서 할수 있는 것은 최대한 백에서 처리하기

- API 설계를 아는 것이 중요하다

- 이번 프로젝트에는 Rest API 를 사용했음

- DB 설계에 맞춰 API 설계하기

 

저는 이번주에 시작한 완전 초짜지만 먼저 시작한 선배님들의 조언과 여러 피드백을 들으면서 월요일보다 성장한 것 같습니다. 함께한 조원분들이 성격도 좋고 개발도 잘해서 다행이었던 프로젝트였습니다. 

 

다음 주에는...

이제는 자바스크립트를 뒤로 하고 자바에 집중하는 한주가 될 예정입니다. 오늘은 남궁성 자바의 정석 ch 5까지 들었습니다. 프로그래머스 알고리즘 문제를 지난 이틀간 풀었는데 아무래도 자바 기초가 부족하다 보니 간단한 문제도 방법을 몰라서 푸는 경우가 많았습니다. 문제 푸는 로직은 어느정도 이해는 갑니다. 더 많은 메소드를 알게 되면 알고리즘 문제 풀이가 좀 더 수월할 것 같습니다. 

 

시그마로 푸는 문제가 하나 있었는데 언제 이걸 봤었지 했는데 고등학생인가 대학생때 통계학에서 배운 기억이 났습니다. 알고리즘 주차에 걷기반을 선택해서 28 문제를 푸는 것이 학습 목표인데 좀더 욕심을 내서 달리기 반의 문제 10개까지 추가를 해서 풀어보도록 하겠습니다.

 

 

7. 음양 더하기

 

class Solution {
    public int solution(int[] absolutes, boolean[] signs) {
        int answer = 0;
        for(int i=0;i<absolutes.length;i++){
            if(signs[i]==true){
                answer += absolutes[i];
            }else{
                answer -= absolutes[i];
            }
        }
        return answer;
    }
}

삼항연산자를 연습해야겠습니다.

 

 

8.  평균 구하기

class Solution {
    public double solution(int[] arr) {
        double answer = 0;
        for(int i=0; i<arr.length; i++){
            answer += arr[i];
        }
        answer /= arr.length;
        return answer;
    }
}

평균 구하기는 쉬웠습니다.

 

 

9.  핸드폰번호가리기

1. 전체 번호 길이에서 마지막 숫자 네 개를 뺀 부분에 *찍기하려면 길이를 구한다.

2. .length() 메소드를 사용해서 길이를 구한디 -4를 한다.

3. length-4만큼 별을 찍는다.

4. 뒤의 숫자는 .substring() 메소드를 이용해서 .substring(length-4)로 마지막 네자리 숫자를 찍어준다.

public class Ex2_1 {
    public static void main(String[] args) {
       Scanner scanner = new Scanner(System.in);
       String phone_number = scanner.nextLine();
       int length = phone_number.length();
       String answer = "";
       for(int star =0; star<length-4; star++){
           answer += "*";
       }
       answer += phone_number.substring(length-4);
        System.out.println(answer);

    }
}

.substring이란 걸 어제푼 문제에서 배워서 대입을 해봤습니다.

그랬더니...

 

.toCharArray() 메소드란것이 있습니다.

String.valueOf() 

 

10. 행렬의 덧셈

어제부터 약간 뇌가 멍해서

 

 

11. x만큼 간격이 있는 n개의 숫자

x부터 시작해서 x씩 증가하는 숫자를 n개 지니는 리스트를 리턴하라

1. x, x(n), x(n^2), ... , x(n^n-1) 을 리스트로 만들어야 한다.

2. for 문을 사용해서 정의하면 되려나

 

class Solution {
    public long[] solution(int x, int n) {
        long[] answer = new long[n];
        for(int i=0; i<answer.length; i++){
            answer[i] = (long)x * (i+1);
        }
        return answer;
    }
}

위는 프로그래머스에 제출한 코드이고 인텔리제이로는 아래처럼 작성했습니다.

public class xnincrease {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int x = scanner.nextInt();
        int n = scanner.nextInt();

        long[] answer = new long[n];
        for(int i=0; i<answer.length; i++){
         answer[i] =  x * (i+1);
        }
		System.out.println(answer);
    }
}

그랬던이 결과값이 이상하게 나오길래 array 전체 배열의 값을 출력하는 방법을 알아보았습니다.

뭐야이게

import java.util.Arrays; //import하기
import java.util.Scanner;

public class xnincrease {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int x = scanner.nextInt();
        int n = scanner.nextInt();

        long[] answer = new long[n];
        for(int i=0; i<answer.length; i++){
         answer[i] =  x * (i+1);
        }
        System.out.println(Arrays.toString(answer)); //Arrays.toString() 메소드 사용

    }
}

Arrays.toString() 메소드를 사용하면 배열의 값을 출력해줍니다.

아래처럼 이쁘게 출력이 되었습니다.

Arrays.toString()

 

 

12. 부족한 금액 계산하기

돈이 얼마나 부족한지 계산하고 부족하지 않다면 0을 return 한다.

1.  다시 탈때 마다 요금이 n배 만큼 올라감 

2. n번 탈때 필요한 돈의 금액 lack = (Price*1+ Price*2+ ... + Price*n) -> for 문 사용 

3. 부족한 돈의 금액 lack - money

4. 안부족하면 return 0;

import java.util.Scanner;

public class lackamout {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int price = scanner.nextInt();
        int money = scanner.nextInt();
        int count = scanner.nextInt();
        long answer;
        int lack = 0;
        
        for(int i=0; i<=count; i++){
            lack += price*i;
        }
        
        if (money>lack){
            answer=0;
        } else{
            answer = lack-money;
        }
        System.out.println(answer);
    }
}

 

생각보다 술술 풀려서 놀랐습니다. 

역시나.. 이유가 있었습니다.

왜 실패했을까요..?

실패????

뭐지 했는데 다시 돌려보니까 통과가 되었습니다....

쉬운게 맞았군요!

오늘부터 다시 주특기 언어 주차로 돌아가서 자바 공부를 합니다. 다음주까지 알고리즘 문제 28개를 풀고 과제를 제출하고 알고리즘 시험을 통과해야 합니다. 새로운 조로 배정이 되었는데 저는 자바 걷기반을 선택했습니다. 시간이 생각보다 훅훅 지나가네요. 

 

🎼오늘의 노래 서인국 애기야

 

사랑스러운 자바

 

IntelliJ 단축키 모음

  • 코드 라인 복사해서 다음 라인에 붙이기: Command + D
  • System.out.println : sout
  • 라인 삭제: Command + Backspace
  • Column selection mode (블럭단위 편집, 세로편집 모드 전환) : Command + Shift + 8
  • 파일 찾기: Command + Shift + O
  • 클릭한 메서드로 이동: Command + 클릭
  • 이전/다음 시점으로 이동: Command + Option + 화살표(좌, 우)
  • 단어 단위 이동: Option + 화살표(좌, 우)
  • 파라미터 변수 확인: Command + P
  • 변수 추출: Command + Option + V
  • 이전 클래스 확인: Command + E
  • 해당 테스트 실행: Control + Shift + R
  • 해당 테스트 디버깅 실행: Control + Shift + R
  • 최근 실행했던 테스트 실행: Control + R
  • 최근 실행했던 테스트 디버깅 실행: Control + D
  • 해당 코드 라인 마치고 다음 라인으로 이동: Command + Shift + Enter
  • 테스트 클래스 생성/이동: Command + Shift + T
  • import 하기: Option + Enter
  • 쓰지 않는 import 정리 하기: Control + Option + O
  • 자동 완성: Control + Space
  • 메서드 생성 및 수정: Option + Enter
  • 주석: Command + /
  • 문법 단위로 코드 이동: Command + Shift + 화살표(상, 하)
  • 한줄 단위로 코드 이동: Option + Shift + 화살표(상, 하)
  • 생성자/Getter/Setter/toString 만들기: Control + Enter
  • 해당 메서드를 사용하는 곳 조회: Option + F7

 

프로그래머스 문제 Java

3.  가운데 글자 구하기

길이를 구해서 중간 글자를 출력 합니다.

 

  1. .length() 메소드를 이용해서 String s의 길이 값을 구한다.
  2. int length = s.length();
  3. 2로 나눈 값의 나머지가 0인 경우는 짝수 -> (length%2==0)
  4. 짝수인 경우, 중간 문자 2개가 answer가 된다. int 이기 때문에 자동으로 소수점 이하 값은 없애버림
  5. 예시. String s = cute; int length =4; 4%2 ==0; 짝수
  6. .charAt() 메소드를 이용해서 x 번째 문자의 값을 구한다
  7. 짝수인 경우 가운데 두글자
  8. 홀수인 경우 가운데 한글자
public class Ex2_1 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        String answer = "";
        int length = s.length();
        if(length%2==0){
            answer+= s.charAt(length/2-1);
            answer+= s.charAt(length/2);
        }else{
            answer+= s.charAt(length/2);
        }
        System.out.println(answer);


    }
}

제출하고 통과는 했으나....

한줄 짜리 코드로도 가능했던 것이었던 것이었습니다.

substring()

.substring 메소드를 이용하는 방법

.substring(start letter, end letter)

시작하는 글자, 끝나는 글자 순번을 넣어주면 됩니다.

.substring(start letter)

시작하는 글자 부터 끝까지 출력합니다. 

 

4. 정수의 합 구하기

a와 b 사이의 숫자를 모두 더한 값을 구하는 문제입니다.

 

  1. a와 b 중 큰 값을 long max, 작은 값을 long min 으로 정의한다.
  2. for문의 초기값을 min, 최대값을 max, 증가연산자 일 때 합을 구한다
public class Ex2_1 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        long answer =0;
        long min = Math.min(a,b);
        long max = Math.max(a,b);
        for (long x=min; x<=max;x++){
            answer += x;
        }
        System.out.print(answer);


    }
}

이렇게 열심히 했는데....

sumAtoB라는 함수가 있었습니다..

sumAtoB() 는 A와 B 사이의 값을 구합니다. 

sumAtoB()

 

5. 문자열을 정수로 전환하기

public class Ex2_1 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
        int answer = 0;
        String s = scanner.nextLine();
        answer = Integer.parseInt(s);
        System.out.println(answer);

    }
}

되게 간단하다고 생각을 했었습니다만....

마! 이게 알고리즘이다

 

6. 없는 숫자 더하기

말그대로 없는 숫자를 더해야 합니다.

 

function solution(numbers) {
  let answer = 0;
   
  for(let i = 0; i <= 9; i++) {
    if(!numbers.includes(i)) answer += i;
  }
   
  return answer;
}

0부터 9까지 숫자가 있는데 없으면 그 수를 더한다.

!변수.includes() 메소드를 사용한다. ! == not

 

오늘은 벌써 4일차입니다. 미니프로젝트를 끝내고 발표까지 하는 날입니다. 4일이지만 하루에 14시간 이상 코딩에 몰입하다보니 일주일은 넘게 지난 느낌입니다. 마지막에 트러블 슈팅하면서 배포후 구현이 안되고 에러가 생기는 경우가 있긴 했지만 그래도 무사히 프로젝틀 끝냈습니다. 

1주차 미니프로젝트 끝

Ajax POST rendering

  • AJAX로 포스트요청을 서버에 보낸후 서버측에서 다른 페이지로 랜더링 해도 페이지 이동이 안되는 현상
    → 해결 : Success 함수 안에 해당 코드를 포함하면 해결
    document.write(response); -> response로
    html안의 내용이 전달되어 오기 때문에 해당 내용을 써주면 됨

Jinja2

  • Jinja2에서 html에서 python 서버로 변수에 값을 담아 보내는 방법..
    → html에서는 {{ 변수이름 }}, app.py에서 받을 때 <변수이름>으로 받을 수 있었다!

encoding

  • Ec2 서버에서의 app.py 실행 시, 토큰 인코딩 값이 바이트로 타입이 지정됨..
    → 해결 : .decode(‘utf-8’)을 붙여 스트링 값으로 바꿔주어 해결

 

1주차 미니프로젝트 회고

  • 다른 조들을 봤는데 수준이 다양하게 분포되어 있었습니다. 다른 사람들의 작업물과 과정, 회고까지 들었는데 굉장히 도움이 되었고 공부를 더 열심히 해야겠다고 마음을 다시 한번 더 다잡게 되는 좋은 자극제가 되었습니다.
  • 트러블슈팅과 코드 리뷰가 중요하고 자신을 챌런지 하는 것이 중요합니다.
  • 협력을 하는 것이 중요합니다. 조원들과 적극적으로 소통하고 협업합니다.
  • 1주차 조원들이 다들 천사같고 너무 친절하고 개발도 잘해서 좋았습니다.
  • 멘토님들의 피드백은
    • 잘했다였다는데 저는 갑자기 zep이 튕겨서 못들었어요 😱😱😱

오늘은 아침에 일어나는 게 너무 힘들었는데 막상 또 일어나서 컴퓨터 앞에 앉으니까 열정이 샘솟았습니다. 제가 어제 걱정하고 씨름했던 오류가 말끔히 해결이 되었거든요. 껐다 켰다는 진리입니다..... 원격 repo에 푸시하지 않는이상 로컬은 상관없으므로 몽땅 merge를 했더니 잘 됐습니다.

 

거의 다 해간다!!!

merge 오류에 대해서

왜 오류가 생기나 했더니 .gitignore에 .idea와 __pycache__넣어서 환경설정을 방해하지 못하게 했었어야했습니다.

  • .gitignore 파일에 .idea와 __pycache__ 를 넣는다.

 

새로 원격 repo를 받았는데 실행이 안되는 건에 대하여...

다시 처음부터 받았는데 몇 개 페이지 실행이 안됐다. 알고보니... 

DB를 끌어와서 구현하는 페이지들이었습니다. 환경설정도 처음부터 해야했었던겁니다.

  • .env 파일을 만들고 DB 정보를 저장하니 실행이 잘 되었습니다.

 

환경변수 처리 .env

  • JWT 토큰 실행을 위한 SECRET_KEY 정보를 .env 넣었습니다.
  • SECRET_KEY가 필요한 파일에 다음과 같이 코드를 넣어줍니다.
from dotenv import load_dotenv
import os

load_dotenv()
SECRET_KEY = os.getenv('SECRET_KEY')

 

발급한 JWT 토큰을 같은 도메인에서 계속 쓰는 방법

function login() {


    $.ajax({
        type: "POST",
        url: "/login/login",
        data: {
            user_id_give: $('#user_id').val(),
            user_pw_give: $('#user_pw').val()
        },
        success: function (response) {
            if (response['result'] == 'success') {
                $.cookie('mytoken', response['token'], {path: '/'}); //path 추가해서 '/' 넣기
                alert('로그인 완료!')
                window.location.href = '/bulletin-board'
            } else {
                // 로그인이 안되면 에러메시지를 띄웁니다.
                alert(response['msg'])
            }
        }
    })
}
  • 왜 페이지 바뀌면 안되지 했는데 path를 설정해주지 않아서 였습니다.
  • 구글링 강의를 들은 게 도움이 되었습니다.

 

회원가입 아이디 중복확인 하는 법

function id_overlap_check() {
    let userid = $('#user_id').val()
    if (userid == '') {
        alert('아이디를 입력해주세요.'); //공백인 경우
    } else {
        $.ajax({
            type: "GET",
            url: "/join/check?user_id=" + userid, //get 할 때 url은 "/url"+찾는값
            data: {},
            success: function (response) {
                alert(response['message']);
                if (response['success'] == false) {
                    let input = document.getElementById("user_id");
                    input.value = null; //input 값 없앰
                } else{$('.user_id').attr("check_result", "success");
                    $('.id_overlap_button').hide(); //중복확인버튼 없앰
                         }
                }
        });
    }
}

 

이렇게 했는데 중복을 필수로 확인해야 회원 가입 버튼이 작동하게 수정했습니다.

 

function join() {
    if ($('.user_id').attr("check_result") == "fail") {
        alert("아이디 중복체크를 해주시기 바랍니다.") //중복체크가 안되어 있을 때
    }
    else if ($('.name_input').val() == '') {
        alert("닉네임을 입력해주시기 바랍니다."); //닉네임 input 이 없을때
        $('.user_name').focus();
    } else if ($('.pw_input').val() == '') {
        alert('비밀번호를 입력해주세요.')
        $('.user_pw').focus(); //pw input이 공백인 경우
    } else {
        $.ajax({
            type: "POST",
            url: "/join/join",
            data: {
                id_give: $('#user_id').val(),
                pw_give: $('#user_pw').val(),
                name_give: $('#user_name').val()
            },
            success: function (response) {
                if (response['result'] == 'success') {
                    alert('회원가입이 완료되었습니다.')
                    window.location.href = '/login'
                } else {
                    alert('다시 시도하세요.')
                }
            }
        })
    }}

어제 남궁성의 자바의 정석 기초편 챕터 1을 듣고 잤습니다. 앞부분이라 프로그램 설치에 대한 내용이 대부분이라 자기 전에 1시간 들었습니다. 강의가 171개가 있던데 다 들을 수 있겠죠...? 회원가입 페이지 구현하는 게 그냥 아이디, 비밀번호, 닉네임 값만 가져오면 될 줄 알았는데, 아이디 중복확인도 해야하고 페이지 디자인도 예쁘게(?) 바꿔야 합니다. 오늘은 회원가입만 완성하고 자도록 하겠습니다. 내일은 로그인 구현하면 되겠죠.....?

 

🎼오늘의 노래: Peachtree Street🍑

Not so mini at all

Jinja2

튜터님이 주신 샘플 파일에도 들어있고 구글링한 블로그에도 있는 Jinja 2는 {%...%}와 같이 생겼습니다. 처음 보는 거라 뭔지도 모르고 어떻게 읽고 고쳐야겠는지도 모르겠어서 일단 공부해봅니다. 어느 세월에 로그인 페이지 만드나....

 

Template Designer Documentation — Jinja Documentation (3.0.x)

Template Designer Documentation This document describes the syntax and semantics of the template engine and will be most useful as reference to those creating Jinja templates. As the template engine is very flexible, the configuration from the application

jinja.palletsprojects.com

 

 

 

 

네이버 HTTP/3 도입

 

 

네이버, 국내 최초 HTTP/3 도입…"검색 결과 빨라져"

네이버가 국내 플랫폼 기업 최초로 자사 검색 서비스에 HTTP/3를 도입했다고 15일 발표했다. HTTP/3는 앱·브라우저와 웹 간 데이터 교환을 위한 3세대 표준 프로토콜이다. 지난 6월 국제인터넷기술

n.news.naver.com

 

js ajax MongoDB 로그인 페이지 구현하기

열심히 해서 커밋해서 푸시까지 해서 원격 repo까지 보냈는데 그 후로 부터 갑자기 제 로컬 repo가 이상해져서 파일 실행이 안됩니다....그래서 해본 게 

  • 로컬 repo 삭제하고 원격 repo 새로 다운 받기
  • 도대체가 모르겠네

여튼 아래처럼 회원가입 페이지를 구현했습니다.

회원가입페이지 만들기

일단은 회원 가입 정보도 DB로 잘 들어가는 걸 확인했습니다. 근데 중복확인은 아직 구현을 못했습니다. 

DB연결이 안되서 애를 먹었는데 그룹으로 프로젝트를 하는 것이 처음이라 더 어렵습니다. 설정을 모두와 맞춘다고 Python도 3.9 버전으로 바꾸고 Blueprint라는 방법도 처음 사용해봤습니다. url 적는 방식이 다르다는 걸 조원분들이 알려줘서 고쳤습니다. 아예 생초보인 저는 다 새롭고 어려운데 척척 하시는 다른분들을 보니 대단하게만 느껴지네요. 

 

백엔드 테스트를 할 때는 postman이라는 것도 사용한다고 합니다. 오늘은 결국 회원가입과 로그인만 구현하고 Github으로 푸시를 했습니다. 각각 feature 별로 커밋하려고 했더니 뭔가 로컬에서 꼬여버려서 작업이 복구가 안되네요.

 

다행히 원격 repo는 잘 들어갔는데... 다시 작업하려고 하니까 도대체 어떻게 해야 원래 작업상태로 돌아갈지 모르겠어요...... 일단 잡니다!

 

드디어 오늘이 항해99 부트캠프 정식 시작일입니다. 지난주는 pre-onboarding 기간으로 주특기 언어인 Java를 공부하는 시간을 가졌습니다. 오늘부터 새로 배정된 조에서 미니 프로젝트를 진행합니다. 조원 4명이서 4일동안 진행할 프로젝트를 기획하고 제작하고 배포하고 발표까지해야 합니다. 

 

오늘은 첫날이라고 대표님이 오셔서 OT를 해주셨는데 항해99프로그램에 대한 흥미로운 사실들과 개발자로서의 마음가짐에 대해 좋은 말씀을 나누어 주셨습니다. '나는 개발을 사랑한다'가 세뇌가 되어야 한다고 하셨는데 저는 지금은 좋아한다 정도여서 사랑으로 한번 끌어올리도록 노력해보겠습니다. 하면 할수록 더 좋아지고 있긴 합니다. 컴퓨터의 역사부터 여러가지가 흥미로워요. 다른 개발자분들이 토이프로젝트를 올려놓은 웹사이트가 있는데 보면서 이런것도 개인이 만들수가 있구나 하면서 열정이 샘솓고 있습니다.  늘 가는 웹사이트를 들어가더라도 전에는 아무 생각없이 이용만 했다면 지금은 어떤 기능을 써서 이런 웹사이트를 구현했나 하고 분석을 하게 됩니다.  아는 만큼 보이는 것 같습니다.

 

🎼오늘의 노래: 오렌지 캬라멜 아잉🧡

 

개발을 향한 저의 사랑(?) 노래입니다....🤣

개발을 너무나 사랑한 나머지...

로그인 기능 구현하기 JWT tocken, access tocken, refresh tocken

  • JWT을 사용하는 이유
    • 쿠키를 받아 토큰을 발급해서 로그인 정보 확인
    • 쿠키는 브라우저에만 존재
    • 같은 도메인이면 쿠키가 유지됨
    • 로그아웃 하려면 쿠키 삭제하면 됨
    • 보안상 더 낫다고 함
  • Hash 함수 사용 이유
    • 비밀번호의 암호화
    • Sha 256, Sha 512 를 많이 사용함
  • unix time: 1970년 1월 1일로부터 몇 초 지났는지

 

튜터님과 멘토링

  • Flask tutorial의 Blueprint를 그대로 따라하면 됨
  • Bootstrap 버전 통일
  • key value 형식으로 하기
  • 권한을 줄 때 일반적으로는 회원 정보에 따라서 하지만 비밀번호를 게시물마다 부여하는 게 개발이 훨씬 빠를것
  • http는 세션이나 토큰으로
  • JWT: 유저정보 넣기 -> 토큰을 통해서 식별 -> 통과 -> decode -> 유저 정보 제공 -> DB에서 유저 정보 식별 -> API tlfgod
  • 체크날짜 구분할 때, PK(Primary key) index를 사용하세요 -> 단, length 말고 max값을 조회해서 +1을 한 값을 가져오기 
  • 관계형 DB, NoSQL 중에 우리 조가 하는 건 NoSQL 
  • MongoDB는 이번주가 지나면 잘 안쓰겠지만, 요즘 핫하니까 잘 정리해두면 좋을 것; app, NoSQL에 많이씀
  • 백엔드는...
    • API 흐름 알기
    • HTTP로 소통한다 - session, token 사용 이유
    • ❗❗Java - 남궁성 자바의 정석 기초편 (유튜브에 있음) 보기
      • ❗❗IntelliJ 따라하면서 보기
    • 객체지향 알기
      • 추천책: 객체지향 사실과 오해, 오브젝트 (조영호)
      • 빨리 이해하려면 따라하고 예제 직접 만들어보기(또는 예제 검색해서 따라해볼것)

 

조원들과 미팅

  • 깃헙 requirements.txt 로 관리하기 https://itholic.github.io/python-requirements/
  • 환경 설정 .env 만들기
    • DB와 관련된 비밀스러운 정보나, 공통적인 환경으로 사용되는 변수들을 config파일이나 .env파일 등으로 환경변수를 따로 관리
  • Blueprint: 하나의 파일에서 같이 작업하면 git 충돌이 일어날 수 있기 때문에 blueprint를 사용해 파일을 쪼개서 각자의 파일에서 따로 작업함 https://youngminieo1005.tistory.com/91

 

드디어 한 주가 끝났습니다. 일주일동안 핵심 쏙쏙 Git 강의를 들었고 혼자 공부하는 자바 챕터 5까지 진도를 나갔습니다. 이번주는 Pre-Onboarding 기간으로 주특기 언어를 학습하는 시간이었고 다음주부터 정식으로 시작합니다. 부족한 공부를 위해서 어떻게 해야하나 백준이랑 프로그래머스라는 게 있다는 데 조사를 해봐야겠습니다. 일단 어디서 시작해야할지 알아보는 중이에요. 아예 새로운 분야에 입문하려고 하니까 공부할 게 태산이네요. 

 

티끌모아 태산 가즈아😎

 

🎼오늘의 노래 - Joopearl Blues

자바가 뭐라고 생각해요?

 

TIL

  • 마우스를 사야겠다
  • 백준 그리디 알고리즘 부터 풀어보기
  • 어떻게든 역량을 키우자
  • Git IntelliJ로 사용하는 법 https://youtu.be/uUzRMOCBorg

어제 기술매니저님께서 책(혼자 공부하는 자바)에 나오는 연습문제 정도는 바로바로 풀 줄 알아야 한다고 하셔서 오늘은 복습에 초점을 맞출 예정입니다. 일단 챕터 5를 다 끝내고 챕터 1부터 연습문제 답지 안보고🤓 다 한번 풀어보겠습니다. 벌써 토요일이네요.

 

🎼오늘의 노래 그레이- 하기나 해

 

하기나 해!! 제발요!!

 

05-3 열거 타입

  • 열거 타입(enumeration type):한정된 값만 갖는 타입
    • 열거 상수(enumeration constant) 중에서 하나의 상수를 저장하는 타입

 

열거 타입 선언

  • 1. 열거 타입의 이름을 정하고 해당 이름으로 소스 파일(.java)을 생성해야 함
    • 이름은 관례적으로 첫 글자를 대문자로 하고 나머지는 소문자로 구성함
    • 여러 단어로 구성된 이름이라면 각 단어의 첫 글자는 대문자로 하는 것이 관례임
  • 2. 소스 파일 내용으로 열거 타입 선언 -> public enum : 열거 타입을 선언하기 위한 키워드 (반드시 소문자로 작성)
    • 열거 타입 이름은 소스 파일 이름과 대소문자가 모두 일치해야함
    • public enum 열거타입 이름 {...}
  • 3. 열거 상수 선언
    • 열거 탕비의 값으로 사용
    • 모두 대문자로 작성함
      • public enum Week { MOMDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
    • 여러 단어로 구성될 경우 밑줄(_)로 연결

 

열거 타입 변수

  • 열거 타입은 변수를 선언하고 사용 가능
    • 열거타입 변수;
  • 열거 상수를 저장
    • 열거타입 변수 = 열거타입.열거상수;
    • ex) Week today = Week.SUNDAY;
    • ex) Week birthday = null;
  • 열거 상수는 열거 객체로 생성
    • Week 의 경우 총 7개의 Week 객체로 생성
    • 메소드 영역에 생성된 열거 상수가 해당 Week 객체를 각각 참조
    • 열거 타입은 참조 타입
    • 열거 상수는 객체!
  • Week today = Week.SUNDAY;
    • 열거 타입 변수 today 스택 영역
    • today에 저장되는 값은 Week.SUNDAY 열거 상수가 참조하는 개체의 번지
    • 열거 상수 Week.SUNDAY와 변수는 서로 같은 Week 객체를 참조
    • today == Week.SUNDAY; //true

 

  • week1와 week2는 모두 Week.SATURDAY 상수라는 동일한 Week 객체를 참조
Week week1 = Week.SATURDAY;
Week week2 = Week.SATURDAY;
System.out.println( week1 == week2 ); //true
  • 자바는 컴퓨터의 날짜 및 요일, 시간을 얻기 위해 Calendar 클래스를 제공함
  • Calendar 변수를 선언 -> Calendar.getInstance()
    • Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR); //연
int month = now.get(Calendar.MONTH) +1; //월(1~12)
int day = now.get(Calendar.DAY_OF_MONTH); //일
int week = now.get(Calendar.DAY_OF_WEEK); //요일(1~7)
int hour = now.get(Calendar.HOUR); //시간
int minute = now.get(Calendar.MINUTE); //분
int second = now.get(Calendar.SECOND); //초

 

열거 타입과 열거 상수

Week.java (열거 타입 선언)

public enum Week {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}

Main.java (열거 타입 사용하기)

import java.util.Calendar;

public class Main {
    public static void main(String[] args) {
        Week today = null;
        Calendar cal = Calendar.getInstance();
        int week = cal.get(Calendar.DAY_OF_WEEK);

        switch (week) {
            case 1:
                today = Week.SUNDAY; break;
            case 2:
                today = Week.MONDAY; break;
            case 3:
                today = Week.TUESDAY; break;
            case 4:
                today = Week.WEDNESDAY; break;
            case 5:
                today = Week.THURSDAY; break;
            case 6:
                today = Week.FRIDAY; break;
            case 7:
                today = Week.SATURDAY; break;
        }

        System.out.println("오늘 요일: " + today);

        if(today == Week.SUNDAY) {
            System.out.println("일요일에는 축구를 합니다.");
        } else {
            System.out.println("열심히 자바 공부합니다.");
        }
    }
}

 

열거 타입을 사용하려면 public enum 열거 타입 선언한 먼저 해야함

 

 


확인문제 복습 손코딩으로 하기

손코딩으로 해야 는다는 글을 어디서 본 적이 있어서 복습은 노트에 손코딩하면서 하기로 결심했습니다. 확실히 답지도 안보고 문제만 보면서 펜으로 노트에 직접 쓰니까 더 머릿속에 잘 들어오는 듯 합니다. 그래도 한 번 푼 문제라고 풀리는 문제가 안풀리는 문제보다는 많습니다.

 

근데 생각보다 저는 더 악필이네요🤓

 

  • while문에 break; 잊지 않기
  • 타입 선언 잊지 않기
  • 변수 선언한 {}를 벗어나놓고 왜 안되지 하지 않기
  • 이유 알고 쓰기
  • {} 빼먹지 않기; 실행 순서 알기
  • 문제를 꼼꼼히 읽읍시다
  • String 변수는 .equals() 메소드를 사용

chapter 2 변수

Chapter 02-1

1. o,x 문제

  • 변수는 하나의 값에만 저장할 수 있음
  • 변수 선언 시에 사용한 타입의 값만 저장할 수 있음
  • 변수는 초기 값이 저장되지 않은 상태에서 읽을 수 없음

2. 변수 이름으로 사용할 수 있는 것 o,x 문제

  • $value는 사용할 수 있음
    • 첫번째 글자는 문자이거나 '$', '_' 만 가능함

 

Chapter 02-2

2. o,x 문제

  • char var = 'AB'; //char 타입이 아니라 String 타입임
  • long var = 50000000000; //long은 int 타입의 범위를 벗어 날 시 숫자 뒤에 L 을 붙어야 함
  • String var = "나의 직업은 "개발자" 입니다."; //"를 썼으면 안에는 '를 써야함
  • float = 1e2f; // 변수 이름을 빼먹음😱😱

 

Chapter 02-3

10. 다음 코드 실행했을 때 출력 결과

String str1 = 2+3+""; //5
String str2 = 2+""+3; //23
String str3 = "+2+3; //23

+ 연산에서의 문자열 자동 타입 변환

숫자 + 숫자 -> 덧셈 연산 -> 숫자

"문자열" + 숫자 -> " 문자열"+"숫자" -> "문자열숫자"

숫자 + "문자열" -> "숫자" + "문자열" -> "숫자문자열"

 

손코딩 연습

 

 

오늘은 금요일입니다. 벌써 항해를 시작한지 5일이 지났네요. 입학시험도 무사히 치르고 일주일동안 많은 것들을 학습했습니다. 아직 Java와 친해지려면 멀었지만요. 프로그래밍 언어는 인간의 언어보다 더 규칙적이라 독일어 배울 때를 생각하면 훨씬 쉬운 것 같습니다만 시간이 좀 필요합니다. 🎼오늘의 노래: 로꼬 - '시간이 들겠지'.

it takes time

Chapter 05-1 참조 타입과 참조 변수

기본타입과 참조 타입

  • 기본 타입(primitive type) 변수는 실제 값을 변수안에 저장
  • 참조 타입(배열, 열거, 클래스, 인터페이스) 변수는 메모리의 번지를 변수 안에 저장
  • 번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부름 -> heap memory

메모리 사용 영역

  • JVM은 Runtime Data Area(운영체제에서 할당받은 메모리 영역)을 아래와 같이 세부 영역으로 구분해서 사용
  • 메소드 영역 Method area: JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역; 코드에서 사용되는 class들을 클래스 로더로 읽어 클래스 별로 정적 필드(static field)와 상수constant, 메소드 코드, constructor(생성자) 코드 등을 분류해서 저장
  • 힙 영역 Heap Area: 객체와 배열이 생성되는 영역; JVM 스택 영역의 변수나 다른 객체의 필드에서 참조
    • 참조하는 변수나 필드가 없다면 의미 없는 객체가 되기 때문에 JVM이 쓰레기로 취급하고 쓰레기 수집기(Garbage Collector)를 실행시켜 자동으로 제거
    • 객체를 제거하기 위해 별도의 코드를 작성할 필요가 없음
    • 자바는 코드로 객체를 직접 제거하는 방법을 제공하지 않음
  • JVM 스택 영역 Stack area: 메소드를 호출할 때마다 Frame을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행
    • 프레임 내부에는 로컬 변수 스택이 있음 
    • 기본 타입 변수와 참조 타입 변수가 Push 되거나 Pop 
    • 최초로 변수에 값이 저장 될 때 stack 영역에 변수가 생성됨
    • 변수는 선언됨 블록 안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거 됨
    • 기본 타입 변수는 스택 영역에 직접 값을 가지고 있지만, 참조 타입 변수는 스택 영역에 힙 영역의 객체 주소를 가짐
    • 자바에서는 배열을 객체로 취급

메모리 사용 영역

참조 변수의 ==, != 연산

  • 기본 타입 변수의 ==, != 연산은 true, false를 조사하지만 참조 타입 변수들은 동일한 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 때 사용
  • 동일한 번지 값을 갖고 있다는 것 == 동일한 객체를 참조함

 

null과 NullPointerException

  • 참조 타입 변수는 힙 영역의 객체를 참조하지 않는다는 뜻으로 null 값을 가질 수 있음
  • null값을 초기값으로 사용할 수 있기 때문에 null로 초기화 된 참조 변수는 스택 영역에 생성됨
  • 참조 타입 변수가 null 값을 가지는지 확인하려면
    • 변수 ==, != null 연산을 수행하면 됨
  • 예외Exception: 프로그램 실행 도중에 발생하는 오류
    • 사용자의 잘못된 입력
    • 코드 잘못 작성
    • 가장 많이 발생하는 예외: NullPointerException-> 참조 타입 변수를 잘못 사용하면 발생함
      • 참조 변수가 null을 가지고 있을 경우에는, 참조 객체가 없으므로 변수를 통해 객체를 사용할 수 없음
      • null이 없는 상태에서 객체의 데이터나 메소드를 사용하는 코드 실행시 발생

String 타입

  • 문자열이 직접 변수에 저장되는 것이 아니라, 문자열은 String 객체로 생성되고 변수는 String 객체를 참조함
  • 문자열 리터럴이 동일하면 String 객체를 공유함
  • 공유하지 않고 별개의 객체에 저장하려면-> new 연산자를 사용해서 직접 String 객체를 생성
    • new 연산자= 객체 생성 연산자
  • 문자열 리터럴로 생성 vs. new 연산자로 생성 
    • 동일한 문자열 리터럴로 String 객체 생성했을 경우: ==연산의 결과는 true
    • new 연산자로 생성 했을 경우: ==연산 결과는 false
    • == 연산자는 변수의 저장된 객체의 번지가 동일한지를 검사하기 때문
    • 동명이인 같은 걸 입력할 때 쓰는 방법일까....?
  • 객체에 상관없이 내부 문자열을 비교하고 싶을 때 -> equals() 메소드를 사용
  • String 변수는 참조 타입으로 초기값으로 null을 대입할 수 있음
    • String 변수가 참조하는 String 객체가 없다는 의미
    • String hobby = null 
  • 참조를 잃은 String 객체는.... goes to the Garbage Collector

 

Chapter 05-2 배열

배열이란? array

  • 같은 타입의 데이터를 연속된 공간에 나열하고 각 데이터에 인덱스(index)를 부여해놓은 자료 구조
  • 인덱스는 0부터 시작함
  • 배열의 특징
    • 같은 타입의 데이터만 저장; 다른 타입 저장하면 타입 불일치 컴파일 에러 발생 type mismatch
    • 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없음
      • 새로운 배열을 생성하고, 기존 배열 항목을 새 배열로 복사하는 수밖에 없음

배열 선언

  • 배열을 사용하기 위해서는 배열 변수를 선언해야함
  • 형식1: 타입[] 변수;
  • 형식2: 타입 변수[];
  • 배열 변수는 참조 변수
  • 배열은 객체로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조함
    • 참조할 배열 객체가 없다면 배열 변수는 null값으로 초기화 됨
    • 배열 변수가 null 값을 가진 상태에서 변수로 값을 읽거나 저장하면 -> NullPointerException 에러 발생
    • 배열을 생성하고 배열 변수가 참조하는 상태에서 값을 저장하거나 읽어야함

배열 생성

  • 값 목록 이용 또는 new 연산자 이용
  • 값 목록으로 배열 생성
    • 타입[] 변수 = {값0, 값1, 값2, 값3, ...}
    • 배열 변수를 이미 선언한 후에는 다른 실행문에서 중괄호를 사용한 배열 생성이 안됨 -> 컴파일 에러!
    • 배열 변수를 미리 선언한 후 값 목록들이 나중에 결정되는 상황에는 -> new 연산자 사용해서 값 목록을 지정!
      • 변수 = new 타입[] {값0, 값1, 값2, 값3, ...}
    • 메소드의 매개값이 배열일 경우에도 new 연산자를 사용
      • int result = add( new int[] {값0, 값1, 값2} );
public class prac {
    public static void main(String[] args) {
        int[] scores;
        scores = new int[] {83,90, 87};
        int sum1 = 0;
        for (int i=0; i<3; i++){
            sum1 += scores[i];
        }
        System.out.println("총합 : " + sum1);

        int sum2 = add( new int[]{83, 90,87});
        System.out.println("총합 : " + sum2);
        System.out.println();
    }

    public static int add(int[] scores){
        int sum =0;
        for(int i=0; i<3;i++){
            sum += scores[i];
        }
        return sum;
    }
}

 

  • new 연산자로 배열 생성
    • 향후 값들을 저장할 배열을 미리 만들고 싶다면 new 연산자로 배열 객체 생성
      • 타입[] 변수 = new 타입[길이];
      • 길이 == 배열이 저장할 수 있는 값을 개수
    • new 연산자로 배열을 처음 생성할 경우-> 기본값 0으로 초기화; String이라면 null값
    • 배열이 생성되고 나서 특정 인덱스 위치에 새로운 값을 저장
      • 변수[인덱스] = 값;

 

배열 길이

  • 배열에 저장할 수 있는 전체 항목의 개수
  • .length 사용
    • 읽기 전용 필드기 때문에 값을 바꿀수 없음
    • for 문 사용할 때 유용

배열의 length 필드

public class prac {
    public static void main(String[] args) {
        int[] scores = {83,90,87};
        int sum =0;
        for(int i=0; i<scores.length; i++){
            sum+=scores[i];
        }
        System.out.println("총합 : " + sum);

        double avg = (double) sum/scores.length;
        System.out.println("평균 : " + avg);
    }
}
  • < 연산자를 사용한 이유는 배열의 마지막 인덱스는 배열 길이보다 1이 적기 때문~~
    • 인덱스 초과해서 사용시 -> ArrayIndexOutOfBoundsException 에러 발생

 

명령 라인 입력

  • public static void main(String[] args){ .... }
    • (String[] args)가 필요한 이유
      • 명령 라인(명령 프롬프트)에서 위 코드를 java 명령어로 실행하면 JVM은 길이가 0인 String 배열을 먼저 생성하고 Main() 메소드를 호출할 때 매개값으로 전달
    • main() 메소드는 String[] args 매개 변수를 통해서 명령 라인에서 입력된 데이터의 수(배열의 길이)와 입력된 데이터(배열의 항목 값)을 알 수 있음

  •  
  • 매개 값을 주고 실행하는 법 (명령 프롬프트(터미널)에서 실행하는 방법)
    • JDK 11 이후 버전: java -p . -m chap05/sec02.exam05.MainStringArrayArgument 10 20
    • JDK 8 이전 버전: java sec02.exam05.MainStringArgument 10 20
  • args는 {"10", "20"}을 array로 참조
    • 문자열로 인식되니까 숫자로 바꾸려면 Integer.parseInt() 메소드를 이용해서 정수로 변환함
      • 정수로 변환할 수없는 문자열이라면 -> NumberFormatException 에러 발생

 

다차원 배열

  • 2차원 배열: 행과 열로 구성된 배열; 가로 인덱스와 세로 인덱스를 사용함
    • 자바는 중첩 배열 방식으로 구현
    • int[][] scores = new int [2][3]
  • 배열의 정확한 길이를 알고 인덱스를 사용해야 함
    • 아니면 ArrayIndexOutOfBoundsException 에러 발생
  • int[][] scores = { {95, 80}, {92, 96}};
행, 열 0 1
0 95 92
1 80 96

 

int score = scores[0][0]; /95
int score = scores[1][1]; /96

 

배열 속의 배열

public class prac {
    public static void main(String[] args) {
        int[][] mathScores = new int[2][3];
        for (int i = 0; i < mathScores.length; i++) {
            for (int k = 0; k < mathScores[i].length; k++) {
                System.out.println("mathScores[" + i + "][" + k + "]=" + mathScores[i][k]);
            }
        }
        System.out.println();

        int[][] englishScores = new int[2][];
        englishScores[0] = new int[2];
        englishScores[1] = new int[3];
        for (int i = 0; i < englishScores.length; i++) {
            for (int k = 0; k < englishScores[i].length; k++) {
                System.out.println("englishScores[" + i + "][" + k + "]=" + englishScores[i][k]);
            }
        }
        System.out.println();

        int[][] JavaScores = {{95, 80}, {92, 96, 80}};
        for (int i = 0; i < JavaScores.length; i++) {
            for (int k = 0; k < JavaScores[i].length; k++) {
                System.out.println("JavaScores[" + i + "][" + k + "]=" + JavaScores[i][k]);
            }
        }
    }
}

중첩for문을 보니 이제 기분이 좋아진다... for문 좋아요😍

 

 

객체를 참조하는 배열

  • 참조 타입(클래스, 인터페이스) 배열은 각 항목에 객체의 번지를 가짐
    • String은 클래스 -> String[] 배열은 String 객체의 번지를 가짐 -> String[] 배열은 String 객체의 번지를 참조함
    • String[] 배열의 항목은 String 변수와 동일하게 취급
      • Ex) == 대신 equals() 메소드 사용 

배열 복사

  • for 문을 사용하거나 System.arraycopy() 메소드를 사용함

for문으로 배열 복사

public class prac {
    public static void main(String[] args) {
        int[] oldIntArray = {1,2,3};
        int[] newIntArray = new int[5];

        for(int i =0; i<oldIntArray.length; i++){
            newIntArray[i] = oldIntArray[i];
        }

        for(int i=0; i<newIntArray.length; i++){
            System.out.print(newIntArray[i] + ", ");
        }
    }
}

 

  • System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

System.arraycopy()로 배열 복사

public class prac {
    public static void main(String[] args) {
        String[] oldStrArray = { "java", "array", "copy"};
        String[] newStrArray = new String[5];

        System.arraycopy( oldStrArray, 0, newStrArray, 0, oldStrArray.length);

        for(int i=0; i< newStrArray.length; i++){
            System.out.print(newStrArray[i] + ", ");
        }
    }
}
  • 복사되지 않은 항목은 null 처리 됨
  • 참조 타입 배열이 복사되면 복사되는 값이 객체의 번지이므로 새 배열의 항목은 이전 배열의 항목이 참조하는 객체와 동일

 

항상된 for문 enhanced for statements

  • for(타입 변수: 배열){ ... } 
  • 배열의 항목 개수 만큼 반복하고 자동적으로 for문을 종료; 반복할 때마다 변수에는 배열에서 가져온 항목이 저장됨

향상된 for문

public class prac {
    public static void main(String[] args) {
        int[] scores = { 95, 71, 84, 93, 87};

        int sum = 0;
        for (int score : scores){
            sum = sum + score;}
        System.out.println("점수 총합 = " +sum);

        double avg = (double) sum / scores.length;
        System.out.println("점수 평균 = " +avg);
    }
}

 

확인 문제🥲🥲

3. 

int[][] array = {
	{95, 86},
    {83, 92, 96},
    {78, 83, 93, 87, 88}
};

array.length -> 3 //3줄

array[2].length -> 5 //3번째 줄은 5개 있음

 

4. for문 이용해서 배열의 항목에서 최대값 구하기

public class prac {
    public static void main(String[] args) {
        int max = 0;
        int[] array = { 1, 5, 3, 8, 2};

        //작성 위치
        for(int i=0; i<array.length; i++){
            if (max < array[i]) {
                max = array[i];
            }
        }

        System.out.println("max: " + max);
    }
}

 

5. 중첩for문을 이용해서 주어진 배열의 전체 항목의 합과 평균값 구하기

public class prac {
    public static void main(String[] args) {
        int[][] array = {
                {95, 86},
                {83, 92, 66},
                {78, 83, 93, 87, 88}
        };

        int sum = 0;
        double avg = 0.0;

        //작성 위치
        int count =0;
        for(int i=0; i<array.length; i++){
            for(int k=0; k<array[i].length; k++){
                sum += array[i][k];
                count++;
            }

        }
        avg = (double) sum/ count;

        System.out.println("sum: " +sum);
        System.out.println("avg: " +avg);

    }
}

 

7. 학생 점수 구하기

import java.util.Scanner;

public class prac {
    public static void main(String[] args) {
        boolean run = true;
        int studentNum = 0;
        int[] scores = null;
        Scanner scanner = new Scanner(System.in);

        while (run) {
            System.out.println("--------------------------------");
            System.out.println("1. 학생수 | 2. 점수입력 | 3. 점수리스트 | 4.분석 | 5. 종료");
            System.out.println("--------------------------------");
            System.out.println("선택> ");

            int selectNo = Integer.parseInt(scanner.nextLine());

            if (selectNo == 1) {
                System.out.print("학생수> ");
                studentNum = Integer.parseInt(scanner.nextLine());
                scores = new int[studentNum];
            } else if (selectNo == 2) {
                for (int i = 0; i < scores.length; i++) {
                    System.out.println("scores[" + i + "]> ");
                    scores[i] = Integer.parseInt(scanner.nextLine());
                }
            } else if (selectNo == 3) {
                for (int i = 0; i < scores.length; i++) {
                    System.out.println("scores[" + i + "]:" + scores[i]);
                }


            } else if (selectNo == 4) {
                int max = 0;
                int sum = 0;
                double avg = 0.0;
                for (int i = 0; i < scores.length; i++) {
                    max = (max < scores[i]) ? scores[i] : max;
                    sum += scores[i];
                }
                avg = (double) sum / studentNum;
                System.out.println("최고 점수: " + max);
                System.out.println("평균 점수: " + avg);
            } else if (selectNo == 5) {
                run = false;

            }

        }
        System.out.println("프로그램 종료!!!");
    }


}

 

tenary operator: 삼항연산자

max = (max <scores[i]) ? scores[i] : max;

==

int max;

if(max<scores[i]){scores[i];} else{max;}

 

더 단순한 variables로 설명하자면,,,,

 

return (a>b ? a:b);

==
int a=10, b=5;
if(a>b)
	return a;
else
	return b;

어제는 Java의 창조자인 제임스 고슬링의 팟캐스트 인터뷰를 듣다가 잠이 들었습니다. 제임스 고슬링이 가장 좋아하는 숫자는 √2라고 합니다. 종교를 바꿔놓은 숫자라고 해서 그렇답니다. 피타고라스의 정리를 만들어 기존의 개념을 파괴한 숫자이기 때문이랍니다. 컴퓨터 과학자들은 수학자에서 시작하는 경우가 많은데 이분도 마찬가지 인 것 같습니다. 전에 우연히 유튜브 알고리즘에 의해 알게 된 Leslie Lampart라는 튜링상을 받은 마이크로소프트 출신의 컴퓨터 과학자도 마찬가지로 수학에서 시작했다고 합니다. 제 주변만 봐도 비전공자중에 수학전공했던 분들이 개발자로 전향한 케이스가 대부분이었습니다. 저는... 경제학과 경영학과를 복수전공했으니 아예 거리가 있지는 않네요. 대학교에서 통계학 공부한 게 도움이 되길 바라면서 오늘도 공부를 시작해봅니다!

 

오늘의 학습목표는 어제 못한 Sololearn Java 정리(임시저장을 안해서 다 날라갔습니다.. 저장을 생활화 합시다😢), 핵심 쏙쏙 Git 3주차 듣기, 혼자 공부하는 자바 챕터 4를 끝내는 것입니다. 점심시간에 운동을 하고 오겠습니다. 강도는 좀 낮게 3세트씩만.. 안그럼 졸려서..ㅎㅎ

 

깃과 자바 공부

핵심 쏙쏙 Git 3주차

PR (Pull Request)

  • PR(Pull Request): 작업내역을 바로 merge 하지 않고, 참여하고 있는 프로젝트에 내 작업(branch)를 merge해달라고 요청(Request) 를 먼저 보내는 것
    • 여러 피드백을 거쳐서 repo 관리자의 승인을 거쳐 프로젝트에 반영(merge)
  • 왜 PR 이 완료된 후에야 로컬 repo의 feature/jjim 을 삭제해야할까요?
    • 통상적으로 PR 이 반영되기 전 추가 commit을 해야한다면, 로컬 branch에서 commit 후 원격 branch에 push해서 변경된 내용을 반영하기 때문
  • PR 은 리뷰하는 과정을 통상적으로 포함
  • PR 후에도 추가적으로 commit을 해야하는 경우
    • 리뷰에서 추가 수정을 요청받거나
    • PR 을 그대로 merge한다고 했을 때 merge conflict 가 나는 것을 미리 고치기
    • ex) 만약 추가 수정을 제안받았다고 가정할 때, 로컬 repo 의 feature/jjim 에서 commit 후, 원격 repo의 feature/jjim (origin/feature/jjim) 에 push 하는 것이 통상적임
  • 주니어 개발자 취업정보 repo
  • fork(포크,일종의 프로젝트 복사): 원본 소스코드를 복사해서 새로운 독립적인 소프트웨어로 개발하는 것
    • 마치 어떤 문서를 복사해서 그 위에 내가 원하는대로 수정해서 사용하는 것
    • repository 의 사용권한이 다른 사람에게 있을 때(ex.오픈소스), 내가 소유하고 있는 repo 가 아니더라도 프로젝트 제안할 때는 일단 프로젝트의 내용을 내 공간으로 가져와야하는데 그걸 포크라고 함

 

amend 최신 커밋 고치기

  • amend: 최신의 commit을 수정하는 것
  • 꼭! 나만 사용하는 branch 에서만 어멘드 하기
  • force push(강제 푸시): push 후에도 push 한 commit 을 되돌릴 수 있음; 강제로 commit 을 덮어씌우는 것과 같음
    • 강제 푸시 옵션은 꼭 필요할 때만 나 혼자만 작업하는 branch에서 사용
    • 일반적인 push 를 할 때는 강제푸시 옵션에 체크가 되어있지 않는지 꼭 확인

 

commit 되돌리기 - revert, reset

  • revert(리버트): commit 이 변경되었다는 거 알리면서 새로운 commit을 남기는 것
    • 최신 commit 뿐만 아니라 이전에 했던 commit 도 revert 로 되돌릴 수 있음
  • reset(리셋): commit 했던 작업내역을 말 그대로 리셋하는 것
    • soft(소프트): commit 들을 되돌리고 변경된 파일 작업 내역은 보존해서 파일 변경사항으로 보여줌. 이때 변경사항은 add 되지 않은 상태로 보임
    • mixed(믹스드): commit 들을 되돌리고 변경된 파일 작업 내역은 보존해서 파일 변경사항으로 보여줌. 이때 변경사항은 add 된 상태로 보임
    • hard(하드): commit 들을 되돌리고 그동안 작업했던 모든 것도 없앰; 즉, 작업내역을 복원할 수 없음
    • 히스토리를 남기지 않고 변경하는 것이므로 강제 푸시를 해야함; 그렇지 않으면 변경내역 이력이 남음

 

stash 변경사항 임시 보관하기

  • stash(스태시): 프로젝트의 변경사항을 임시적으로 보관해둘 때 사용
  • commit 한 적이 없는 파일이라면 stash 하지 않아도 됨
  • stash 는 여러 변경사항을 임시 저장해둘 수 있음
    • 만약 같은 파일을 여러 번 stash 했을 경우, 내가 수정한 내역이 이곳저곳에 흩어져 있어서 자칫하다가 작업내용이 날아갈 수 있음;
    • 내가 어떤 변경사항 stash 를 저장해두었는지를 파악하기
    • 이전 stash 에서 편집하던 파일을 불러와서 작업하는 습관을 들이기

 

작업으로 의사소통하기

 

Git 프로젝트 관리

오픈 소스 기여

 

깃헙 블로그 꾸미는 건 내일 해야겠다...

강의가 오래되서 (1년 반전) 테마 설정하는 버튼이 사라졌다...

 

🍯꿀팁 이미지 파일 url 만드는 법

github repo에서 issue 만들기 해서 이미지 끌어다 놓으면 자동으로 생성됨. 이슈 등록 안해도 이미지 링크는 쓸 수 있음

 

 


왜 또 안되냐... 깃헙 푸시 오류 😱

지난번에 토큰을 url 주소에 추가하는 것으로 해결된 문제(참조)인 줄 알았는데 PR 하고 푸시하는 과정에서 다시 에러가 발생했습니다. 김치 레시피 추가하는 게 이렇게 힘들일인가요😭


git -c color.branch=false -c color.diff=false -c color.status=false -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree push -v --tags --set-upstream origin refs/heads/feature/1_stir_fired:refs/heads/feature/1_stir_fired 
Pushing to https://github.com/sooni2/kimchi-recipe-os.git
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sooni2/kimchi-recipe-os.git/'
Pushing to https://github.com/sooni2/kimchi-recipe-os.git
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sooni2/kimchi-recipe-os.git/'
Pushing to https://github.com/sooni2/kimchi-recipe-os.git
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sooni2/kimchi-recipe-os.git/'
Pushing to https://github.com/sooni2/kimchi-recipe-os.git
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sooni2/kimchi-recipe-os.git/'
Completed with errors, see above

push repo 오류

해결했습니다....!!😎

해결방법은 아래와 같습니다. 참고로 저는 맥북프로를 사용하고 있습니다. (참고 자료)

  1. keychain access에 접속한다
  2. github.com을 검색한다
  3. 속성에 들어간다
  4. 암호보기를 누른다.
  5. Github에서 발급받은 토큰을 입력한다. (전에 발급 받은 걸 따로 저장해 두어서 새로 발급받지는 않았습니다.)
  6. 변경 사항 저장 버튼을 누른다.

키체인 접근

 


Chapter 04 조건문과 반복문

Chapter 04-1 조건문: if문, switch문

조건문은 조건식에 따라 다른 실행문을 위해 사용

if문

  • 조건식의 결과에 따라 블록 실행 여부가 결정
  • 조건식에는 연삭식, boolean 타입 변수가 올 수 있음
  • if (조건식) {실행문; 실행문; ...}

if-else문

  • if문은 else 블록과 함께 사용
  • if문의 조건식이 true이면 if문의 블록이 실행되고, 조건식이 false이면 else 블록을 실행

if-else if-else문

  • 주사위를 굴려서 나올 수 있는 숫자 중 하나의 수를 무작위로 뽑아서 출력하는 프로그램 작성하기

1. 임의의 정수를 뽑는 법: Math.random() 메소드 활용하기; 0.0과 1.0 사이에 속하는 double 타입의 난수 하나를 리턴함. 0.0은 범위에 포함되고 1.0은 포함되지 않음

        0.0 <= Math.random() < 1.0

2. 1~10 사이의 정수를 얻기 위해서는 각 변에 10을 곱함

        0.0*10 <= Math.random()*10 < 1.0*10 

3. 각 변을 int 타입으로 강제 변환

       (int) 0.0 <= (int) (Math.random()*10) < (int) 10.0

4. 각 변에 1을 더하면 1~10 사이의 정수 중에서 하나의 정수를 얻게 됨

       0+1 <= (int) (Math.random()*10)+1 < 10+1

5. start부터 시작하는 n개의 정수 중에서 임의의 정수 하나를 얻기 위한 연산식은 다음과 같음

      int num = (int) (Math.random()*n)+1;

6. 주사위 번호 하나 뽑기 위한 연산식

     int num = (int) (Math.random()*6)+1;

7. 로또 번호 하나 뽑기 위한 연산식

     int num = (int) (Math.random()*45)+1;

 

public class prac {
    public static void main(String[] args) {
        int num = (int) (Math.random() * 6) + 1;
        if (num == 1) {
            System.out.println("1번이 나왔습니다!");
        } else if (num == 2) {
            System.out.println("2번이 나왔습니다!");
        } else if (num == 3) {
            System.out.println("3번이 나왔습니다!");
        } else if (num == 4) {
            System.out.println("4번이 나왔습니다!");
        } else if (num == 5) {
            System.out.println("5번이 나왔습니다!");
        } else if (num == 6) {
            System.out.println("6번이 나왔습니다!");
        }
    }}

 

switch문

  • if와 다르게 변수의 값에 따라 실행문이 결정됨
  • if문보다 코드가 간결함
public class prac {
    public static void main(String[] args) {
        int num = (int) (Math.random() * 6) + 1;
        switch (num){
            case 1:
            System.out.println("1번이 나왔습니다!");
            break;
            case 2:
            System.out.println("2번이 나왔습니다!");
            break;
            case 3:
            System.out.println("3번이 나왔습니다!");
            break;
            case 4:
            System.out.println("4번이 나왔습니다!");
            break;
            case 5:
            System.out.println("5번이 나왔습니다!");
            break;
            default:
            System.out.println("6번이 나왔습니다!");
            break;
        }
    }}

 

  • break문이 없는 case: case값과 상관없이 실행됨

 

04-2 반복문:for문, while문, do-while문

  • for문
    • for ( 초기화식; 조건식; 증감식){실행문;}
    • for (Int i=0, j=100; i<=50 && j>=50; i++, j--){실행문}
    • 초기화식에서 루프 카운터 변수 선언할 때 float 타입 사용하지 말아야함
  • 중첩 for문
    • 바깥쪽 for문이 한 번 실행할 대마다 중첩된 for문은 지정된 횟수만큼 반복해서 돌다가 다시 바깥쪽 for문으로 돌아감

              구구단 출력하기

public class prac {
    public static void main(String[] args) {
        for (int m=2; m<=9; m++){
            System.out.println("*** "+m+"단 ***");
            for (int n=1; n<=9; n++) {
                System.out.println(m + "x" + n + " = " + (m*n));
            }
        }
    }}
  • while문
    • 조건식이 true일 경우 반복 실행
    • 조건식이 false가 되면 반복 행위를 멈추고 while문 종료

           1부터 100까지 합을 출력

public class prac {
    public static void main(String[] args) {
        int sum = 0;
        int i =1;
        while(i<=100){
            sum+=i;
            i++;
        }
        System.out.println("1 ~ " + (i-1) + " 합 : " + sum);
    }}
  • do-while문: 내부 실행문을 우선 실행하고 실행 결과에 따라서 반복 실행을 계속할지 결정
  • break문: 반복문의 실행을 중지할 때 사용
    • 대게 if문과 같이 사용되어 If문의 조건식에 따라 for문과 while 문을 종료할 때 사용
    • 반복문이 중첩되어 있을 경우 break문은 가장 가까운 반복문만 종료하고 바깥쪽 반복문은 종료하지 않음
      • 바깥쪽 반복문까지 종료하려면 바깥쪽 반복문에 이름(라벨)을 붙이고 'break 이름;'을 사용하면 됨
  • continue문: for문, while문, do-while문에서만 사용
    • continue문은 블록 내부에서 실행되면 for문의 증감식 또는 while문, do-while문의 조건식으로 이동
    • If랑 사용시 특정 조건을 만족하는 경우에 continue문을 실행해서 그 이후의 문장을 실행하지 않고 다음 반복으로 넘어감

           1에서 10 사이 중 짝수만 출력 (continue를 사용한 for문)

public class prac {
    public static void main(String[] args) {
        for(int i=1; i<=10; i++){
            if(i%2 !=0){
                continue;
            }
            System.out.println(i);
        }
    }}

 

확인문제

3. while문과 Math.random() 메소드를 사용해 2개의 주사위를 던졌을 때 나오는 눈을 (눈1, 눈2) 형태로 출력; 눈의 합이 5이면 실행을 멈추는 코드

 

public class prac {
    public static void main(String[] args) {
        int sum = 0;

        while (true) {
            int num1 = (int) (Math.random() * 6) + 1;
            int num2 = (int) (Math.random() * 6) + 1;
            System.out.println("" + num1 + "와" + num2 + "합은" + (num1 + num2));
            if ((num1 + num2) == 5) {
                break;
            }
        }

    }
}

 

4. 중첩 for문을 이용하여 방정식 4x + 5y=60의 모든 해를 구해서 (x,y) 형태로 출력

public class prac {
    public static void main(String[] args) {
        for(int x=0; x<=10; x++) {
            for (int y =1; y<=10; y++){
            if(4*x+5*y== 60){
                System.out.println(x+" , "+y);
            }}
        }
    }
}

 

5, 6. for문 이용해서 출력하기

public class prac {
    public static void main(String[] args) {
        for (int i = 1; i <= 4; i++) {
            for (int j = 1; j <= i; j++) { /*i가 2면 j는 2번 실행됨*/
                System.out.print("*");
                if (i == j) {
                    System.out.println();
                }
            }
        }
    }
}

6. for문 이용해서 출력하기

public class prac {
    public static void main(String[] args) {
        for (int i = 1; i < 5; i++) {
            for (int j = 4; j > 0; j--) {
                if (i < j) {
                    System.out.print(" ");
                } else{ System.out.print("*");}
            }
            System.out.println();
        }
    }
}

i=1, j =4 일 때: 1<4 -> " "

i=1, j=3 일 때: 1<3 -> " "

i=1, j=2 일 때: 1<2 -> " "

i=1, j=1 일 때: 1=1 -> "*"

 

중첩for문 이해할 것...😇😇😇

 

7. while문과 Scanner의 NextLine()를 이용해서 입력된 데이터로 예금, 출금, 조회, 종료 기능을 제공하는 코드 작성

public class prac {
    public static void main(String[] args) {
        boolean run = true;
        int balance = 0;
        Scanner scanner = new Scanner(System.in);
        while (run) {
            System.out.println("----------------------------");
            System.out.println("1.예금 | 2. 출금 | 3.잔고 | 4.종료");
            System.out.println("----------------------------");
            System.out.println("선택> ");

            int menuNum = Integer.parseInt(scanner.nextLine());

            switch (menuNum) {
                case 1:
                    System.out.print("예금액> ");
                    balance += Integer.parseInt(scanner.nextLine());
                    break;
                case 2:
                    System.out.print("출금액> ");
                    balance -= Integer.parseInt(scanner.nextLine());
                    break;
                case 3:
                    System.out.print("잔고> ");
                    System.out.println(balance);
                    break;
                default:
                    run = false;
                    break;
            }
            System.out.println();
        }
        System.out.println("프로그램 종료");
    }
}

Integer.parseInt() : String 타입을 Int 타입으로 바꿔주는 메소드

 

 

입학시험을 봤습니다. 생각보다 오래걸렸고 안배운 기능을 구현하는 것은 어려웠으나 어찌어찌 야매로 했습니다. 오늘은 입학시험이 있어서 모여서 하는 스터디가 없는 대신에 메타버스 zep에서 밍글파티(?)가 있을 예정이라고 합니다. 핵심 쏙쏙 Git 2주차 강의를 오늘 다 듣고 Sololearn Java 캡처한 것들 정리하고 자는 게 목표입니다. 내일은 7시 일어나야지. 새로 산 무선키보드가 생각보다 구려서 손가락이 아프네요.

깃 플로우 배우다

입학시험 - 화성땅 주문하기 가격 붙이기

평당 500원이니까 size * 500 하면 되겠지라는 단순 결론에 이르기까지 3시간이나 걸렸습니다. 뭔가 멋지게 price를 정의해서 하는 방법은 없을까하고 정답 사이트의 html를 샅샅히 보았으나 정답 비스무리한 건 보이지가 않았습니다. ajax를 바꿔야하나 했는데 은행 창구는 계산하는 곳은 아닌 거 같았습니다. 나중에 해답을 보여주면 그 때는 창피할 수도 있겠으나 지금 제 실력에서는 그냥 500을 곱하는 게 최선이었습니다. 

되긴 하는데 이게 맞아...?

입학시험 제출한 것 (언제까지 서버 열어놓을지는 모름)

 

가격 버튼이 없는데 어떻게 가격이 나오냐구요...

input이 없는데 output이 어떻게 나오는 건가에 대해 고민하다가 결국에는 변수에 고정값을 곱하자로 결론이 났습니다. 온갖 블로그를 봤는데 머리만 더 아파지고 힌트도 안되더라고요. 입학시험이 이렇게 어려울리가 없는데 하면서 이러다 입학 못하는 거 아냐 했지만...결과는 내일 나옵니다.

 

 

핵심 쏙쏙 Git 2주차

Issue

  • Github을 이용한 이슈관리
  • About issues
  • 프로젝트에서 issue(이슈) = 프로젝트에서 해결해야하는 문제
    • 버그(프로그램이 원하는 대로 동작하지 않는 것)를 신고 (Bug report, 버그 리포트)
    • 기능 추가 등의 프로젝트 개선 제안 (enhancement)
    • 위 문제들을 해결하기 위한 작업단위

Branch

  • issue 는 내가 할 작업, 기능 추가, 버그 리포트 등 여러 방식으로 사용
  • 협업을 하기 위해
    • issue 를 만들어 누가 작업할지 정함
    • 브랜치를 만들어 작업할 공간을 나눔
  • 브랜치(branch)는 특정 commit 에서 갈라져나와 작업할 수 있음
    • 기능별로 이름을 만들어주어 브랜치에 작업
      • ex) feature/이슈번호_관리쉬운이름
      • feature 는 기능 개발하는 브랜치에 관행적으로 붙여주는 이름
  • 체크아웃(checkout): 작업할 브랜치로 바꾸는 것; 체크아웃된 브랜치에만 commit이 반영됨

 

Merge

그러나 컴퓨터 프로그래밍을 배울 때 처음부터 잘하지는 못한다. 능숙한 프로그래머가 되려면 능숙하게 '버그'를 찾아내고 수정하는 법을 익혀야 한다. 프로그래밍을 하면서 던져야할 질문은 이것이 맞느냐 틀리느냐가 아니라 버그를 수정할 수 있느냐 없느냐다. 이런 식의 지적 결과물을 바라보는 방식이 지식과 지식 습득을 대하는 좀 더 큰 문화에까지 보편화된다면 우리 모두 '틀리는 것'을 덜 두려워하게 될 것이다.
- 마인드스톰 mindstorm (시모어 패퍼트 지음.인사이트.이현경 옮김)

 

  • 에러 안 내려고 시도하지 않는 거보다 해결하는 것을 배우자
  • 하나의 파일을 여러 브랜치에서 수정하고 하나의 branch에 merge 하려고 할 때 merge conflict(병합 충돌) 가 발생
  • 머지한 브랜치는 삭제하기

머지하기

원격 repo와 branch

  • tracking: 로컬 repo와 원격 repo의 특정 브랜치를 연결해주는 것
    • push와 pull 은 기본적으로 tracking(추적)되고 있는 브랜치를 기준으로 commit 내역을 반영
"No matter the circumstances you can always improve. You can always start improving with yourself. You can always start improving today."

 

오늘은 항해99 부트캠프의 둘쨋날입니다. 엄밀히 말하면 Pre-onboarding 기간 입니다. 이번주는 9시부터 시작하지 않고 3시부터 9시까지 학습합니다. 내일 입학 시험에 통과하지 못하면 수요일이 마지막 날이 될 수도 있습니다. 이제 무선키보드도 있고 노트북 받침대도 왔고 데스크 스탠드도 있고 거북목이 되지 않기 위해 어제는 등운동도 했습니다. 로지텍 mx mini for mac을 샀는데 생각보다 타자가 부드럽지은 않습니다. 손가락에 무리가 생기는 거 같기도 하지만 제 손톱이 좀 길어서 그런거같습니다. 손목 보호대랑 무선 마우스도 구매를 해야겠습니다. 개발자가 되기로 한지 2개월, 돈을 많~~~이 썼습니다.

 

어제부터 '혼자 공부하는 자바' 라는 책으로 스터디를 진행하고 있습니다. Sololearn도 레슨 64개중 40 레슨까지 진행했습니다. 자바 마스터가 되는 그날 까지 달리겠습니다. 오늘은 '혼자 공부하는 자바'의 챕터3을 끝내는 것이 학습 목표입니다.

 

핵심 쏙쏙 GIT이라는 강의를 지급 받았는데 오늘 스터디 시작 전에 몇개를 들었는데 GIT을 설치하고 Github 아이디를 만들었습니다. 유저네임을 뭘로할까 고민하다가 sooni2 라고 저희 집 강아지 이름을 따서 만들었습니다. 

Today I learned JAVA

Chapter 03-1 연산자와 연산식

  • 연산자(Operator): 연산에 사용되는 표시나 기호 (ex. +,-,*,==)
  • 연산자는 피연산자의 수에 따라 단항, 이항, 삼항 연산자로 구분됨
  • 연산자의 종류: 
  • 연산식은 반드시 하나의 값을 산출하며, 값 대신 연산식을 사용할 수 있음
  • 비교 연산자와 논리 연산자의 산출타입은 boolean 타입이다.

연산자 종류

 

연산의 방향과 우선순위

  • &&보다 >,<의 우선순위가 높음
  • 대부분의 연산자는 왼쪽에서 오른쪽 방향으로 연산을 수행함
  • 단항 연산자 (++,--,~,!), 부호 연산자(+,-), 대입 연산자(=,+=,-+,...)는 오른쪽에서 왼쪽 방향으로 연산을 수행
  • 복잡한 연산식에는 괄호()를 사용해서 우선순위를 정함
  •  

연산자 연산 방향 우선순위

 

03-2 연산자의 종류

  • 단항 연산자: 피연산자가 단 하나; 부호 연산자(+,-), 증감 연산자(++,--) 논리 부정 연산자(!)
  • 부호 연산자(+,-): boolean 과 char 타입을 제외한 기본 타입에 사용가능
    • 정수 및 실수 리터럴 앞에 붙여 양수 및 음수를 표현
    • 정수 및 실수 타입 변수 앞에는 변수의 부호를 유지하거나 변경하기위해 사용
  • 증감 연산자(++,--): 변수의 값을 1 증가(++) 또는 1 감소(--)시킴; boolean 제외 모든 기본 타입 피연산자에 사용가능
    • ++피연산자 -> 다른 연산을 수행하기 전에 피연산자의 값을 1 증가 시킴
    • 피연산자++ -> 다른 연산을 수행한 후에 피연산자의 값을 1 증가시킴
  • ++i 와 i = i +1의 연산 속도
    • ++i가 i=i+1 보다 연산 속도가 빠르다고 알려져 있으나 차이는 없음
      • i =i+1이 두번의 연산이 필요하지만 i++는 한번의 연산만 수행하기 때문에 생긴 오해이지만 바이트 코드는 동일하기 때문에 속도 차이 없음
  • 논리 부정 연산자(!)
    • true를 false로 false를 true로 변경 -> boolean에서만 사용
      • 조건문과 제어문에서 조건식의 값을 부정하도록 해서 실행흐름을 제어할 때 주로 사용 
      • 두가지 상태(true/false)를 번갈아가면서 변경하는 토글(toggle)기능을 구현할 때도 사용
  • 이항 연산자: 피연산자가 2개인 연산자; 산술, 문자열 결합, 비교, 논리, 대입 연산자 등이 있음
  • 산술연산자의 특징: 피연산자들의 타입이 동일하지 않을 경우 규칙을 사용해서 피연산자들의 타입을 일치 시킨 후 연산을 수행함
    • 피연산자들이 byte, short, char 타입일 경우 모두 Int 타입으로 변환 후 연산을 수행
    • 피연산자들이 모두 정수타입이고 long타입이 포함되어 있을 경우, 모두 long 타입으로 변환 후 연산을 수행
    • 피연산자 중 실수 타입(float, double)이 있을 경우, 허용 범위가 큰 실수 타입으로 변환된 후, 연산을 수행
  • 문자열 결합 연산자(+):문자열을 서로 결합하는 연산자
  • 비교 연산자(<,<=,>,>=,==,!=): 흐름 제어문인 조건문(if), 반복문(for, while)에서 주로 이용되어 실행 흐름을 제어할 때 사용
  • String 변수 비교
    • 대소비교 연산자 사용 불가, 동등 비교 연산자 사용 가능
    • String 변수 비교 시 equals() 메소드를 사용함
  • 논리연산자: 논리곱(&&), 논리합, 배타적 논리합(^), 논리 부정(!) 연산을 수행-> boolean 타입만 사용가능
    • &&와 &의 산출 결과는 같지만 연산 과정이 다름
    • &&는 앞의 피연산자가 false라면 뒤의 피연산자를 평가하지 않고 바로 false라는 산출 결과를 냄; &은 두 피연산자를 모두 평가해서 산출결과를 냄 -> &&이 더 효율적으로 동작
      • 논리합||도 마찬가지
    • 논리 연산은 흐름 제어문인 조건문(If), 반복문(for, while) 등에서 주로 이용됨

논리연산자

 

  • 대입연산자(=, +=,-=,*=,/=,%=): 오른쪽 피연산자의 값을 왼쪽 피연산자인 변수에 저장
    • 오른쪽 피연산자에는 리터럴 및 변수, 다른 연산식이 올 수 있음
    • 모든 연산자들 중에서 가장 낮은 연산 순위를 가짐; 제일 마지막에 수행됨
     

삼항 연산자 

    • ? 앞의 조건식에 따라 콜론(:) 앞뒤의 피연산자가 선택된다고 해서 조건 연산식이라고도 부름
    • if문으로 작성할 수 있지만, 한줄에 간단하게 작성 시 삼항 연산자를 사용하는 것이 더 효율적
    • (?:) 삼항 연산자: 3개의 피연산자를 필요로 하는 연산자

 

삼항 연산자

 

 

핵심 쏙쏙 Git 1주차

  • Git과 github 설치
  • 나의 첫 커밋!! - 실습 01
    • 김치요리법을 모으는 프로젝트를 Git을 사용해서 관리

나의 첫 커밋

 

  • 버전관리: 프로젝트 상태가 변경되는 정보를 알고 있다는 것
  • Git 은 commit 을 사용해서 버전이 달라지는 것을 관리함
  • 컴퓨터에 있는 프로젝트를 Git 이 관리하는 프로젝트로 만들 수 있음 ->**git 초기화(git initialize)**한다고 표현
  • 현재 프로젝트의 상태를 찰칵 📸 저장 = commit
    • 누가(author), 언제 commit 했는지의 정보와 프로젝트 변경 내용
    • 작업내역이 어떤 것인지 알아볼 수 있게 적는 메시지를 'commit 메시지'라고 함
  • commit 에 반영할지 안할지는 파일 단위로 선택
  • commit 에 반영할 파일을 선택 = add (혹은 staging, 스테이징)
  • history: commit 한 기록

 

커밋 수정하기

원격 repo와 로컬 repo

  • repo(리포, repository 리포지토리의 약자):Git으로 관리되는 프로젝트
  • 로컬 repo(local repository):내 컴퓨터에 저장되어있는 리포지토리
  • 원격 repo(remote repository): Github 처럼 다른 곳에서 접속할 수 있는 공간에 저장되어있는 것
  • Github은 원격 repo 가 저장되어있고 + 개발자 커뮤니티 기능을 하는 서비스
  • Tracking, 트랙킹 / branch tracking: 로컬 repo 가 원격 repo 를 연결하는 것을 추적
    • 로컬 repo 만이 내가 어떤 원격 repo 와 연결되어있는지를 앎
    • 원격 repo 는 내가 어떤 로컬 repo 와 연결되어있는지 정보를 가지고 있지 않음
    • 언제나 로컬 repo 를 기준으로 동작을 이해하기
    •  commit을 자동으로 반영하지 않음; 내가 원하는 대로 어디 commit 까지만 반영할지를 수동으로 설정할 수 있게 해서 프로젝트를 더 잘 관리하기 위해서임 
      • commit 을 수동으로 반영
  • push(푸쉬): 로컬 repo 의 commit 들을 원격 repo 에 반영하기
  • pull(풀): 원격 repo 의 commit 들을 로컬 repo 에 반영하기
  • clone(클론, 복제):원격 repo 를 내 컴퓨터에서도 사용할 수 있도록 가져오기; 초기 다운로드

 

😫Push가 안됩니다... 소스트리 git 인증 해결 방법

소스트리에서

설정 - 원격 - 추가로

새로 생성한 github 원격 repo 주소를 넣어서 등록을 했습니다.

 

push 버튼만 누르면 된다고 해서 했는데 계속 해서 에러가 떴습니다.

 

support for password authentication was removed on august 13 2021.

 

라는 말과 함께 push 창이 완료가 안됐습니다.

 

구글링해보니 토큰을 새로 발급받아 보라는 말이 있어서 기존의 토큰을 삭제하고 새로 발급받은 토큰으로 대체했습니다.

 

그래도 안되서😰 다시

 

'맥 소스트리 맥 소스트리 support for password authentication was removed on august 13 2021.'라는 검색어로 구글링해서 찾은 티스토리 블로그에서 다음과 같이 솔루션을 알려주셔서 해결했습니다.

 

원격에 입력되어 있는 git 경로에 'github.com~' 앞에 '토큰 값@'를 붙여넣어준다. 즉, git 경로가 'https://토큰 값@github.com~'이 되는 것이다. 그러면 자동으로 사용자명에 토큰 값이 입력된다. 그리고 확인 버튼을 클릭해 설정한 git 원격 토큰 정보를 저장한다.  출처:https://pamyferret.tistory.com/44

저의 첫 푸시는 생각보다 오래 걸렸지만 성공적으로 실행했습니다🤓

숙제할 때도 마찬가지로 URL에 토큰을 추가해서 입력했습니다.

 

 

혼자 공부하는 자바 Chapter 1 

오늘은 부트캠프 첫날입니다. 사전 스터디 할 때는 자바스크립트를 공부했는데 오늘부터 제가 선택한 언어인 JAVA를 배웁니다. Sololearn으로 레슨 64개 중 29개를 완료한 상태입니다. 부트캠프 시작 전에 완료할 생각이었는데 Getter 와 Setter 에서 막혔습니다. 이번주는 Sololearn의 Java 레슨을 다 끝내고 혼자 공부하는 자바 책 Chapter 5를 스케쥴에 맞춰 끝내는 것이 목표입니다. 

 

혼자 공부하는 자바 TIL

01-1 프로그래밍 언어와 자바

  • 기계어: 이진법으로 이루어진 코드
  • 소스파일(Source file): 프로그래밍 언어로 작성한 파일
  • 컴파일(compile): 소스파일을 기계어로 번역하는 것
  • Java: 1995년 Sun Microsystems에서 발표; 안드로이드폰 앱, 웹사이트 개발 핵심 언어로 사용; 모든 운영체제에서 실행 가능한 데스크톱 어플리케이션 개발에 사용
    • 오라클에서 라이선스 보유; JDK(Java Developement Kit:개발 실행 환경(JVM)과 컴파일러 등을 제공)를 배포
  • Java의 특징
    • 모든 운영체제에서 실행 가능
    • 객체지향 프로그래밍: 객체를 만들고, 이 객체들을 서로 연결해서 더 큰 프로그램을 완성하는 기법
    • 메모리 자동 정리: RAM을 자동 관리; 코드 작성 집중 가능
    • 무료 라이브러리 풍부

자바 개발 도구 설치

  • 자바 개발 도구(JDK: Java Development Kit) 설치 필요
    • Open JDK(무료)와 Oracle JDK(유료)가 있는데 LTS(Long term Support)를 위해서는 Oracle JDK 사용이 안정적
    • 나는 JAVA 11를 설치함
  • JDK JAVA SE(Standard Edition) 표기
    • JAVA 11을 설치한다는 것은 JAVA SE 11 또는 JDK 11을 설치한다는 것과 동일한 의미
     
  • 주 버전이 높은 것 보다는 버그를 지속적으로 수정해나가는 LTS 버전을 사용할것을 추천

java 버전 표기

 

환경 변수 설정

맥에서는 어떻게 하는 건지 책에 안나와 있음

검색해보니 terminal을 사용하라함 -> 스파르타 자바 강의를 보니 Window 설치는 환경 변수 내용이 들어있는데 Mac에는 없는 걸로 보아 상관없는듯

 

01-2 이클립스 개발 환경 구축

이클립스를 사용하지 않고 IntelliJ라는 툴을 사용하기 때문에 교양정도로 알고 지나가겠습니다....

이클립스

  • 오픈소스 통합 개발 환경(IDE: Integrated Development Environment)
  • IDE: 프로젝트 생성, 자동 코드 완성, 디버깅 등 여러 개발에 필요한 기능 통합 제공

 

01-3 자바 프로그램 개발 과정

    1. .java 텍스트 파일 생성
    2. 자바 언어로 코드 작성
    3. 컴파일러 javac 명령어로 컴파일
    4. 컴파일 성공하면 확장명이 .class인 바이트 코드 파일 생성
    5. java 명령어로 바이트 코드를 완전한 기계어로 번역해서 실행

java 개발 과정

바이트 코드 파일과 자바 가상 기계

  • 자바 프로그램은 바이트 코드(byte code) 파일(.class)로 구성
  • 바이트 코드 파일은 운영체제에서 바로 실행할 수 없고, 자바 가상 기계(JVM: Java Virtual Machine)라는 번역기가 필요
  • JVM 사용 이유: 바이트 코드 파일을 다양한 운영체제에서 수정하지 않고 사용 가능 -> 자바 언어 성공 요인
    • javac 명령어로 컴파일된 바이트 코드 파일은 JDK가 설치된 어떤 운영체제에서도 java 명령어로 동일하게 실행
    • 개발자는 운영체제와 상관없이 자바 프로그램을 개발 가능
  • 모듈명: JDK 11 버전 이후부터는 명령 프롬프트와 같은 명령 라인에서 프로젝트를 실행할 때 필요; module-info.java 보고 확인 가능
    • module-info.java 라는 모듈을 만들라고 하는데 스킵하고 Hello.java 부터 실행함
  • public static void main(String[] args) 를 자동 추가 설정하는 방법
    • 단축키: ctrl + J
    • psvm + enter
    • 자동 추가는 이클립스에서 제공하는 기능; intelliJ 템플릿 수정할 수 잇음
  • sout 단축키 -> System.out.println();

 

명령 라인에서 컴파일하고 실행하기

명령 프롬프트 또는 터미널과 같은 명령 라인에서 javac와 java 명령어로 소스 파일을 직접 컴파일하고 실행하는 법

-> 명령 라인에서 프로젝트 컴파일 및 바이트 코드 파일 실행 방법

 

  • 예시가 윈도우라 안되는 부분들은 구글링중.... -> 맥의 명령어가 훨씬 쉽다
  • javac 명령어로 컴파일해서 바이트 코드 파일 생성하기
    • javac Hello.java --> Hello.class 파일(바이트 코드 파일) 생성됨
  • tree 명령어
    • 맥 터미널에서 실행 위해서 Homebrew 프로그램 설치 https://brew.sh/index_ko -> tree 설치 brew install tree 입력
    • 설치가 안됨.....ㅠ -> 다시 하니까 됨~

tree 명령어

 

  • java 명령어로 바이트 코드 실행
    • JDK 8 이전 버전: java -cp bin sec03.exam01.Hello
    • JDK 11 이후 버전
      • javac -p [바이트 코드 파일 저장 위치] -m 모듈/패키지이름...클래스이름
      • java -p bin -m chap01/sec03.exam01.Hello
    • 근데 내 맥북프로에서는 JDK 8 이전 버전이 먹히고 11이후 버전은 안됨;;

 

프로그램 소스 분석

프로그램 소스 분석 혼공자

패키지 선언

 

클래스 선언

 

  • {} 중괄호 블록의 앞부분인 public class Hello -> 클래스 선언
  • public class: 공개 클래스; 클래스 이름은 소스 파일명과 동일(대소문자도 일치)
    • 클래스는 필드 또는 메소드를 포함하는 블록
    • 메소드: 어떤 일을 처리하는 실행문들을 모아 놓은 블록
    • javac 명령어로 컴파일 하면 클래스 이름에 .class가 붙어 바이트 코드 파일이 생성됨;
      • Hello.class -> Hello 클래스라고 부름
  • java 명령어로 바이트 코드 파일 실행하려면 클래스 블록 내부에 main() 메소드 블록을 가지고 있어야
  • {} 중괄호 블록의 앞부분, public static void main(String[] args) -> 메소드 선언부
    • main: 메소드 이름
    • java 명령어로 바이트 코드 실행 시 main() 메소드 찾아 블록 내부 먼저 실행
      • main() 메소드: 프로그램 실행 전입점 (entry point)

주석 사용하기

  • 라인 주석 : // ...
  • 범위 주석: /* ... */
  • 도큐먼트 주석: /** ....*/  -> 주로 javadoc 명령어로 API 도큐먼트 생성할 때 사용
  • 문자열 내부에는 주석 붙이기 불가능
  • 주석을 많이 작성한다고 해서 바이트 코드 파일 크기가 커지는 것은 아님
  • 주로 실행문에 사용

 

실행문과 세미콜론(;)

  • 컴파일러는 ; 까지 실행문으로 해석하기 때문에 ; 를 붙여서 실행문이 끝났음을 표시해야함

 

Chapter 2 변수와 타입

02-1 변수

변수 선언

  • 변수의 타입과 이름 결정
  • 첫번째 글자는 문자 , '$', '_' 이어야 하고 숫자로 시작할수 없음
  • 영어 대소문자 구분
  • 첫 문자는 영어 소문자, 다른 단어 붙을 경우 첫문자 대문자 (관례)
  • 문자 수 제한 없음
  • 자바 예약어 사용 불가

 

값 저장

  • 대입 연산자(=) 사용
    • 오른쪽 값을 왼쪽 변수에 저장한다는 의미

 

변수 사용

  • 출력문이나 연산식 내부에서 변수에 저장된 값을 출력하거나 연산할 때 사용

변수 사용 범위

  • 모든 변수는 {} 중괄호 블록 내에서 선언되고 사용됨
  • 로컬 변수(local variable): 메소드블록 내에서 선언된 변수; 메소드 실행이 끝나면 메모리에서 자동으로 없어짐
  • 메소드 블록 전체에서 사용하고 싶으면 메소드 블록 첫머리에 삽입
  • 특정블록내부에서만 사용된다면 해당 블록 내 선언

 

02-2 기본 타입 Primitive Type

구분 저장되는 값에 따른 분류 타입의 종류
기본 타입 정수 타입 byte, char, short, int, long
실수 타입 float, double
논리 타입 boolean

 

정수 타입

타입 메모리사용크기 저장되는 값의 허용 범위
byte 1byte 8bit -128 ~ 127
short 2byte 16bit -32.768 ~ 32.767
char 2byte 16bit 0 ~ 65535 (유니코드)
int 4byte 32bit -2,147,483,648 ~ 2,147,483,647
long 8byte 64bit -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
  • 리터럴(literal): 프로그래머에 의해 직접 입력된 값
  • char 타입: 하나의 문자를 작은따옴표(')로 감싼것 = 문자 리터럴 -> 유니코드로 변환되어 저장됨
    • 유니코드로 변환되기 때문에 int 타입 정수에도 저장 가능 -> 유니코드 자체가 출력됨

 

스트링 타입

  • 문자열: (")로 감싼 문자 
  • String은 기본 타입이 아닌 클래스 타입임
  • 이스케이프문자(Escape): 문자열 내부에 역슬래시(\)가 붙은 문자를 사용; 특정 문자를 포함시킬 수 있음
    • ex) \t -> 탭만큼 띄우기; \n -> 한 줄 내림

자주 사용하는 이스케이프 문자

 

실수 타입

  • float 타입 저장시, f 또는 F 붙여 컴파일러가 타입을 인지하게 함
  • 자바는 실수 리터럴을 기본적으로 double 타입으로 인식함
  • float은 소수점 7자리 이하, double은 소수점 15자리 (좀 더 정확한 데이터 저장이 가능)

논리 타입

  • boolean 타입: true or false 로 저장


02-3 타입 변환

자동 타입 변환

  • 자동으로 타입 변환이 일어나는 것; 허용 범위가 작은 타입이 허용 범위가 큰 타입으로 저장 될 때
    • byte < short < int < long < float < double
    • byte은 char 로 변환 불가 ; char은 음수가 없음

강제 타입 변환

  • casting: 큰 허용 범위 타입을 작은 허용 범위 타입으로 강제로 나눠서 저장하는 것
  • 작은 허용 범위 타입 = (작은 허용 범위 타입) 큰 허용 범위 타입

정수 연산에서의 자동 타입 변환

  • 정수 타입 변수가 산술 연산식에서 피연산자로 사용되면 int 타입보다 작은 byte, short 타입의 변수는 int 타입으로 자동 타입 변환되서 연산 수행
  • 타입 변환이 줄면 실행 성능 향상
  • 두 피연산자 중 허용 범위가 큰 타입으로 변환되어 연산을 수행
  • 정수 연산 실수 연산으로 변경하는 방법:

정수 연산 실수 연산으로 변경하는 방법

실수 연산에서의 자동 타입 변환

  • 피연산자 중 하나가 double 타입이면 다른 피연산자도 double 타입으로 자동 타입 변환되서 연산을 수행 -> 연산결과 double 타입

문자열을 기본 타입으로 강제 타입 변환

문자열을 기본 타입으로 강제 타입 변환

 

기본 타입을 문자열로 변환

  • String.valueOf(기본타입값);

02-4 변수와 시스템 입출력

모니터로 변수값 출력하기

  • println(내용): 괄호 안의 내용을 출력하고 행을 바꿔라; ln = line
  • print(내용): 괄호 안의 내용을 출력만 해라
  • printf("형식문자열", 값1, 값2, ...): 괄호 안의 첫번 째 문자열 형식대로 내용(format string)을 출력해라 
    • 형식 문자열에 포함될 값이 2개 이상인 경우, 순번(argument_index$)을 알려준다

printf()

 

자주 사용되는 형식 문자열

키보드에서 입력된 내용을 변수에 저장하기

  • 키코드 읽는 법
    • keyCode = System.in.read();
      • 시스템이 가지고 있는 입력 장치에서 입력된 키코드를 읽어라
    • throw Exception: System.in.read() 
      • System.in.read()의 단점: 키코드를 하나씩 읽기 때문에 2개 이상의 키가 조합된 한글을 읽을 수 없음 -> Scanner로 보완
     
  • Scanner scanner = new Scanner(System.in)
    • 시스템의 입력장치로부터 읽는 scanner를 생성해서 Scanner 변수 scanner에 저장
  • String inputData = scanner.nextLine()
    • 읽은 문자열(enter키 이전까지 입력된 문자열을 읽음)을 String 변수 inputData에 저장
  • boolean result = inputData. equals("비교문자열")
    • inputData가 비교문자열과 같으면 true, 다르면 false
    • 자바는 기본타입의 값이 동일한지 비교할 때에는 ==를 사용하고 문자열(String)이 동일한지 비교할 때는 equals() 메소드를 사용

 

 

튜터님의 미션! 터미널로만~ java 파일 만들고 실행하기

java를 IDE(IntelliJ)를 사용하지 않고 오직 터미널로만 코딩해서 실행하기

 

 

hong@Jinhongui-MacBookPro chap01 % java -version  //자바 버전 확인했음

openjdk version "11.0.16.1" 2022-07-19 LTS

OpenJDK Runtime Environment Zulu11.58+23-CA (build 11.0.16.1+1-LTS)

OpenJDK 64-Bit Server VM Zulu11.58+23-CA (build 11.0.16.1+1-LTS, mixed mode)

hong@Jinhongui-MacBookPro chap01 % touch Hello.java //① Hello라는 파일명의 자바 파일 생성

hong@Jinhongui-MacBookPro chap01 % vi Hello.java //②Hello라는 이름의 java 파일을 수정, i를 누르면 (insert 화면이 뜸)

// ③:wq 로 저장하고 esc로 수정모드에서 나오기

 

hong@Jinhongui-MacBookPro chap01 % javac Hello.java  //④컴파일러로 클래스 파일 변환

hong@Jinhongui-MacBookPro chap01 % java Hello //⑤자바 파일 실행

Hello java! //⑥yay!

+ Recent posts