오늘은
JAVA와 JavaScript를 잠시 마무리하고
SQL과 HTML에 대해서 배우고 있는 중인데요
이렇게 해놓고 보니 벌써 4개의 큰 주제를 배우고 있는것이 되었네요
그만큼 헷갈릴 때도 있고
잊어버린 것도 많지만...
그리고 아직 해야할 일이 산더미 같이 있지만
그래도 멈춰있지않고 나아가고 있다는 느낌이 듭니다...
학원 수업
<<DB - SQL>>
DB(데이터베이스) = 조직에 필요한 정보를 얻기 위해 논리적으로 연관된 데이터의 집합
DBMS(데이터베이스 관리 시스템 - 소프트웨어)
- 데이터베이스 정의(생성) 갱신, 삭제, 질의(select) 기능 제공
- Oracle(오라클) DB
- 설치확인 방법 = cmd -> sqlplus 입력 -> 사용자명 system -> 비밀번호 pw1234 -> show user입력 = 확인
- 오라클 설치 경로 = C:\app\user\product\21c\dbhomeXE
DBMS 개발(사용)툴 - IDE
- SQL Developer(디벨로퍼)
- SQL 언어 : DDL(정의어), DML(조작어), DCL(제어어)
Delete = 데이터 삭제, 테이블 유지 => DML
Drop = 데이터 삭제, 테이블 삭제 = > DDL
-- 부서(dept)와 사원 테이블 생성
CREATE TABLE department(
deptid NUMBER PRIMARY KEY, -- 기본키
deptname VARCHAR2(20) NOT NULL, -- NULL 불허 (값이 비어있으면 안됨)
location VARCHAR2(20) NOT NULL
);
-- 부서 자료 추가
INSERT INTO department(deptid, deptname, location)
VALUES (10, '전산팀', '서울');
INSERT INTO department(deptid, deptname, location)
VALUES (2, '관리팀', '인천');
INSERT INTO department(deptid, deptname, location)
VALUES (30, '마케팅팀', '수원');
-- 자료 검색 (특정 칼럼 검색)
SELECT deptid, deptname FROM department;
-- 모든 칼럼 검색 ('*' 사용)
SELECT * FROM department;
-- 특정한 데이터(행:로우) 검색 -> WHERE 조건절 사용
-- 부서이름이 전산팀인 row(레코드) 검색
SELECT * FROM department
WHERE deptname = '전산팀';
-- 자료 수정(부서 이름 변경 - 관리팀 -> 경영팀)
UPDATE department SET deptname = '경영팀'
WHERE deptid = 20;
-- 마지막 COMMIT한 시점 까지 실행 취소
ROLLBACK;
-- 자료 삭제(부서 번호가 30번인 마케팅팀 삭제)
-- 삭제 이상(자식이 참조하고 있으므로 삭제 안됨)
DELETE FROM department
WHERE deptid = 10;
-- 영속화
COMMIT;
-- 사원 테이블 생성
CREATE TABLE employee(
empid NUMBER(3),
empname VARCHAR2(20) NOT NULL,
age NUMBER(3),
deptid NUMBER,
PRIMARY KEY(empid), -- 기본키
FOREIGN KEY(deptid) REFERENCES department(deptid) -- 외래키
);
-- 사원 자료 추가
INSERT INTO employee(empid, empname, age, deptid)
VALUES (101, '이강', 27, 10);
INSERT INTO employee(empid, empname, age, deptid)
-- 부서코드가 30이라면 부서코드가 없어서 외래키 제약조건 위배, 삽입 이상
VALUES (102, '김산', 34, 30);
INSERT INTO employee(empid, empname, deptid)
VALUES (103, '정들', 20);
INSERT INTO employee(empid, empname, age, deptid)
VALUES (104, '남한강', 41, 20);
-- 모든 사원의 정보 출력
SELECT * FROM employee;
-- 사원 이름과 나이 칼럼 출력
SELECT empname, age FROM employee;
-- 사원 이름이 김산인 데이터 출력
SELECT * FROM employee
WHERE empname = '김산';
-- 나이가 30세 이상인 사원 검색
SELECT * FROM employee
WHERE age >= 30;
-- 부서번호가 20인 사원 검색
SELECT * FROM employee
WHERE deptid = 20;
-- 나이가 입력되지 않은 사원 검색
SELECT * FROM employee
WHERE age IS NULL;
-- 문자열 검색(사원 이름에서 '강'이 들어있는 사원 검색) => LIKE '%문자열%'
SELECT * FROM employee
WHERE empname LIKE '%강%' OR age IS NULL; -- AND, OR 사용 가능
SELECT * FROM employee
WHERE empname LIKE '%강%' AND age IS NULL; -- AND, OR 사용 가능
COMMIT;
DROP TABLE employee;
ER = entity relationship - 개체(개체의 특성을 나타내는 속성으로 식별)와 개체 간의 관계로 표현
- IE 표기법 = 관계 대응 수를 새발 모양의 기호로 표현 = 새발 표기법(crow-feet)
PK = primary key 기본키 - 중복 체크, NOT NULL속성
FK = Foreign key 외래기 - 두 테이블 간의 종속이 필요한 관계이면
그 접점이 되는 컬럼을 FK로 지정하여
서로 참조할 수 있도록 관계를 맺어준다
관계를 맺게 되면 삽입, 삭제시 이상이 일어날 수 있다
삽입 이상 = 자식
삭제 이상 = 부모
<<JAVA>>
- TCP 네트워킹 (신뢰성 중시)
- 에코서버, 클라이언트
서버 -> 동시 요청 처리
ExecutorService = Executor interface(Executor.execute();)를 상속받은 interface
스레드를 생성하고 관리하는 서비스를 제공
스레드 풀을 사용하여 해당작업의 실행을 관리할 수 있음
고정 크기 생성 방법 : newFixedThreadPool(10)
* 실행 메서드
executorService.execute(()->{}) : 매개변수로 람다식 구현
package network.socket3;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EchoServer {
// 서버 소켓 객체 선언
private static ServerSocket serverSocket;
// 서버에서 동시 처리할 스레드풀 10개 생성
private static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) {
System.out.println("==========================================");
System.out.println("서버를 종료하려면 q 또는 Q를 입력하고 Enter를 누르세요");
System.out.println("==========================================");
// TCP 서버 시작
startServer();
Scanner scanner = new Scanner(System.in);
while(true) {
String key = scanner.nextLine();
if(key.toLowerCase().equals("q"))
break;
}
scanner.close();
// TCP서버 종료
stopServer();
}
private static void startServer() {
// 작업 스레드 생성
Thread thread = new Thread() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(50001);
System.out.println("[서버] 시작");
while(true) {
System.out.println("\n[서버] 연결 요청을 기다림\n");
// 서버가 연결 요청 수락함
Socket socket = serverSocket.accept(); // 클라이언트와 통신할 소켓 생성
// 서버의 동시 처리(스레드 풀 사용)
// Runnable은 함수형 인터페이스이므로 람다식으로 구현 가능
// 추상메서드 void run(); = 매개변수가 없음 => 그래서 execute람다식도 매개변수X
executorService.execute(() -> {
try {
// IP 주소 알아내기
InetSocketAddress isa = (InetSocketAddress) socket.getRemoteSocketAddress();
String clientIp = isa.getHostString();
System.out.println("[서버]" + clientIp + "의 연결 요청을 수락함");
// 웹 브라우저에서 http://127.0.0.1:50001/ 입력 - 콘솔에서 확인
// 클라이언트가 보낸 데이터 받기
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024]; // 데이터를 저장할 배열 선언
int readBytes = is.read(bytes);
// 데이터를 문자열로 생성
String message = new String(bytes, 0, readBytes, "utf-8");
// 받은 데이터 보내기
OutputStream os = socket.getOutputStream();
bytes = message.getBytes("utf-8"); // 인코딩
os.write(bytes);
os.flush();
System.out.println("[서버] 받은 데이터를 다시 보냄: " + message);
socket.close();
System.out.println("[서버]" + clientIp + "의 연결을 끊음");
}catch(IOException e) {
System.out.println("[서버] " + e.getMessage());
}
}); // execute 끝
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println("[서버] " + e.toString() + "의 연결을 끊음");
}
}
};
thread.start(); // 서버 스레드 시작
}// startServer 끝
private static void stopServer() {
try {
serverSocket.close();
executorService.shutdown();
System.out.println("[서버] 종료됨");
} catch (IOException e) {
e.printStackTrace();
}
}
}
package network.socket3;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class EchoClient {
public static void main(String[] args) {
try {
// Socket 객체 생성 및 연결 요청
Socket socket = new Socket("localhost", 50001);
System.out.println("[클라이언트] 연결 성공");
// 데이터 보내기
String sendMessage = "오늘도 즐거운 하루 되세요";
OutputStream os = socket.getOutputStream();
byte[] bytes = sendMessage.getBytes("utf-8"); // 인코딩
os.write(bytes);
os.flush();
System.out.println("[클라이언트] 데이터 보냄: " + sendMessage);
// 서버가 보낸 데이터 받기
InputStream is = socket.getInputStream();
bytes = new byte[1024];
int readBytes = is.read(bytes);
// 문자열로 복원(디코딩)
String receiveMessage = new String(bytes,0,readBytes,"utf-8");
System.out.println("[클라이언트] 데이터 받음: " + receiveMessage);
socket.close();
System.out.println("[클라이언트] 연결 끊음");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- UDP 네트워킹 (속도 중시)
Datagram - Socket = 통신 (발신점, 수신점)
- Packet = 데이터
뉴스 서버(주제를 요청하면 데이터를 보내줌)
NewsServer - ClientServer
DatagramSocket
DatagramPacket
(Networking - udpnetwork)
HTML 공부
<<VSCode Emmet>>
에밋을 실행하면 마크업으로 확장된다
=> 축약된 구문을 이용해 HTML 요소들을 빠르게 생성할 수 있다
<자식 요소를 만드는 문법>
= ' > ' 이용
ex. nav>ul>li -> Tab
=> <nav>
<ul>
<li> </li>
</ul>
</nav>
<형제 요소를 만드는 문법>
= ' + ' 이용
ex. div+p+bq
=> <div></div>
<p></p>
<blockquote></blockquote>
<곱하기 요소 문법>
= ' * ' 이용
ex. ul>li*5
=> <ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
=> 유사한 작업을 한번에 할 때 도움이 된다
* $ = 순서를 입력해준다
=> 넘버링 작업에 도움을 준다
* 새로운 요소에 텍스트를 넣고 싶은 경우
= {} 이용
ex. a{Click me}
= <a href="">Click me</a>
<<HTML 표>>
표 = 데이터 테이블을 말하는 것
=> 2차원 행과 열 구조로 되어있다
=> 표 형식으로 표시하고 싶은 정보를 담은 테이블 데이터와 행과 열에 대해 만들어져야 한다
테이블 데이터 = 대개 일부 데이터를 근사하고 명확하게 표시하는 방법
표 -> 테이블 형식에 적합한 정보를 보여주는 경우 사용
-> 표 하나에 들어갈 수 있는 요소들이 아주 많다
<표의 요소>
* <td>요소
td = 테이블 데이터 셀, 테이블 데이터를 줄인 말
d = 단일 셀
=> td = 데이터를 포함한 표 안에 있는 단일 셀을 정의한다
-> <td>내용</td> 형식으로 셀을 생성한다
=> 하나하나 모두 셀이지만 모두 같은 선 위에 있다
= 모두 같은 행 안에 있다
* <tr>요소
tr = table row를 줄인 말
= 표 안에 있는 셀들이 모인 행을 의미
=> 행들을 하나의 tr에 넣는 것
=> 여러개의 행 생성 가능
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
// => 2개의 행이 생긴다
* <th>요소
= 헤더를 정의한다 -> 헤더를 행 안에 넣는다
열이 세개 있으면 헤더 세개가 여기 있다고 표시를 해주어야 한다
=> <th>요소들이 필요
=> 초기 값으로 굵은 글씨체
<tr>
<th></th>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<표 섹션 추가 요소>
=> 표를 논리 섹션으로 분리하는 작업 외에는 하는 일이 없다
그 섹션을 통해 무엇이 헤더인지 푸터인지 바디인지 구별 가능
=> 3요소로 행을 처리하는 것
표가 복잡한 경우 -> 이해하기 쉬운 표를 만드는 데에 중요한 역할
-> 접근성 목적에서도 중요
* <thead>
표의 헤더들을 모은 것
이 요소로 wrap처리를 해서 모두 표의 헤더임을 명확히 밝혀야 한다
* <tfoot>
누계, 평균, 총합 등의 정보
없는 경우도 있다
* <tbody>
표의 주요 데이터
Coding Test Practice
Description
문자열 my_string과 정수 배열 indices가 주어질 때, my_string에서 indices의 원소에 해당하는 인덱스의 글자를 지우고 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.
function solution(my_string, indices) {
var answer = '';
indices = indices.sort();
for(var i = 0; i < my_string.length; i++){
if(!indices.includes(i)){
answer += my_string[i]
}
}
return answer;
}
Description
문자열 my_string과 정수 s, e가 매개변수로 주어질 때, my_string에서 인덱스 s부터 인덱스 e까지를 뒤집은 문자열을 return 하는 solution 함수를 작성해 주세요.
function solution(my_string, s, e) {
var answer = '';
var reverse = my_string.slice(s,e + 1).split("").reverse().join("");
for(var i = 0; i < my_string.length; i++){
if(i >= s && i <= e ){
answer += reverse[i-s]
}else{
answer += my_string[i]
}
}
return answer;
}
Description
정수가 있을 때, 짝수라면 반으로 나누고, 홀수라면 1을 뺀 뒤 반으로 나누면, 마지막엔 1이 됩니다. 예를 들어 10이 있다면 다음과 같은 과정으로 1이 됩니다.
10 / 2 = 5
(5 - 1) / 2 = 4
4 / 2 = 2
2 / 2 = 1
위와 같이 4번의 나누기 연산으로 1이 되었습니다.
정수들이 담긴 리스트 num_list가 주어질 때, num_list의 모든 원소를 1로 만들기 위해서 필요한 나누기 연산의 횟수를 return하도록 solution 함수를 완성해주세요.
function solution(num_list) {
var times = 0;
for(var i = 0; i < num_list.length; i++){
var num = num_list[i];
while(num != 1) {
if(num % 2 == 0){
num /= 2;
}else{
num = (num -1) / 2;
}
times++
}
}
return times;
}
2023. 10. 10 (화)
프로그래머 도전기 43일차 (0) | 2023.10.13 |
---|---|
프로그래머 도전기 42일차 (4) | 2023.10.12 |
프로그래머 도전기 40일차 (0) | 2023.10.09 |
프로그래머 도전기 39일차 (1) | 2023.10.07 |
프로그래머 도전기 38일차 (2) | 2023.10.06 |