Skip to content

Commit c8a4a41

Browse files
committed
best practice
1 parent be4d745 commit c8a4a41

40 files changed

Lines changed: 1310 additions & 0 deletions

ee/src/interview/DoubleCheckLesson.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,11 @@ public static Singleton getInstance() {
1919
}
2020
return singleton;
2121
}
22+
public Singleton getField() {
23+
Singleton result = singleton;
24+
if (result == null)
25+
singleton = result = new Singleton();
26+
return result;
27+
}
2228
}
2329
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package bestpractice;
2+
3+
import java.util.*;
4+
import java.util.concurrent.CopyOnWriteArrayList;
5+
import java.util.concurrent.ExecutionException;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.Executors;
8+
9+
//don't run alien methods on sync blocks, it can cause exceptions, deadlocks, or data corruption
10+
//you should do as little work as possible inside synchronized regions
11+
public class AvoidExcessiveSync {
12+
public static void main(String[] args) {
13+
ObservableSet<Integer> set = new ObservableSet<Integer>(new HashSet<Integer>());
14+
set.addObserver(new SetObserver<Integer>() {
15+
public void added(ObservableSet<Integer> s, Integer e) {
16+
System.out.println(e);
17+
if (e == 20) {
18+
ExecutorService executor = Executors.newSingleThreadExecutor();
19+
final SetObserver<Integer> observer = this;
20+
try {
21+
executor.submit(new Runnable() {
22+
public void run() {
23+
s.removeObserver(observer);
24+
}
25+
}).get();
26+
} catch (ExecutionException | InterruptedException ex) {
27+
throw new AssertionError(ex.getCause());
28+
} finally {
29+
executor.shutdown();
30+
}
31+
}
32+
}
33+
});
34+
for (int i = 0; i < 100; i++)
35+
set.add(i);
36+
}
37+
}
38+
class ObservableSet<E> extends HashSet<E> {
39+
public ObservableSet(Set<E> set) { super(set); }
40+
private final List<SetObserver<E>> observers = new CopyOnWriteArrayList<>();
41+
public synchronized void addObserver(SetObserver<E> observer) {
42+
observers.add(observer);
43+
}
44+
public synchronized boolean removeObserver(SetObserver<E> observer) {
45+
return observers.remove(observer);
46+
}
47+
private void notifyElementAdded(E element) {
48+
for (SetObserver<E> observer : observers)
49+
observer.added(this, element);
50+
}
51+
@Override public boolean add(E element) {
52+
boolean added = super.add(element);
53+
if (added)
54+
notifyElementAdded(element);
55+
return added;
56+
}
57+
@Override public boolean addAll(Collection<? extends E> c) {
58+
boolean result = false;
59+
for (E element : c)
60+
result |= add(element);
61+
return result;
62+
}
63+
}
64+
interface SetObserver<E> {
65+
void added(ObservableSet<E> set, E element);
66+
}
67+
68+
// if (e == 20) s.removeObserver(this);
69+
// if (e == 20) {
70+
// ExecutorService executor = Executors.newSingleThreadExecutor();
71+
// final SetObserver<Integer> observer = this;
72+
// try {
73+
// executor.submit(new Runnable() {
74+
// public void run() {
75+
// s.removeObserver(observer);
76+
// }
77+
// }).get();
78+
// } catch (ExecutionException | InterruptedException ex) {
79+
// throw new AssertionError(ex.getCause());
80+
// } finally {
81+
// executor.shutdown();
82+
// }
83+
// }
84+
85+
// List<SetObserver<E>> snapshot = null;
86+
//synchronized(observers) {
87+
// snapshot = new ArrayList<>(observers);
88+
// }
89+
// for (SetObserver<E> observer : snapshot)
90+
// observer.added(this, element);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package bestpractice;
2+
3+
//Throwable, Error, Exception, RuntimeException, IOException
4+
//it’s best not to implement any new Error subclasses
5+
//don't use Throwable, use Exception or RuntimeException
6+
//use checked exceptions for conditions from which the caller can reasonably be expected to recover
7+
//checked - when can restore //unchecked - when execution cad make more harm
8+
//Use runtime exceptions to indicate programming errors //precondition violations
9+
10+
//A well-designed API must not force its clients to use exceptions for ordinary control flow //instead of error codes
11+
//Cloneable //CloneNotSupportedException
12+
//ask yourself how the programmer will handle the exception
13+
public class CheckedVsUncheckedExceptions {
14+
public static void main(String[] args) throws Exception {
15+
CheckedVsUncheckedExceptions checkedVsUncheckedExceptions = new CheckedVsUncheckedExceptions();
16+
long time = System.currentTimeMillis();
17+
checkedVsUncheckedExceptions.doJob(10_000);
18+
System.out.println(System.currentTimeMillis() - time);
19+
}
20+
public void doJob(long l) throws Exception {
21+
if (l > 0) {
22+
l--;
23+
doJob(l);
24+
}
25+
}
26+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package bestpractice;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
//no constructor
7+
//never make the client do anything the library can do for the client
8+
//final fields problem
9+
//creation time
10+
//use constructor or factory analog //can use interface
11+
public class CloneableLesson implements Cloneable {
12+
int i;
13+
private Object[] elements;
14+
public CloneableLesson() {
15+
System.out.println("this is constructor");
16+
}
17+
18+
public static void main(String[] args) throws CloneNotSupportedException {
19+
CloneableLesson cloneableLesson = new CloneableLesson();
20+
CloneableLesson cloneableLesson2 = cloneableLesson.clone();
21+
System.out.println(cloneableLesson != cloneableLesson2);
22+
System.out.println(cloneableLesson.getClass() == cloneableLesson2.getClass());
23+
System.out.println(cloneableLesson.equals(cloneableLesson2.getClass()));
24+
//example
25+
List list = new ArrayList();
26+
List list2 = new ArrayList(list);
27+
}
28+
public static CloneableLesson makeCopy(CloneableLesson cloneableLesson) {
29+
//make copy;
30+
return cloneableLesson;
31+
}
32+
@Override
33+
protected CloneableLesson clone() {
34+
CloneableLesson result = null;
35+
try {
36+
result = (CloneableLesson) super.clone();
37+
result.elements = elements.clone();
38+
} catch (CloneNotSupportedException e) {
39+
e.printStackTrace();
40+
}
41+
return result;
42+
}
43+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package bestpractice;
2+
3+
import java.util.*;
4+
5+
//inheritance is bad //in package is norm or good documented //interface is good
6+
//inheritance violates encapsulation //subclass depends on the implementation details of its superclass
7+
//override and verify all methods problem
8+
//add new method could override in the future //and we don't know the contract
9+
//it's wrapper//no performance and memory issues
10+
//inheritance only if a is b //stack is not a vector //Properties -> Hashtable
11+
//inheritance propagates any flaws, while composition lets you design a new API that hides these flaws
12+
public class CompositionOverInheritance {
13+
public static void main(String[] args) {
14+
InstrumentedSet<String> s = new InstrumentedSet<>();
15+
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
16+
System.out.println(s.getAddCount());
17+
}
18+
}
19+
20+
class InstrumentedHashSet<E> extends HashSet<E> {
21+
private int addCount = 0;
22+
@Override public boolean add(E e) {
23+
if(e instanceof String) return false;
24+
addCount++;
25+
return super.add(e);
26+
}
27+
@Override public boolean addAll(Collection<? extends E> c) {
28+
addCount += c.size();
29+
return super.addAll(c);
30+
}
31+
public int getAddCount() {
32+
return addCount;
33+
}
34+
}
35+
36+
class InstrumentedSet<E> {
37+
private int addCount = 0;
38+
private final Set<E> set = new HashSet<E>();
39+
40+
public boolean add(E e) {
41+
if(e instanceof String) return false;
42+
addCount++;
43+
return set.add(e);
44+
}
45+
public boolean addAll(Collection<? extends E> c) {
46+
addCount += c.size();
47+
return set.addAll(c);
48+
}
49+
public int getAddCount() {
50+
return addCount;
51+
}
52+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package bestpractice;
2+
3+
//don't use lazy initialization
4+
//Don’t depend on the thread scheduler //don't use Thread.yield - better Thread.sleep(1) //no testable //same about thread priorities
5+
//Avoid thread groups
6+
public class ConcurrencyBestPractice {
7+
public static void main(String[] args) {}
8+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package bestpractice;
2+
3+
import java.util.Date;
4+
5+
//copy when return
6+
//copy when use
7+
//don't use clone
8+
//check after and check on ended params //time-of-check time-of-use race condition
9+
//use long
10+
public class CopyInImmutableObjects {
11+
public static void main(String[] args) {
12+
Date start = new Date();
13+
Date end = new Date();
14+
Period p = new Period(start, end);
15+
}
16+
}
17+
18+
final class Period {
19+
private final long start;
20+
private final long end;
21+
22+
/**
23+
* @param start the beginning of the period
24+
* @param end the end of the period; must not precede start
25+
* @throws IllegalArgumentException if start is after end
26+
* @throws NullPointerException if start or end is null
27+
*/
28+
public Period(Date start, Date end) {
29+
this.start = start.getTime();
30+
this.end = end.getTime();
31+
if (this.start < this.end)
32+
throw new IllegalArgumentException(start + " after " + end);
33+
}
34+
35+
public Date start() {
36+
return new Date(start);
37+
}
38+
public Date end() {
39+
return new Date(end);
40+
}
41+
}
42+
//class MyDate extends Date {
43+
// @Override
44+
// public Object clone() {
45+
// //some bad code
46+
// return super.clone();
47+
// }
48+
//}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package bestpractice;
2+
3+
import java.util.AbstractCollection;
4+
import java.util.AbstractList;
5+
import java.util.Date;
6+
7+
//document for inheritance
8+
//which method we invoke? and how does it affect //in which circumstances it should be invoke i.e. background threads or static initializers
9+
//The description begins with the phrase “This implementation.”
10+
//inheritance violates encapsulation
11+
//class may have to provide hooks into its internal workings in the form of judiciously chosen protected methods
12+
//The only way to test a class designed for inheritance is to write subclasses
13+
//Constructors must not invoke overridable methods //NullPointerException
14+
//Cloneable and Serializable //neither clone nor readObject may invoke an overridable method //readResolve or writeReplace method protected
15+
//good - skeletal implementations of interfaces
16+
//prohibit subclassing in classes that are not designed and documented to be safely subclassed //final class is bad
17+
public class DesignForInheritance {
18+
public static void main(String[] args) {
19+
AbstractCollection abstractCollection;
20+
AbstractList abstractList;
21+
Sub sub = new Sub();
22+
sub.overrideMe();
23+
}
24+
}
25+
26+
class Super {
27+
public Super() {
28+
overrideMe();
29+
}
30+
public void overrideMe() {
31+
}
32+
}
33+
class Sub extends Super {
34+
private final Date date;
35+
public Sub() {
36+
date = new Date();
37+
}
38+
@Override public void overrideMe() {
39+
System.out.println(date);
40+
}
41+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package bestpractice;
2+
3+
//Choose method names carefully
4+
//Too many methods make a class difficult to learn, use, document, test, and maintain
5+
//Avoid long parameter lists //Long sequences of identically typed parameters are especially harmful
6+
//1. break the method up into multiple methods
7+
//2. create helper classes to hold groups of parameters
8+
//3. Builder pattern
9+
//For parameter types, favor interfaces over classes
10+
//Prefer two-element enum types to boolean parameters
11+
public class DesignMethodSignature {
12+
public static void main(String[] args) {}
13+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package bestpractice;
2+
3+
import java.math.BigInteger;
4+
import java.util.ArrayList;
5+
import java.util.Collections;
6+
import java.util.Random;
7+
import java.util.concurrent.ConcurrentHashMap;
8+
9+
public class DocumentThreadSafety {
10+
public static void main(String[] args) {
11+
// immutable
12+
String s;
13+
Long l;
14+
BigInteger bigInteger;
15+
// unconditionally thread-safe
16+
Random random;
17+
ConcurrentHashMap concurrentHashMap;
18+
// conditionally thread-safe
19+
Collections.unmodifiableList(new ArrayList<>());
20+
// not thread-safe
21+
ArrayList arrayList;
22+
// thread-hostile
23+
System.runFinalizersOnExit(true);
24+
}
25+
}

0 commit comments

Comments
 (0)