심심풀이 문제2 - String
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Test { public static void main(String[] args) { String a = "CGun"; String b = new String("CGun"); String c = a; String d = b; a += " Good"; b += " Good"; System.out.println(c); System.out.println(d); } } | cs |
정답
해설
"java string immutable" 혹은 "java string 불변"
으로 검색해보시면 많은 정보를 얻으실 수 있습니다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제4 - Object Assign (객체 대입) (0) | 2016.10.04 |
---|---|
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors) (0) | 2016.08.02 |
심심풀이 문제1 - Object.equals() (0) | 2016.07.16 |
[Collection] ArrayList vs Vector (0) | 2016.02.01 |
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors)
이유1: 객체 생성시 초기화 작업
일반 변수들의 경우, 생성자 없이 전역에서 바로 초기화를 해줘도 됩니다.
하지만 불가능해서 꼭 생성자에서 초기화를 해줘야하는 경우도 있습니다.
1 2 3 4 5 | import java.io.FileInputStream; public class FileHandler { private FileInputStream fis = new FileInputStream("\tmpFile"); } | cs |
위 코드는 컴파일에러가 발생하며, 아래와 같이 수정해야 합니다.
1 2 3 4 5 6 7 8 9 10 | import java.io.FileInputStream; import java.io.FileNotFoundException; public class FileHandler { private FileInputStream fis; public FileHandler() throws FileNotFoundException { fis = new FileInputStream("\tmpFile"); } } | cs |
new FileInputStream() 에서 FileNotFoundException 을 throw 하므로 받아줘야 하기 때문입니다.
이유2: 객체 생성시 필수입력값을 강제하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public class Human { private String name; private String nickName; private int age; public Human(String name) { this.name = name; } public void setNickName(String nickName) { this.nickName = nickName; } public void setAge(int age) { this.age = age; } } | cs |
사람 객체를 생성시 name 을 필수입력 항목으로 강제하는 코드입니다.
그외 nickName 과 age 는 원하는 경우에 한해 set 함수로 입력할 수 있습니다.
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제3 - Call by Value vs Call by Reference (0) | 2016.10.04 |
---|---|
심심풀이 문제2 - String (0) | 2016.08.02 |
심심풀이 문제1 - Object.equals() (0) | 2016.07.16 |
[Collection] ArrayList vs Vector (0) | 2016.02.01 |
String vs StringBuilder vs StringBuffer (2) | 2016.01.28 |
심심풀이 문제1 - Object.equals()
문제
출력 결과는 무엇일까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class Test { public static void main(String[] args) { User a = new User("CGun", 29); User b = new User("CGun", 29); User c = a; System.out.println(a == b); System.out.println(a == c); System.out.println(a.equals(b)); } public static class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } } } | cs |
정답
해설
위 소스코드를 자세히 보시면 User 클래스 안에 equals() 메서드가 없습니다.
근데 왜 컴파일 에러가 안날까요?
Java 에서 모든 클래스들은 기본적으로 Object 클래스를 상속받습니다.
extends Object 가 생략되었을 뿐입니다.
그리고 이 Object 클래스 안에 equals() 메서드가 존재하고 있으며, 소스코드는 아래와 같습니다.
네. 따라서 a.equals(b) 는 a == b 와 완전히 같습니다.
String.equals() 문제에 익숙한 분들을 향한 함정 문제였습니다.
참고
출처
'뿌리튼튼 CS > Java' 카테고리의 다른 글
심심풀이 문제2 - String (0) | 2016.08.02 |
---|---|
생성자를 쓰는 이유. 생성자의 필요성 (Why use constructors) (0) | 2016.08.02 |
[Collection] ArrayList vs Vector (0) | 2016.02.01 |
String vs StringBuilder vs StringBuffer (2) | 2016.01.28 |
Array size in Loops (0) | 2015.07.31 |
[JavaScript(ES6)] Promise
프라미스 (Promise) 란
비동기적으로 결과를 리턴하는 함수에 대한 비동기 프로그래밍 패턴의 일종이다.
(※ 매우 중요한 개념이므로 필히 익히시기를 추천합니다.)
A부터 Z까지 Promises 의 모든 것
http://www.html5rocks.com/ko/tutorials/es6/promises/
너무도 완벽한 글을 찾아서 본문 없이 그냥 위 링크로 대체합니다.
한편, 퀄리티가 이 정도로 좋은 글을 쓰는 사람은 어떤 사람인지 궁금해서 찾아보았습니다.
네... 그렇습니다. 구글러네요.
전공적인 깊은 이해는 물론이고 글솜씨와 전개방식도 완벽합니다.
존경합니다.
'뿌리튼튼 CS > Web' 카테고리의 다른 글
구형 브라우저에서의 HTML5 (HTML5 Browser Support) (0) | 2016.06.11 |
---|---|
[JavaScript(ES6)] Proxy (0) | 2016.05.19 |
[JavaScript(ES6)] Iterators and Generators (0) | 2016.05.16 |
[JavaScript] DOM 엑세스 줄이기 (Reduce DOM Access) (0) | 2015.08.03 |
[JavaScript] Loose Comparison vs. Strict Comparison (0) | 2015.07.31 |
구형 브라우저에서의 HTML5 (HTML5 Browser Support)
우리는 구형 브라우저가 HTML5 를 올바르게 다룰 수 있도록 지도할 수 있다. 심지어 Windows XP 2001 의 IE6 도 가능하다. |
최종 해결책
1 2 3 | <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> | cs |
위 세 줄을 <head> 영역에 써주면 된다.
원리1. CSS 를 통한 대응
예를 들어 구형 브라우저 입장에서 Unknown Elements 인 HTML5 Elements 에 대하여 아래와 같이 대응할 수 있다.
1 2 3 | header, section, footer, aside, nav, main, article, figure { display: block; } | cs |
원리2. 새로운 사용자 정의 Element 추가하기
같은 원리로 새로운 Element 를 HTML 에 추가할 수도 있다:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!DOCTYPE html> <html> <head> <title>New element</title> <script>document.createElement("myHero")</script> <style> myHero { display:block; background-color:#ddd; padding: 50px; font-size: 30px; } </style> </head> <body> <myHero>My First Hero</myHero> </body> | cs |
원리3. 인터넷 익스플로러 (Internet Explorer) 의 문제점
위의 원리2 의 해결책을 통해 모든 HTML5 Elements 에 대응할 수 있지만,
IE8 이하에서는 unknown elements 에 대한 css 적용을 허용하지 않는 문제점이 있다.
이것까지 해결한 것이 "the shiv" 라는 js 파일이다:
1 2 3 | <!--[if lt IE 9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> | cs |
이 코드는 주석이지만 IE9 미만의 버전에서는 단순 주석이 아니라 실제 코드로써 동작한다.
출처
http://www.w3schools.com/html/html5_browsers.asp
'뿌리튼튼 CS > Web' 카테고리의 다른 글
[JavaScript(ES6)] Promise (0) | 2016.06.22 |
---|---|
[JavaScript(ES6)] Proxy (0) | 2016.05.19 |
[JavaScript(ES6)] Iterators and Generators (0) | 2016.05.16 |
[JavaScript] DOM 엑세스 줄이기 (Reduce DOM Access) (0) | 2015.08.03 |
[JavaScript] Loose Comparison vs. Strict Comparison (0) | 2015.07.31 |
[JavaScript(ES6)] Proxy
프록시 (Proxy) 란
Proxy 의 사전적 의미는 "대행", "대리", "위임" 이다.
프록시 (Proxy) 는 객체에 수행되는 동작들 (예를들면 속성값 조회, 변경) 을 가로챌 수 있게 해주고, 커스터마이징도 할 수 있게 해주는 일종의 객체 감싸미다.
프록시는 세 요소로 구성된다:
* 타겟 (target) : 프록시로 감쌀 대상 객체. * 핸들러 (handler) : 트랩 메서드들을 담고 있는 객체. 타겟에 대한 동작을 감지하여 그에 대응하는 트랩 메서드가 존재할 경우 해당 트랩 메서드를 호출한다. * 트랩 (trap) : 핸들러 안에 존재하는 메서드. 타겟 객체에 대한 동작을 가로채며, 사용자 정의 로직을 넣을 수 있다. |
아래는 프록시를 적용한 예제 코드이다. 여기서는 트랩으로 get, deleteProperty 가 사용되었다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var target = {a: 1}; var handler = { get: function(target, key) { // any custom logic console.log('GET: ' + key); return target[key]; }, deleteProperty: function(target, key) { // any custom logic console.log('DELETE: ' + key); return delete target[key]; } }; var proxiedTarget = new Proxy(target, handler); console.log(proxiedTarget.a); // GET: a // 1 console.log(proxiedTarget.b); // GET: b // undefined delete proxiedTarget.a; // DELETE: a | cs |
Reflect
ECMAScript 6 에서는 모든 트랩에 대하여 포워딩을 도와주는 Reflect 라는 객체가 추가되었다:
handler.trap(target, arg_1, ···, arg_n) 위와 같은 모든 trap 메서드에 대응하는 Reflect.trap(target, arg_1, ···, arg_n) 이 존재한다. |
Reflect 를 이용한 포워딩 (Forwarding intercepted operations with Reflect):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | var target = {a: 1}; var handler = { get: function(target, key) { // any custom logic console.log('GET: ' + key); return Reflect.get(target, key); }, deleteProperty: function(target, key) { // any custom logic console.log('DELETE: ' + key); return Reflect.deleteProperty(target, key); } }; var proxiedTarget = new Proxy(target, handler); console.log(proxiedTarget.a); // GET: a // 1 console.log(proxiedTarget.b); // GET: b // undefined delete proxiedTarget.a; // DELETE: a | cs |
Why Proxy? Proxy 의 강력한 활용
아래 코드를 이해하면 Proxy 의 강력함을 느낄 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | let normalObj = {name: 'CGun'}; let dfObj = makeDefensiveObject(normalObj); /* [1] name */ console.log(dfObj.name); // GET: name // CGun /* [2] marriage */ console.log(dfObj.marriage); // GET: marriage // Uncaught ReferenceError: marriage does not exist. dfObj.marriage = 'x'; // SET: marriage, x // Uncaught TypeError: marriage should be "기혼" or "미혼" dfObj.marriage = '미혼'; // SET: marriage, 미혼 console.log(dfObj.marriage); // GET: marriage // 미혼 /* [3] age */ console.log(dfObj.age); // GET: age // Uncaught ReferenceError: age does not exist. dfObj.age = 'x'; // SET: age, x // Uncaught TypeError: The age is not an integer dfObj.age = -30; // SET: age, -30 // Uncaught RangeError: The age seems invalid dfObj.age = 29; // SET: age, 29 console.log(dfObj.age); // GET: age // 29 /* [4] grade */ console.log(dfObj.grade); // GET: grade // Uncaught ReferenceError: grade does not exist. dfObj.grade = 80; // SET: grade, 80 // Uncaught TypeError: grade should be "A" to "F" dfObj.grade = 'b'; // SET: grade, b console.log(dfObj.grade); // GET: grade // B /* [5] Proxy */ function makeDefensiveObject(target) { if (target === undefined) { target = {}; } let handler = { get: function(target, key) { console.log('GET: ' + key); if (!(key in target)) { throw new ReferenceError(key + ' does not exist.'); } if (key == 'marriage') { return Reflect.get(target, key) === true ? '기혼' : '미혼'; } return Reflect.get(target, key); }, set: function(target, key, value) { console.log('SET: ' + key + ', ' + value); if (key == 'marriage') { if (value == '기혼') { value = true; } else if (value == '미혼') { value = false; } else { throw new TypeError('marriage should be "기혼" or "미혼"'); } } if (key == 'age') { if (!Number.isInteger(value)) { throw new TypeError('The age is not an integer'); } if (value < 0 || value > 150) { throw new RangeError('The age seems invalid'); } } if (key == 'grade') { if (!value || value.length != 1) { throw new TypeError('grade should be "A" to "F"'); } value = value.toUpperCase(); if (value < 'A' || value > 'F') { throw new RangeError('The grade seems invalid'); } } return Reflect.set(target, key, value); } }; return new Proxy(target, handler); } | cs |
Revocable proxy
ECMAScript 6 에서는 취소가 가능한 (스위치를 끌 수 있는) 프록시가 추가되었다:
1 | var {proxy, revoke} = Proxy.revocable(target, handler); | cs |
revoke 함수를 실행하고 나면 해당 proxy 가 취소되며, 사용하려고 하면 TypeError 가 발생한다:
1 2 3 4 5 6 7 8 9 10 | var target = {}; // Start with an empty object var handler = {}; // Don’t intercept anything var {proxy, revoke} = Proxy.revocable(target, handler); proxy.foo = 123; console.log(proxy.foo); // 123 revoke(); console.log(proxy.foo); // TypeError: Revoked | cs |
출처
http://exploringjs.com/es6/ch_proxies.html
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Proxy
'뿌리튼튼 CS > Web' 카테고리의 다른 글
[JavaScript(ES6)] Promise (0) | 2016.06.22 |
---|---|
구형 브라우저에서의 HTML5 (HTML5 Browser Support) (0) | 2016.06.11 |
[JavaScript(ES6)] Iterators and Generators (0) | 2016.05.16 |
[JavaScript] DOM 엑세스 줄이기 (Reduce DOM Access) (0) | 2015.08.03 |
[JavaScript] Loose Comparison vs. Strict Comparison (0) | 2015.07.31 |
[JavaScript(ES6)] Iterators and Generators
한 collection 에서 각각의 아이템을 순회하는 것은 매우 흔한 작업이다. Iterator 와 Generator 는 iteration 에 대한 직접적인 적용 및 커스터마이징 메커니즘을 제공한다. |
ES6 에서의 Iterator (Iterator in ES6)
Iterator 는 새로운 문법이나 built-in 이 아니라 프로토콜(약속)이다.
이 프로토콜은 몇 가지 규칙만 준수한다면 어떠한 객체에서도 구현될 수 있다.
Iterator 프로토콜 (The iterator protocol)
Iterable 한 객체가 되려면 Symbol.iterator 를 Key 로 갖는 속성이 반드시 존재해야 한다:
Property |
Value |
[Symbol.iterator] |
Iterator 프로토콜을 준수하는 객체를 리턴하며 인자가 없는 함수 |
다음 규칙에 따라 next() 메서드를 구현한 객체를 iterator 라고 한다:
Property |
Value |
next |
아래의 두 속성을 가지는 객체를 리턴하며 인자가 없는 함수: 1. done (boolean) * iterator 가 순회를 모두 마쳤을 경우 true * iterator 가 순회할 다음 value 가 존재할 경우 false 2. value - iterator 에 의해 리턴될 값. done 이 true 일 경우 생략 가능 |
Iterable 하며 Iterator 프로토콜을 만족하는 예시 코드:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var someObject = {}; ... someObject[Symbol.iterator] = function () { var num = 1; return { next: function() { return num < 4 ? {value: num++, done: false} : {done: true}; } }; }; ... for (let value of someObject) { console.log(value); } // 1 // 2 // 3 | cs |
Generators
커스텀 iterator 는 유용하지만, 그 내부 상태를 유지하기 위한 매우 세심한 관리를 필요로 한다.
Generator 는 이에 대한 강력한 대안이다: 내부 상태를 스스로 유지하는 하나의 함수만 작성하면 된다.
Generator 는 iterator 를 위한 factory 함수의 일종이다.
하나 이상의 yield expression 을 가지며 function* 문법을 사용하는 함수를 Generator 라고 한다.
Generator 예시 코드:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var someObject = {}; ... someObject[Symbol.iterator] = function* () { var num = 1; while (num < 4) { yield num++; } }; ... for (let value of someObject) { console.log(value); } // 1 // 2 // 3 | cs |
특이한 예제 코드 (Examples)
무한 iterator (infinite iterator):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function idMaker(){ var index = 0; return { next: function(){ return {value: index++, done: false}; } }; } var it = idMaker(); console.log(it.next().value); // '0' console.log(it.next().value); // '1' console.log(it.next().value); // '2' // ... | cs |
Generator 를 사용한 무한 iterator (Infinite iterator with a generator):
1 2 3 4 5 6 7 8 9 10 11 12 | function* idMaker(){ var index = 0; while(true) yield index++; } var gen = idMaker(); console.log(gen.next().value); // '0' console.log(gen.next().value); // '1' console.log(gen.next().value); // '2' // ... | cs |
출처
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
'뿌리튼튼 CS > Web' 카테고리의 다른 글
구형 브라우저에서의 HTML5 (HTML5 Browser Support) (0) | 2016.06.11 |
---|---|
[JavaScript(ES6)] Proxy (0) | 2016.05.19 |
[JavaScript] DOM 엑세스 줄이기 (Reduce DOM Access) (0) | 2015.08.03 |
[JavaScript] Loose Comparison vs. Strict Comparison (0) | 2015.07.31 |
[JavaScript] 함수에 인자에 default 값을 넣어주자 (Use Parameter Defaults) (0) | 2015.07.31 |
프로세스(Process)의 상태 전이, 스케쥴링(Scheduling)
프로세스가 생성되면 Ready 상태가 된다.
Ready 상태란, cpu를 기다리는 상태이다.
그리고 곧 Running 상태로 넘어가서 cpu에게 실행된다.
Running 상태란, cpu에게 실행되어지고 있는 상태이다.
그러다가 자신에게 주어진 cpu 단위 사용시간 (cpu time quantum) 을 모두 소비하거나, 혹은 더 높은 우선순위의 작업 (예를들어 인터럽트) 에게 cpu를 선점당할 경우 다시 Ready 상태로 돌아가서 줄을 선다.
만약 Running 상태에 있다가 block I/O 등 시간이 오래 걸리는 함수 (예를들어 fopen) 를 호출한 경우 해당 함수가 리턴될 때까지 Waiting 상태가 된다.
Waiting 상태란 Sleep 상태와 같다. cpu를 기다리는 게 아니라 해당 I/O 의 종료를 기다린다. 신호 수신을 통해 Sleep 에서 깨어나면 Ready 상태가 되어 cpu에게 다시 실행되기를 기다린다.
프로세스가 종료될 때까지 위 과정이 반복된다.
출처 : 2015년 한양대학교 강수용 교수님의 수업 및 내 지식