오늘은 벌써 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는 잘 들어갔는데... 다시 작업하려고 하니까 도대체 어떻게 해야 원래 작업상태로 돌아갈지 모르겠어요...... 일단 잡니다!

 

자바의정석

 

  • 자바란? 
    • 프로그래밍언어
    • 애플리케이션을 만드는데 사용
      • PC 애플리케이션: IntelliJ, eclipse
      • 웹 애플리케이션
      • 모바일 애플리케이션(안드로이드)
      • 빅 데이터 : hadoop
      • 게임(마인 크래프트), 과학, 소형기기 등
  • Why 자바?
    • 다양한 분야에서 활발히 사용
    • 20년동안 1, 2위를 유지
    • 첫번째 프로그래밍 언어로 GOOD
      • 배우기 쉽고 풍부한 학습자료
    • 모던 프로그래밍 언어(객체지향 + 함수형)
    • 취업에 유리
  • 강의는 Java SE 8 에 맞춰져 있음; 근데 요즘엔 6개월 마다 버전을 출시한다고 함

 

자바의 특징

  • 배우기 쉬운 객체지향 언어(C++, java, python, js)
  • 자동 메모리 관리 (GC: garbage collector)
  • 멀티 쓰레드 지원
  • 운영체제에 독립적

 

자바 가상 머신(JVM)

  • 자바 프로그램이 실행되는 가상컴퓨터(VM)
  • 한번 작성하면, 어디서든 실행(Write once, run anywhere)

자바 API 문서

  • 자바 사전

 

자바의 정석 기초편 github

 

 

GitHub - castello/javajungsuk_basic: 자바의 정석 기초편 관련 자료입니다.

자바의 정석 기초편 관련 자료입니다. Contribute to castello/javajungsuk_basic development by creating an account on GitHub.

github.com

 

드디어 오늘이 항해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;

Sololearn에서 제공하는 Java 언어 학습은 총 60개 레슨으로 이루어져 있습니다. 현재는 아직 40번째 레슨에 머물러 있는 상태에요. 뒤로 갈수록 어려워져서 그렇습니다. 부트캠프 핑계로 Sololearn을 놓고 있지만 이번주 일요일까지는 Sololearn의 Java를 끝내 보도록 하겠습니다. 어차피 저랑은 당분간 친해지려고 노력해야하는 언어입니다. 이 포스팅에서는 공부하다가 헷갈리거나 다시 복습하고 싶은 부분을 캡쳐해서 정리해보려고 합니다.

 

지난번에 썼던거 다 날라가서 슬펐지만 다시 마음 다 잡고 복습해봅니다.

복습 두 번 하면 좋지 뭐...🥹

 

sololearn Java

Scanner

  • Scanner class를 사용하기 위해서 다음 syntax를 사용함
    • Scanner myVar = new Scanner(System.in);

scanner

Division

  • int 타입으로 계산한 것은 int 타입으로 결과가 나옴
  • 소수점까지 원하면 double을 사용

division

 

Prefix & Postfix

  • Prefix: 변수의 값을 증가시키고 새로운 증가된 값을 연산에 사용
  • Postfix: 변수의 값을 사용 후에 값을 증가시킴

prefix postfix

Decision Making

  • 조건문(conditional statements)는 다른 조건에 다른 실행을 하도록함
  • if문은 가장 자주 사용되는 조건문중에 하나
  • if가 true이면 실행되고 아니면 다음 코드가 실행됨

decision making

if...else Statements

  • if문이 false이면 else가 실행됨

if else

The OR Operator

  • The OR Operator(||)은 어느 하나가 true이면 실행

Or Operator

The default Statement

  • switch문은 default case를 옵션으로 가질수 있음
  • 다른 케이스가 다 false이면 default case를 실행
  • default case는 break문이 필요 없음

the default Statement

The switch Expression

  • allows multiple comma-separated values per case
  • -> 을 사용함

switch expression

while Loops

  • 주어진 조건이 true인 이상 계속 반복

while문

for Loops

  • 특정한 숫자만큼 반복한다
  • for(initialization; condition; increment/decrement){statement(s)}

for문

 

do...while Loops

  • do...while문은 최소 한번은 실행됨
  • 일단 한번 실행 하고 그다음에 while 문 조건에 따라 실행

do while

 

continue

  • 반복문이 스킵하고 다음으로 넘어가게 함

continue

Arrays

  • int [ ] arr = new int[5]
    • new 키워드를 사용해서 array에 integers 5개가 있다고 선언함

arrays

 

Enhanced for Loop

enhanced for loop

 

Reverse a String

  • .toCharArray() : String 타입을 CharArray로 바꾼다. 문자열을 문자별로 다 따로 저장
    • ex) "Santa" -> "S", "a", "n", "t", "a"
  • arr.length에 -1을 하는 이유: 
    • .length에 -1을 하지 않는 경우: core dump error가 발생
    • arr[10]에서 배열의 첫 주소는 0부터 시작하지만!!
    • 즉, 배열의 주소는 arr+0, arr+1, ..., arr+9까지이고, 이는 arr[0], arr[1], ..., arr[9]로 표현됨
    • 즉, arr[10]부터는 존재하지 않고 arr[10]에 관한 코드가 작성되면 에러가 발생
    • 이중for문에서 j<length(=10)이기 때문에 j가 될 수 있는 가장 마지막 수는 9가 되니 j가 9인 경우, if문 안에 j=9인 상황을 대입하면 arr[9] < arr[10]입니다. 이 때 arr[10]은 코드 어디에도 정의되지 않았기 때문에 찾을 수 없음. 그렇기 때문에 컴퓨터는 arr[10]이 도대체 어디 정의되었는지 알 수 없다고 에러를 발생시킵니다.
    • 그렇기 때문에 for문의 범위를 length-1까지 정해준다.
  • 그러니까 갯수 세는건 우리가 아는 것 처럼 세지만!!! index 번호는 0부터 시작하니까 array 마지막 수를 부르고 싶으면 array.length-1 을 써야한다!

Reverse a String

Object-Orientation

  • Java는 Object-Oriented Programming(OOP) 객체지향 프로그래밍 스타일을 사용하고 현실과 가깝게 프로그래머들이 생각할 수 있도록 한다
  • OOP에서는 각 객체가 유니크 아이덴티티를 가진 독립적인 유닛이다. (마치 현실에서 그런것처럼(?))
    • 사과는 객체이다. 머그잔도 그러하다. 각각의 사물은 그만의 아이덴티티를 가진다. 두개의 머그잔이 똑같이 생길 수는 있지만 각각의 독립적인 유니크한 objects이다.
  • Objects는 그들을 묘사하는 특징이 있다.
    • 차가 빨간색이거나 파란색, 머그잔이 가득 차 있거나 비어있는 것처럼 말이다.
    • 이러한 특징(characteristics)들은 attributes라고 불린다.
    • attributes는 object의 현 상태를 묘사한다.
    • 차가 움직이거나 전화가 울리는 것처럼 object type에도 behavior 가 적용된다.
  • object는 3가지 dimension이 있다:
    • identity
    • attributes - describe object's current state
    • behavior - what the object is capable of doing
  • class는 object가 뭐가 될지를 묘사한다. object의 청사진(blueprint)과 같음

Object Orientation

 

 

Methods

  • Methods는 behavior를 정의한다
  • Method는 실행문의 집합; function이라고도 함
  • 아래 코드를 보면 sayHello라는 method를 선언함 
  • 메소드를 먼저 정의하고 그 다음에 사용함

Method

 

 

Static

static이 헷갈려서 댓글창을 열어보았읍니다...🤓 영어 만세!

  • memory에는 3가지 타입이 있다:
    • 1. static memory: 실행을 위해 프로그램의 변수/함수/object 저장
    • 2. stack memory: 함수를 실행하기 위해 변수를 저장( 함수 실행 전, arguments/registers 저장, 함수 실행후 옛 값들 로드)
    • 3. heap memory: objects를 저장
  • 실행하기 전에는 objects, 함수, 변수가 없음. 함수를 불러서 프로그램을 시작해야만함
    • 여기서 함수는 main()을 말함
      • main 함수는 static memroy에 생성이 됨
      • 그래서 우리는 main함수를 static이라고 정의함
    • 다른 함수는 필요하다면 static이라고 정의 할 수 있음
  • Static keyword는 변수, objects, 메소드를 준비하기 위해서 사용

static

 

Public

  • Public: accessible anywhere
  • Protected: Accessbible by subclass in other packages, same class and package
  • Private: Accessible by the same class
  • 누가 너의 데이터 또는 메소드에 접근할 수 있는 지를 정의한다

public

 

Hello World! code reuse

  • 아마 반복문이 이해가 안되서 캡쳐를 했던 거 같습니다...
  • 초기값 i= 0, i<=2, i ++ 일때 sayHello()를 실행한다
  • 0부터 시작해서 0,1,2 총 3번 실행합니다. 

Hello world

 

Code reuse 와 parameters

  • method 사용의 장점
    • 코드를 재사용할 수 있음
    • parameters: parameter에 따라서 여러가지를 실행할 수 있음

 

void

  • void는 아무것도 return하지 않는다
  • public static void main(String[] args)의 뜻
    • main methd는 Stirng arrays를 parameters로 불러오고 아무 값도 return 하지 않는다(void)

 

Creating Classes

  • 나만의 커스텀 objects를 생성하기 위해서 class를 만들어야함
  • public class Animal { void bark(){System.out.println("Woof-Woof")
    • bark()가 뭐인지 선언한 것임 
    • class와 그 안의 methods를 사용하기 위해서는 object를 선언해야함

Class 만들기

 

Creating Objects

  • dog 는 Animaldml object가 됨 -> bark()를 부를 수 있음 .을 이용해서
  • .은 object의 attributes와 methods에 연결하기 위해 사용함
  • 이해 안되서 댓글을 캡쳐한 것으로 보임🤓 Gracias Miguel
Object name = new Object();

 

Animal object를 아무 이름으로 만들 수 있어요. 예를 들자면:

 

Animal cat = new Animal();
Animal mouse= new Animal();

 

 

new Animal()을 쓰는 이유는 constructor가 없기 때문이에요. constructor가 있다면 이렇게 됩니다:

 

public class Animal{
   private String name;

 

 

//constructor with parameters

public Animal(String name){
this.name = name;
}

 

//constructor without parameters

public.Animal(){
  this.name="";
 }
}

 

Creating Objects

 

Access Modifiers

  • public: access modifier-> 접근 레벨을 정한다
    • accessible by any other class
  • default: the class is accessible only by classes in the same package
    • 따로 정의 되지 않으면 같은 package안에서는 다 접근 가능
  • protected: 같은 package + subclass는 접근 가능
  • private: 선언된 class만 접근가능

access modifiers

 

Getters & Setters

  • 여기서 조금 막혔습니다😢 혼공자에서 더 파볼 예정
  • Getter: get변수이름; 변수 이름 첫글자 대문자 - return the value
  • Setter: set변수이름; 변수 이름 첫글자 대문자 - set the value

getter and setter

 

static variables

  • static variables&methods는 class에 속함
  • static variable은 다 대문자로 씀

static variable

 

Packages

  • packages: 이름 충돌과 class 접근을 통제하려고 사용됨
    • a group made up of similar types of classes, along with sub-packages

packages

 

Encapsulation

  • OOP에는 4가지 핵심 컨셉이 있습니다
    • encapsulation
    • inheritance
    • polymorphism
    • abstraction
  • encapsulation: implementation details are not visible to users
    • variables of one class will be hidden from the other classes, accessible only through the methods of the current class => data hiding
    • Java에서 encapsulation을 위해서 class변수를 setter와 getter methods로 수정하고 변수값을 본다....??

Encapsulation

 

어제는 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 타입으로 바꿔주는 메소드

 

 

+ Recent posts