Java 9 and above

https://advancedweb.hu/2019/08/08/post_java_8_language_features/ https://dev.to/awwsmm/20-reasons-to-move-on-from-java-8-1dio https://habr.com/ru/post/446590/ https://youtu.be/cF-rUNCOm2c https://www.youtube.com/watch?v=wW8j9ootXvs https://advancedweb.hu/2019/02/19/post_java_8/?mc_cid=5fbac15154&mc_eid=2dc463b37c https://medium.com/slalom-engineering/clean-architecture-with-java-11-f78bba431041

Java


 https://books.sonatype.com/mvnex-book/reference/index.html  Maven

https://www.reddit.com/r/java/comments/an5g18/containerized_development_ide_on_mac/
https://habr.com/ru/post/440590/ .  Java Memory Model
Data Structures
https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value
 https://habr.com/post/436024/
 https://stackabuse.com/design-patterns-in-java/
 https://www.youtube.com/watch?v=Nd6lyFwZCLg .   Professional Java Programmer - Tips & Tricks
https://www.youtube.com/watch?v=tzsbjloUdf4 .  Collections Framework Enhancement in Java 9
https://www.youtube.com/watch?v=BD9cRbxWQx8 .  Low latency Java
My Java code snippets
Java memory model

https://eli.thegreenplace.net/2018/type-erasure-and-reification/

https://learning.oreilly.com/videos/optimizing-java/9781492044673

https://habr.com/post/431524/ .  Serialization

https://www.spinellis.gr/blog/20181127/  Java Stream method and Unix Pipeline
https://medium.com/adorsys/jvm-memory-settings-in-a-container-environment-64b0840e1d9e
 

http://august.nagro.us/small-java.html    jlink Docker

IntelliJ

https://habr.com/company/jugru/blog/428648/ Антон Архипов про эффективную работу с IntelliJ https://javaspecialists.teachable.com/p/intellij-wizardry https://www.jworks.io/essential-intellij-shortcuts/ https://jug.ru/ https://habr.com/company/jugru/blog/433858/ on youtube https://www.tutorialdocs.com/article/java-4-referance-types.html https://www.marcobehler.com/guides/a-guide-to-logging-in-java https://youtu.be/Pqf367x-OuA . profiling https://github.com/bgard6977/depends . depends! https://docs.oracle.com/javase/9/tools/jlink.htm#JSWOR-GUID-CECAC52B-CFEE-46CB-8166-F17A8E9280E9 . jlink https://github.com/jhalterman/failsafe https://github.com/akullpp/awesome-java https://www.reddit.com/r/java/comments/9pnvac/java_libraries/ https://news.ycombinator.com/item?id=18168226 . Functional data structures on JVM

Books

Modern Java Recepies Effective Java Java Precisely http://www.javapractices.com http://javarevisited.blogspot.com/ http://www.java67.com/ https://ordepdev.me/posts/size-of-an-object-in-java

Concurrency

Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double). Reads and writes are atomic for all variables declared volatile (including long and double variables). https://www.youtube.com/watch?time_continue=6&v=8i_9ZNNhn2I . Russian (~2 hours) https://github.com/code-review-checklists/java-concurrency https://medium.com/@wiemzin/concurrency-is-complicated-e44ddb5aa9ef https://www.youtube.com/watch?v=8i_9ZNNhn2I . Aсинхронное программирование в Java https://www.youtube.com/watch?v=ADxUsCkWdbE . Concurrency Concepts in Java by Douglas Hawkins https://www.youtube.com/watch?v=6Oo-9Can3H8 . Java ExecutorService https://www.youtube.com/watch?v=ImtZgX1nmr8 . Completeble Future https://www.nurkiewicz.com/2018/09/thread-pool-self-induced-deadlocks.html https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html - immutable object https://stackoverflow.com/questions/1038007/why-should-wait-always-be-called-inside-a-loop A JVM runs in a single process and threads in a JVM share the heap belonging to that process. That is why several threads may access the same object. Threads share the heap and have their own stack space. This is how one thread’s invocation of a method and its local variables are kept thread safe from other threads. But the heap is not thread-safe and must be synchronized for thread safety. There are following ways to create threads in Java 1) Extending the java.lang.Thread class. 2) Implementing the java.lang.Runnable interface. 3) Implementing the java.util.concurrent.Callable interface with the java.util.concurrent.Executor framework to pool the threads. The java.util.concurrent package was added in Java 5. 4) Using the Fork/Join Pool Concurrency (Vogella) Concurrency (Jenkov) CountDownLatch-and-CyclicBarrier Java Blog

Links

Java Practice Assertion https://habr.com/post/352672/ Assertions https://www.rainerhahnekamp.com/en/ignoring-exceptions-in-java/ Executable Jar Executable jar Cheat sheet https://github.com/gaul/java-collection-overhead x^x=0 x^y^x=y

Collection / Collections

youtube interface Collection extends Iterable { boolean add(E e); boolean remove (Object o); int size(); boolean isEmpty() void clear() boolean contains(Object o) boolean containsAll( Collection> c> boolean addAll( Collection> c> boolean removeAll( Collection> c> boolean retainAll( Collection> c> Iterator iterator() } List Set Queue interfaces extends Collection

List

E set ( int index, E e) void add(int i, E e) get set vs add remove int indexOf(Object o) int lastIndexOf(Object o) ListIterator List sublist(int i int j) ArraList implements List, RandomAccess Vector is as ArrayList but syncronised LinkList implements List, Queue (double linked list, good for implementing stack and queue)

Set

HashSet is Implemented using a hash table. Elements are not ordered. The add, remove, and contains methods have constant time complexity O(1). TreeSet is implemented using a tree structure(red-black tree in algorithm book). The elements in a set are sorted, but the add, remove, and contains methods has time complexity of O(log (n)). It offers several methods to deal with the ordered set like first(), last(), headSet(), tailSet(), etc. LinkedHashSet is between HashSet and TreeSet. It is implemented as a hash table with a linked list running through it, so it provides the order of insertion. The time complexity of basic methods is O(1). Example of usage LinkedHashSet: /* Function removes duplicate characters from the string This function work in-place */ void removeDuplicates(String str) { LinkedHashSet lhs = new LinkedHashSet<>(); for(int i=0;i interface SortedSet extends Set { SortedSet subSet(E from, E to) SortedSet headSet(E from, E to) TailSet headSet(E from, E to) E first() E last() } interface NavigatableSet extends SortedSet Implementation of Set interface: class HashSet class LinkedHashSet maintains the order of insertion class TreeSet implements Set, NavigableSet - keeps the sorted order Build Set from Array example: public static boolean useSet(String[] arr, String targetValue) { Set set = new HashSet(Arrays.asList(arr)); return set.contains(targetValue); }

Map Interface

Map, SortedMap, NavigableMap get put Set keySet Map interface implementation HashMap - allows null keys Hashtable - threadsafe, not allows null key LinkedHashMap - maintains the order of insertion TreeMap - sorted

Queue Interface

interface Queue extends Collection{ Insert boolean add(E e) - throws exception if failure boolean offer(E e) - return false if failue Remove E remove() - removes head, throws exception if empty E poll() - removes head, null if empty Examine E element() - throws exception E peek() - read but not remove, null if empty } interface Deque extends Queue{ addFirst, addLast, offerfirst,offerLast, removeFirst,removeLast } interface BlockingQueue extends Queue{ boolean offer(E e, long timeout) E poll(long timeout) E take() - waits untile element become available } Implementations of Queue interface PriorityQueue ArrayDeque ArrayBlockingQueue LinkedListBlockingQueue Collection is an interface that is the parent of most of the collection interfaces defined in the collection framework. This interface implements Iterable. The Set and List interfaces extends Collection interface. Collections, on the other hand, is a class with an exclusive collection of static methods and fields. Examples: sort(), binarySearch(), shuffle() Using Arrays.binarySearch() example: binarySearch() can ONLY be used on sorted arrays. If the array is sorted, you can use the following code to search the target element: public static boolean useArraysBinarySearch(String[] arr, String targetValue) { int a = Arrays.binarySearch(arr, targetValue); if(a > 0) return true; else return false; }

Interfaces

Interfaces can have default methods. @FunctionalInterface Functional interfaces: only one abstract method Examples: public interface Predicate { boolean test (T t); } public interface Comparator{ //java.util.Comparator int compare(T o1, T o2); } public interface Runnable { //java.lang.Runnable void run(); } public interface Consumer { //java.util.function.Consumer void accept(T t); } public interface Callable{ //java.util.concurrent.Callable V call(); } public interface Function{ R apply(T t); } Example of creating the method map() to transform list into list using Function interface: public static List map(List list, Function f){ List result = new ArrayList<>(); for (T s: list){ result.add(f.apply(s)); } return result; } Usage: List lst= map{Arrays.asList("a","bb","ccc"), (String s) -> s.length()}; Another example: import java.util.function.Function; public class TestFrame { public static void main(String[] args) { Function toDegree = (radian) -> { return (radian*180)/Math.PI; }; System.out.println(toDegree.apply(1.5707963267948966)); } } To avoid boxin/unboxing for primitive types Java8 provides specialization interfaces, for example: public interface IntPredicate { boolean test (int t); }

Comparators

Comparator c = Comparator.comparing((Apple a) -> a.getWeight()); mylist.sort(comparing(Apple::getWeight)); mylist.sort(comparing(Apple::getWeight).reversed()); mylist.sort(comparing(Apple::getWeight). reversed(). thenComparing(Apple:getCountry));

Composing predicates

Predicate notRed = redApple.negate(); Predicate RedAndHeavy = redApple.and(a.getWeight() > 150); Predicate RedAndHeavyOrGreen = redApple.and(a.getWeight() > 150).or(a->"green".equals(a.getColor()));

Composing functions

Function f = x->x+1 Function g = x->x+2 Function h = f.andThen(g) int result = h.apply(1) Function s = f.compose(g)

Streams

A stream is based on internal iteration; a collection is based on external iteration. Streams can be directly obtained from the Arrays class as follows: DoubleStream ds = Arrays.stream(new double[] {10.234, 25.26, 3792.8755}); Stream st = Arrays.stream(new String[] {"Spade", "Heart", "Diamond", "Club"}); Intermediate operations: filter (Predicate) findAny findFirst - returns Optional map (Function) flatMap allMatch anyMatch noneMatch limit reduce sorted(Comparator) distinct Terminal operations: count collect(toList()) forEach Primitive stream specialization: IntStream, DoubleStream, LongStream int[] numbers ={2,3,5,7} int sum = Arrays.stream(numbers).sum();

Labmda expressions

Old stile: for(Car c : cars) { if(c.productionYear > 2007) System.out.println(c.name); } New style using lambda: cars.stream().filter((c) -> (c.productionYear > 2007)) .forEach((c) -> {System.out.println(c.name);}); Java 8 allows add methods to interfaces and provide a default implementation and forEach method is: @FunctionalInterface public interface Iterable { Iterator iterator(); default void forEach(Consumer action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } }

Optional

This is container class to represent existance or absense of value The get method returns the value if present; otherwise, NoSuchElementException is thrown. isPresent() ifPresent(Consumer block) T get() T orElse(T other) https://arnhem.luminis.eu/pure-bliss-with-pure-functions-in-java/

Processes

These processes execute in an isolated, independent manner to which resources are allocated such as: memory, file handles, and security credentials. On occasion, one process communicates with another through a communication mechanism such as: sockets, signals, shared memory, semaphores, and files.

Threads

youtube Some classes that are designed keeping thread safety in mind are String, Hashtable, ConcurrentHashMap, Atomic operations are thread-safe; for example, a+1 is atomic but a++ is not, because a++ means a=a+1 and consists of two operations, + (addition) and = (assignment). But, there is a way to make the increment operation atomic with the help of AtomicInteger, AtomicBoolean, AtomicLong, AtomicLongArray. AtomicInteger aInt=new AtomicInteger(5); aInt.incrementAndGet();. Local variables are thread safe because each segment has its own copy. Volatile keywords can be used to ensure that threads do not cache variables. Implement Runnable interface (void run()) or extend Thread class deadlock starvation livelock Priority: 1-10; default 5 Thread.setPriority(1) Thread states: NEW - obj is created, but start() is not called yet RUNNABLE eligible to run, not running yet; scheduler moves from runnable to running state RUNNING BLOCKED/WAITING TERMINATED/DEAD syncronized method can be executed only by 1 thread synchronized(this) {code here} t1.start() t2.start() t3.join(time) - wait then t3 is completed yield() method change state from running to runnable sleep() suspend() wait() releases the lock; tells the calling thread to relinquish the monitor and go to sleep until some other thread calls, such as notify() or notifyAll(). notify() wakes up the thread which called wait(). And, in a similar manner, notifyAll() wakes up all the threads. notifyAll() ThreadGroup.activeCount() ThreadLocal class daemon thread -low priority; garbage collector

ForkJoinPools

https://www.java-success.com/10-%E2%99%A6-executorservice-vs-forkjoin-future-vs-completablefuture-interview-qa/

CompletableFuture

Ru Eng

ExecutorService

ExecutorService s =Executors.newSingleThreadExecutor(); ExecutorService s =Executors.newFixedThreadsPool(10); ExecutorService s =Executors.newSheduledThreadPool(10); s.execute( new Runnable () public void run(){} ) s.shoutdown() Future f = s.submit( new Runnable(){ public void run(...)} ) f.get() // returns null if complete Callable returns result Future f = s.submit( new Callable(){ public String call() throws exception { return "some_result";) } }) f.get() // returns result if complete ------ import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; class Counter implements Callable { private static final int THREAD_POOL_SIZE = 2; private AtomicInteger count = new AtomicInteger(); // method where the thread execution takes place public String call() { return Thread.currentThread().getName() + " executing ..." + count.incrementAndGet(); //Consumer } public static void main(String[] args) throws InterruptedException, ExecutionException { // create a pool of 2 threads ExecutorService executor = Executors .newFixedThreadPool(THREAD_POOL_SIZE); Counter counter = new Counter(); Future future1 = executor.submit(counter); //Producer Future future2 = executor.submit(counter); //Producer System.out.println(Thread.currentThread().getName() + " executing ..."); //asynchronously get from the worker threads System.out.println(future1.get()); System.out.println(future2.get()); } } Java 8 has the DoubleAccumulator and the DoubleAdder new classes that allow us to have multiple threads updating the same variable, but in fact, they update their own copy of that variable. The trick happens when you have to read the variable. When you have to do a read, the system will pause all threads, figure out what the value is, update a single instance that the read is associated with and the give the correct value.

Handling Exceptions

Use checked exceptions for all exceptional events that you can anticipate and that a well-written application should be able to handle. A checked exception extends the Exception class. A method that throws a checked exception or that calls a method that specifies a checked exception needs to either specify or handle it. Unchecked exceptions extend the RuntimeException. Use them for internal errors that you can’t anticipate and that, most often, the application can’t recover from. Methods can but don’t need to handle or specify an unchecked exception. Typical examples that throw unchecked exceptions are: - the missing initialization of a variable which results in a NullPointerException or - the improper use of an API that causes an IllegalArgumentException AutoCloseable interface Instantiate the object within the try clause File file = new File("./tmp.txt"); try (FileInputStream inputStream = new FileInputStream(file);) { // use the inputStream to read a file } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Without Closeable the code looks like this: public void closeResourceInFinally() { FileInputStream inputStream = null; try { File file = new File("./tmp.txt"); inputStream = new FileInputStream(file); // use the inputStream to read a file } catch (FileNotFoundException e) { log.error(e); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.error(e); } } } } Counters performance: https://www.programcreek.com/2013/10/efficient-counter-in-java/ https://www.programcreek.com/2014/01/java-8-counter/ public class Java8Counter { public static void main(String[] args) { String[] arr = {"program", "creek", "program", "creek", "java", "web", "program"}; Stream stream = Stream.of(arr).parallel(); Map counter = stream.collect(Collectors.groupingBy(String::toString, Collectors.counting())); System.out.println(counter.get("creek")); } }

Concurrent LRU cache

https://www.ebayinc.com/stories/blogs/tech/high-throughput-thread-safe-lru-caching/

Given a non-empty array of integers, return the k most frequent elements

Time is O(n*log(k)). class Pair{ int num; int count; public Pair(int num, int count){ this.num=num; this.count=count; } } public class Solution { public List topKFrequent(int[] nums, int k) { //count the frequency for each element HashMap map = new HashMap(); for(int num: nums){ if(map.containsKey(num)){ map.put(num, map.get(num)+1); }else{ map.put(num, 1); } } // create a min heap PriorityQueue queue = new PriorityQueue(new Comparator(){ public int compare(Pair a, Pair b){ return a.count-b.count; } }); //maintain a heap of size k. for(Map.Entry entry: map.entrySet()){ Pair p = new Pair(entry.getKey(), entry.getValue()); queue.offer(p); if(queue.size()>k){ queue.poll(); } } //get all elements from the heap List result = new ArrayList(); while(queue.size()>0){ result.add(queue.poll().num); } //reverse the order Collections.reverse(result); return result; } }