├── .gitignore ├── LICENSE ├── README.md ├── images ├── collection-hierarchy-1.png ├── collection-hierarchy-2.png ├── map-hierarchy-1.png └── map-hierarchy-2.png └── topics ├── core ├── collections.md ├── concurrency.md ├── core-java.md ├── garbage-collection.md ├── java-8.md ├── java-memory-model.md └── jvm-internals.md ├── design ├── approach.md ├── design-patterns.md ├── effective-java.md ├── solid.md └── testing.md ├── opinion └── myanswers.md └── related ├── sql.md ├── unix.md └── web.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Deepak Vadgama 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java interview 2 | 3 | I created study notes for my recent interviews. I am sharing them here so that others can benefit from it. 4 | The notes are specifically for theory based Java interviews, typically done in service based companies 5 | (as opposed to coding based interviews done in product companies). 6 | 7 | ### How to use it? 8 | 9 | These are study notes, mostly for revision couple of days before the interview. Check resources on each topic 10 | for more in-depth preparation. 11 | 12 | ## Table Of Contents 13 | 14 | ### Core Java 15 | 16 | - [Core Java](topics/core/core-java.md) 17 | - [Collections](topics/core/collections.md) 18 | - [Java 8](topics/core/java-8.md) 19 | - [Java Memory Model](topics/core/java-memory-model.md) 20 | - [Concurrency](topics/core/concurrency.md) 21 | - [Garbage Collection](topics/core/garbage-collection.md) 22 | - [JVM Internals](topics/core/jvm-internals.md) 23 | 24 | ### Design / Clean Code 25 | 26 | - [SOLID Principles](topics/design/solid.md) 27 | - [Effective Java](topics/design/effective-java.md) 28 | - [Design Patterns](topics/design/design-patterns.md) 29 | - [Approach to Design Questions](topics/design/approach.md) 30 | 31 | ### Related topics 32 | 33 | - [SQL](topics/related/sql.md) 34 | - [UNIX](topics/related/unix.md) 35 | - [Web](topics/related/web.md) 36 | 37 | ### Other topics 38 | 39 | - [Spring Boot overview (DI, Security, JPA, Testing)](http://deepakvadgama.com/blog/spring-boot-wonders/) 40 | 41 | ### Opinion based questions 42 | 43 | Answers to such questions vary based on multiple factors (interviewer and interviewee's experience with Java, exposure to other languages, personal taste, etc). Thus, take the answers with pinch of salt, and make them your own before using them. 44 | 45 | - What do you like about Java? [Answer](topics/opinion/myanswers.md#what-do-you-like-about-java) 46 | - What do you not like about Java? [Answer](topics/opinion/myanswers.md#what-do-you-not-like-about-java) 47 | - Which is better - compilation, interpretation or JIT? Why? [Answer](topics/opinion/myanswers.md#importance-of-compile-time-vs-jit) 48 | -------------------------------------------------------------------------------- /images/collection-hierarchy-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepakVadgama/java-interview/f3d6f32a2ce7db2c0a653f011a82590e23776d57/images/collection-hierarchy-1.png -------------------------------------------------------------------------------- /images/collection-hierarchy-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepakVadgama/java-interview/f3d6f32a2ce7db2c0a653f011a82590e23776d57/images/collection-hierarchy-2.png -------------------------------------------------------------------------------- /images/map-hierarchy-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepakVadgama/java-interview/f3d6f32a2ce7db2c0a653f011a82590e23776d57/images/map-hierarchy-1.png -------------------------------------------------------------------------------- /images/map-hierarchy-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepakVadgama/java-interview/f3d6f32a2ce7db2c0a653f011a82590e23776d57/images/map-hierarchy-2.png -------------------------------------------------------------------------------- /topics/core/collections.md: -------------------------------------------------------------------------------- 1 | ## Collections 2 | 3 | ### Resources 4 | 5 | - [OCA/OCP Java SE 7 Programmer](https://www.amazon.com/Programmer-Study-1Z0-803-1Z0-804-Certification/dp/0071772006/ref=asap_bc?ie=UTF8) (book) 6 | - [Cheat sheet](http://files.zeroturnaround.com/pdf/zt_java_collections_cheat_sheet.pdf) (PDF) 7 | - [Effective Java study notes](topics/design/effective-java.md) 8 | 9 | ### Table of contents 10 | 11 | - [Lists](#lists) 12 | * [ArrayList](#arraylist) 13 | * [LinkedList](#linkedlist) 14 | * [Stack](#stack) 15 | * [Vector](#vector) 16 | * [CopyOnWriteArrayList](#copyonwritearraylist) 17 | * [Collections.synchronizedList](#collectionssynchronizedlist) 18 | - [Sets](#sets) 19 | * [HashSet](#hashset) 20 | * [LinkedHashSet](#linkedhashset) 21 | * [TreeSet](#treeset) 22 | * [ConcurrentSkipListSet](#concurrentskiplistset) 23 | * [CopyOnWriteArraySet](#copyonwritearrayset) 24 | * [EnumSet](#enumset) 25 | - [Maps](#maps) 26 | * [HashMap](#hashmap) 27 | * [HashMap implementation details](#hashmap-implementation-details) 28 | * [LinkedHashMap](#linkedhashmap) 29 | * [Hashtable](#hashtable) 30 | * [ConcurrentHashMap](#concurrenthashmap) 31 | * [TreeMap](#treemap) 32 | * [ConcurrentSkipListMap](#concurrentskiplistmap) 33 | - [Queues](#queues) 34 | * [LinkedList](#linkedlist-1) 35 | * [ArrayBlockingQueue](#arrayblockingqueue) 36 | * [LinkedBlockingQueue](#linkedblockingqueue) 37 | * [ConcurrentLinkedQueue](#concurrentlinkedqueue) 38 | * [Deque classes](#deque-classes) 39 | * [PriorityQueue](#priorityqueue) 40 | * [PriorityBlockingQueue](#priorityblockingqueue) 41 | * [DelayQueue](#delayqueue) 42 | * [SynchronousQueue](#synchronousqueue) 43 | - [equals and hashCode](#equals-and-hashcode) 44 | - [Collections class](#collections-class) 45 | * [Utility methods](#utility-methods) 46 | * [Methods returning wrapped instances](#methods-returning-wrapped-instances) 47 | - [Hierarchy and classes](#hierarchy-and-classes) 48 | 49 | --- 50 | 51 | ### Lists 52 | 53 | #### ArrayList 54 | 55 | - Backed by array (which are co-located in memory), thus fast iteration and get(i) operation. 56 | - Slow inserts when the backed array is full and has to double in size. 57 | - Fail-fast iterators, which can throw ConcurrentModificationException. 58 | - Add is O(n) - When element is added to middle of list, all elements on the right have to be moved. 59 | - [Use Case](http://stackoverflow.com/a/322742/3494368) - When iterations outnumber number of read/writes. 60 | 61 | #### LinkedList 62 | 63 | - Chain of nodes referencing each other (doubly linked list). 64 | - No co-location of nodes, pointers need to be chased for next element, thus slow iterations and get(i) operation. 65 | - Fail-fast iterators, which can throw ConcurrentModificationException. 66 | - Implements Queue interface, thus allows offer/pop/peek operations. 67 | - Add is O(1) - Adding element in middle of list is just adjusting the node pointers. 68 | - Internally uses references (~ to skiplist) to optimize iterations. 69 | - [Use Case](http://stackoverflow.com/a/322742/3494368) - Lot of inserts in middle of the list. 70 | 71 | | Operation | ArrayList | LinkedList | 72 | |-----------------|-----------------------------------|---------------------------| 73 | | get(i) | O(1) | O(n) | 74 | | add() | O(1) amortized | O(1) | 75 | | remove(i) | O(n) Remove and move all elements | O(n) Iterate then remove | 76 | | iterator.remove | O(n) | O(1) | 77 | 78 | #### Stack 79 | 80 | - For stack operations push/pop/peek. 81 | - Not used anymore. Recommended to use Deque implementations. 82 | 83 | #### Vector 84 | 85 | - Synchronized version of list. 86 | - Not used anymore. Recommended below mentioned alternatives. 87 | 88 | #### CopyOnWriteArrayList 89 | 90 | - Thread-safe. 91 | - Backed array is copied during every element insert. 92 | - Avoids ConcurrentModificationException since iteration can continue in original copy, and insert results in new copy. 93 | - High memory usage (more pressure on GC) due to the resulting copies. 94 | - Use case - Large number of threads for read, low number of writes. 95 | 96 | #### Collections.synchronizedList 97 | 98 | - Thread-safe. 99 | - Can be slow due to mutual exclusion. 100 | - Iterations have to be externally synchronized by developer 101 | - Can throw ConcurrentModificationException if (above mentioned) synchronization not done during iteration. 102 | 103 | --- 104 | 105 | ### Sets 106 | 107 | Collection of unique elements. No duplicates. 108 | 109 | #### HashSet 110 | 111 | - Backed by HashMap. 112 | - Performance can vary based on hashCode implementation. 113 | - Constant time get/remove/add/contains (subject to above point). 114 | - Fail-fast iterators. 115 | - Insertion order not retained. 116 | 117 | #### LinkedHashSet 118 | 119 | - Insertion order is retained. 120 | - Uses doubly-linked list to maintain the order. 121 | - Iteration can be slower due to this. 122 | - Other features, same as HashSet above (except iteration) 123 | 124 | #### TreeSet 125 | 126 | - Elements sorted by their natural order (or Comparator passed in constructor). 127 | - Log(n) time for add/remove/contains operations. 128 | - Navigable (floor, ceiling, higher, lower, headSet, tailSet operations). 129 | - Fail fast iterators. 130 | 131 | #### ConcurrentSkipListSet 132 | 133 | - Thread-safe. 134 | - Log(n) time for add/remove/contains operations. 135 | - Navigable (floor, ceiling, higher, lower, headSet, tailSet operations). 136 | - Size method is not constant time operation. 137 | - Weakly consistent iterators (do not throw ConcurrentModificationException but also __may not__ reflect concurrently added items). 138 | - Thus, bulk operations (addAll, removeAll, retainAll, containsAll etc) are not guaranteed to be atomic. 139 | 140 | #### CopyOnWriteArraySet 141 | 142 | - Backed by CopyOnWriteArrayList 143 | - Thread-safe. 144 | - Slow. Operations have to iterate through the array for most operations. 145 | - Recommended where reads vastly outnumber writes and set size is small. 146 | 147 | #### EnumSet 148 | 149 | - To be used with Enum types. 150 | - Very efficient and fast (backed by bit-vectors). 151 | - Weakly consistent iterators. 152 | - Nulls not allowed. 153 | 154 | --- 155 | 156 | ### Maps 157 | 158 | #### HashMap 159 | 160 | - key, value pairs. 161 | - Permits a null key, and null values. 162 | - Iteration order not guaranteed. 163 | - Throws ConcurrentModificationException. 164 | - [Article detailing implementation](http://www.deepakvadgama.com/blog/java-hashmap-internals/). 165 | 166 | #### HashMap implementation details 167 | 168 | - Backed by array (buckets), array-size is known as table-size. 169 | - Position in array = element-hash % table-size. 170 | - If elements end up in same bucket, they are added to linked-list (or a balanced red-black tree). 171 | - O(1) access (if hashcode properly distributes the values, else O(n) for linked-list & O(log(n)) for tree. 172 | - Load factor - 0.75 default, decides when table-size should increase (double). 173 | - Bigger load-factor - more space-efficient, reduced speed (due to more elements in same bucket). 174 | - Lower load-factor - less space-efficient, more speed (less, ideally 1 element in 1 bucket). 175 | - Initial table-size = 16. 176 | 177 | #### LinkedHashMap 178 | 179 | - Insertion order is retained. 180 | 181 | #### Hashtable 182 | 183 | - Thread-safe. 184 | - Not used anymore, ConcurrentHashMap recommended. 185 | 186 | #### ConcurrentHashMap 187 | 188 | - Thread-safe. 189 | - Fine grained locking called striped locking (map is divided into segments, each with associated lock. Threads holding different locks don't conflict). 190 | - Improved performance over Hashtable. 191 | 192 | #### TreeMap 193 | 194 | - Sorted by keys. 195 | - Uses Red-Black tree implementation. 196 | 197 | #### ConcurrentSkipListMap 198 | 199 | - Thread-safe version of TreeMap. 200 | - Navigable (floor, ceiling, higher, lower, headSet, tailSet operations). 201 | 202 | --- 203 | 204 | ### Queues 205 | 206 | #### LinkedList 207 | 208 | - Implements Queue interface. 209 | - offer, peek, poll operations. 210 | - Use case - task queues 211 | 212 | #### ArrayBlockingQueue 213 | 214 | - Thread-safe. 215 | - Backed by array. Thus bounded in size. 216 | - Adding element to full queue results in blocking. 217 | - Polling an empty queue results in blocking. 218 | - Use case - Producer consumer problem. 219 | 220 | #### LinkedBlockingQueue 221 | 222 | - Thread-safe. 223 | - Backed by linked-list. 224 | - Optionally bounded in size. Takes maxSize as constructor argument. 225 | 226 | #### ConcurrentLinkedQueue 227 | 228 | - Thread-safe. 229 | - Uses CAS (Compare-And-Swap) for more throughput. Also known as lock free. 230 | 231 | #### Deque classes 232 | 233 | - ArrayDeque - Double ended queue. Backed by array. Can throw ConcurrentModificationException. 234 | - LinkedList - Implements Deque interface. 235 | - LinkedBlockingDeque 236 | - ConcurrentLinkedDeque 237 | 238 | #### PriorityQueue 239 | 240 | - Elements sorted based on their natural order (or Comparator provided in Constructor). 241 | - Use case - task queues where tasks can have different priorities. 242 | 243 | #### PriorityBlockingQueue 244 | 245 | - Thread-safe. 246 | 247 | #### DelayQueue 248 | 249 | - Elements added, are available to be removed only after their delay-time is expired. 250 | 251 | #### SynchronousQueue 252 | 253 | - Holds single elements. 254 | - Blocks for both producer and consumer to arrive. 255 | - Use case - For safe/atomic transfer of objects between threads. 256 | 257 | --- 258 | 259 | ### equals and hashCode 260 | 261 | - equals required for all collections. 262 | - equals and hashCode required for Maps and Sets (which are backed by Maps). 263 | 264 | --- 265 | 266 | ### Collections class 267 | 268 | #### Utility methods 269 | 270 | - sort(list, key) - guarantees stable sort 271 | - reverse 272 | - reverseOrder - returns Comparator for reversed order 273 | - shuffle 274 | - rotate(list, distance) - rotates elements by the distance specified 275 | - binarySearch(list, key) 276 | + list should be sorted else can get unpredictable results 277 | + log(n) if list implements RandomAccess, else O(n) 278 | + RandomAccess - Marker interface that says, collection supports fast random access, get(i). Typically backed by arrays. 279 | 280 | #### Methods returning wrapped instances 281 | 282 | - empty - emptyList, emptySet, emptyMap etc. 283 | - synchronized - synchronizedList, synchronizedSet, synchronizedMap etc. 284 | - unmodifiable - unmodifiableList, unmodifiableSet, unmodifiableMap etc. 285 | - singleton(t) - singleton (returns set), singletonList, singletonMap etc. 286 | 287 | --- 288 | 289 | ### Hierarchy and classes 290 | 291 | 292 | 293 | 294 | -------------------------------------------------------------------------------- /topics/core/concurrency.md: -------------------------------------------------------------------------------- 1 | ## Concurrency 2 | 3 | 4 | ### Resources 5 | 6 | - [Concurrency in Practice by Brian Goetz](http://jcip.net) - Highly Recommended 7 | 8 | ### Table of Contents 9 | 10 | - [Basics](#basics) 11 | * [Benefits of Threads](#benefits-of-threads) 12 | * [Thread safety](#thread-safety) 13 | * [Race Condition](#race-condition) 14 | * [Solutions to compound operations](#solutions-to-compound-operations) 15 | * [Synchronized](#synchronized) 16 | * [Liveness and Performance](#liveness-and-performance) 17 | - [Sharing Objects](#sharing-objects) 18 | * [Data Visibility](#data-visibility) 19 | * [Safe construction](#safe-construction) 20 | * [Confinement](#confinement) 21 | * [Immutability](#immutability) 22 | * [Final Fields](#final-fields) 23 | * [Safe Publishing](#safe-publishing) 24 | - [Composing Objects](#composing-objects) 25 | * [State Ownership](#state-ownership) 26 | * [Unmodifiable](#unmodifiable) 27 | * [Client-side locking](#client-side-locking) 28 | - [Building Blocks](#building-blocks) 29 | * [Iterators and ConcurrentModificationException](#iterators-and-concurrentmodificationexception) 30 | * [Concurrent Collections](#concurrent-collections) 31 | * [InterruptedException](#interruptedexception) 32 | * [Synchronizers](#synchronizers) 33 | - [Task Execution](#task-execution) 34 | * [Thread Pools](#thread-pools) 35 | * [Uncaught exception handlers](#uncaught-exception-handlers) 36 | * [Shutdown hooks](#shutdown-hooks) 37 | * [Daemon threads](#daemon-threads) 38 | * [Finalizers](#finalizers) 39 | - [Applying Thread Pools](#applying-thread-pools) 40 | * [Thread pool sizes](#thread-pool-sizes) 41 | * [ThreadPoolExecutor](#threadpoolexecutor) 42 | * [Threads](#threads) 43 | * [Task Queues](#task-queues) 44 | * [Saturation Policy](#saturation-policy) 45 | * [Thread Factory](#thread-factory) 46 | - [Avoiding Liveness Hazards](#avoiding-liveness-hazards) 47 | * [Deadlocks](#deadlocks) 48 | * [Starvation and LiveLock](#starvation-and-livelock) 49 | - [Performance and Scalability](#performance-and-scalability) 50 | * [Costs on performance](#costs-on-performance) 51 | * [Steps](#steps) 52 | - [Explicit Locks](#explicit-locks) 53 | * [Lock and ReentrantLock](#lock-and-reentrantlock) 54 | * [Advantages of lock classes](#advantages-of-lock-classes) 55 | * [Read-Write lock](#read-write-lock) 56 | * [Custom Synchronizer](#custom-synchronizer) 57 | 58 | 59 | ### Basics 60 | 61 | #### Benefits of Threads 62 | 63 | - Exploiting multiple processors (Resource utilization) - Increasing core counts 64 | - Simplicity of modeling applications - Distinct tasks can have own thread, and each can be written sequentially. 65 | - Simplified handling of asynchronous events - If thread is blocked on IO, other threads can still run. Though these days OS allow 100s of thousands of threads, so blocking is not a major issuer anymore. Thus NIO is not as crucial anymore (because its very complicated to implement). 66 | 67 | Even if your class doesn't use threads, these do 68 | 69 | - Underlying frameworks 70 | - RMI 71 | - JVM (for GC + Main) 72 | - Timer 73 | - Servlets & JSP 74 | 75 | #### Thread safety 76 | 77 | Correctness means that a class _conforms to its specification_. A good specification defines _invariants_ constraining an object's state and _postconditions_ describing the effects of its operations. 78 | 79 | _No set of operations performed sequentially or concurrently on instances of a thread-safe class can cause an instance to be in an invalid state._ 80 | 81 | #### Race Condition 82 | 83 | - A race condition occurs when the correctness of a computation depends on the relative timing or interleaving of multiple threads by the runtime 84 | - Occurs usually with _check-then-act_ (check stale value). Eg: Lazy initialization. 85 | - Data races is different than race condition. Data races is when thread access (read/write) data to variable without any synchronization. 86 | 87 | #### Solutions to compound operations 88 | 89 | - Atomic classes (if only single variable is the issue) 90 | - Synchronized (if multiple variables are to be updated atomically) 91 | 92 | #### Synchronized 93 | 94 | - Aka Intrinsic locks, Mutexes, monitors 95 | - Are re-entrant 96 | - Re-entrancy can help for overridden synchronized methods. Call to super.method() tries to re-acquire lock, and is permitted. 97 | 98 | Allowing Object class to act as a lock (instead of special classes) was a mistake in JVM design. JVM implementors now have to make trade offs between object size and locking performance. 99 | 100 | #### Liveness and Performance 101 | 102 | - If scope of synchronized block is too large (say entire method of service). The whole performance benefit of multi-threading might be wiped off if service is accessed by lot of threads. 103 | - Scope of synchronized block should be small enough that it covers all mutable state. 104 | 105 | ### Sharing Objects 106 | 107 | #### Data Visibility 108 | 109 | - When data is not synchronized, other thread might read stale data (due to caching of variables in CPU registers and L1, L2) 110 | - 64-bit operations can be treated as 2 32-bit operations, thus need to be synchronized 111 | - Synchronized keyword ensures other thread reads latest data 112 | - Volatile keyword does the same 113 | - Semantics of volatile does not guarantee atomic increment!! Thus use volatile generally as status flags and such. 114 | 115 | Debugging tip: --server argument can hoist variables out of if condition (due to heavier optimization), while client JVM may not. Thus don't just think, if it works in client it works on server. 116 | 117 | #### Safe construction 118 | 119 | Do not let this reference escape the constructor. Even if it is last statement of constructor, the escaped reference of this, may not be pointing to completed object. 120 | 121 | Thus instead of constructors, listeners use setListener factory methods. 122 | 123 | #### Confinement 124 | 125 | Confining variables within method is best. For primitives its easy, but for objects, have to ensure its reference is not escaping. Thus Java has Collections.unmodifiableCollection and such. 126 | 127 | Note: unmodifiableCollection doesn't allow references to be updated, but objects' can still be updated if they are mutable. Eg: Map<String, Vehicle>.. Vehicle object can still be updated. 128 | 129 | ThreadLocal can also be used if its instance variable, but has to be thread-confined. 130 | 131 | #### Immutability 132 | 133 | Simple. Objects that cannot be modified, there are no threading issues. 134 | 135 | #### Final Fields 136 | 137 | Guarantee initialization safety. 138 | 139 | ```java 140 | public Holder holder; 141 | 142 | public void initialize() { 143 | holder = new Holder(42); // not guarantee to be done atomically, unless variable is final 144 | } 145 | ``` 146 | 147 | #### Safe Publishing 148 | 149 | - Placing a key or value in a Hashtable, synchronizedMap, or Concurrent- Map safely publishes it to any thread that retrieves it from the Map (whether directly or via an iterator); 150 | - Placing an element in a Vector, CopyOnWriteArrayList, CopyOnWriteArraySet, synchronizedList, or synchronizedSet safely publishes it to any thread that retrieves it from the collection; 151 | - Placing an element on a BlockingQueue or a ConcurrentLinkedQueue safely publishes it to any thread that retrieves it from the queue. 152 | 153 | Using a static initializer is often the easiest and safest way to publish objects that can be statically constructed: _public static Holder holder = new Holder(42);_ 154 | 155 | ### Composing Objects 156 | 157 | Making a class thread-safe means ensuring that its invariants hold under concurrent access; this requires reasoning about its state. Objects and variables have a state space: the range of possible states they can take on. The smaller this state space, the easier it is to reason about. By using final fields wherever practical, you make it simpler to analyze the possible states an object can be in. (In the extreme case, immutable objects can only be in a single state.) 158 | 159 | #### State Ownership 160 | 161 | Owner of the state can help reason about the mutable access. In Java, there can be shared ownership or transferred ownership (since objects are passed as reference). 162 | 163 | 164 | #### Unmodifiable 165 | 166 | unmodifiableCollection doesn't allow references to be updated, but values themselves can still be updated if they are mutable. Eg: Map<String, Vehicle>.. Vehicle object can still be updated. 167 | 168 | locations = new ConcurrentHashMap<String, Point>(points); 169 | 170 | unmodifiableMap = Collections.unmodifiableMap(locations); 171 | 172 | unmodifiableMap stores "live" view of the locations map (i.e. any update to locations are reflected in unmodifiableMap). 173 | 174 | To just give static view (non-live view) wrap it in new HashMap instance and then in unmodifiable. 175 | 176 | Collections.unmodifiableMap(new HashMap<String, Point>(locations));} 177 | 178 | #### Client-side locking 179 | 180 | It can be difficult, because client has to lock on same object which the ThreadSafeClass uses. For example creating a putIfAbsent method in List class 181 | 182 | - Cannot be achieved through having separate lock. 183 | - Can be achieved using same lock as the list. But here locks are spreads over 2 classes (this and List) 184 | - Best is to use composition, where you extend list, and ask clients to use this class. 185 | 186 | 187 | ### Building Blocks 188 | 189 | #### Iterators and ConcurrentModificationException 190 | 191 | Iterators are implemented by associating a modification count with the collection: if the modification count changes during iteration, hasNext or next throws ConcurrentModificationException. However, this check is done without synchronization, so there is a risk of seeing a stale value of the modification count and therefore that the iterator does not realize a modification has been made. This was a deliberate design tradeoff to reduce the performance impact of the concurrent modification detection code. 192 | 193 | Easiest way to avoid this, is to hold lock on the list/collection during iteration (in client code). This will come at a cost of scalability. This again, can be avoided, by making copy of entire collection (by wrapping in a lock), and then without locking iterating over that cloned collection. But this comes with increased cost of memory & speed (copying collection every time). 194 | 195 | There are also hidden iterators, like when you do toString on collection it internally iterates over all elements appending to StringBuilder. In such cases, on client side use the Collection.synchronizedSet() and then perform all operations. 196 | 197 | #### Concurrent Collections 198 | 199 | **Java 5** 200 | 201 | - ConcurrentHashMap instead of synchronizedMap (with operations put-if-absent, conditional remove, replace) 202 | - CopyOnWriteArrayList instead of synchronizedList 203 | - CopyOnWriteArraySet instead of synchronizedSet 204 | - Queue & BlockingQueue along with ConcurrentLinkedQueue 205 | - PriorityQueue (non concurrent) 206 | 207 | **Java 6** 208 | 209 | - ConcurrentSkipListMap instead of synchronized TreeMap 210 | - ConcurrentSkipListSet instead of synchronized TreeSet 211 | 212 | **ConcurrentHashMap** 213 | 214 | - Lock striping 215 | - Concurrent readers and writers, thus high throughput 216 | - Weakly consistent iterators instead of fail-fast 217 | - Weakly consistent size and isEmpty too 218 | - Cannot lock at client side using map object, because internally it uses different locks 219 | - Due to above reason, we cannot exclusively lock map and thus cannot write our own put-if-absent 220 | - Thus this map provides such operations put-if-absent, conditional remove, replace 221 | 222 | **CopyOnWriteArrayList & CopyOnWriteArraySet** 223 | 224 | - Do not throw ConcurrentModificationException 225 | - Copy underlying data during, modification 226 | - No locking needed during iteration 227 | 228 | **Other classes** 229 | 230 | - ArrayBlockingQueue & LinkedBlockingQueue 231 | - SynchronousQueue 232 | - ArrayDeque & LinkedBlockingDeque (work stealing: each consumer has its own deque and it steals from other consumer's deque's tail if its own is empty) 233 | 234 | #### InterruptedException 235 | 236 | - Threads waiting in blocked state can be interrupted, using interrupt method. It has boolean flag for setting this. 237 | - Good for cancelling long waiting tasks. 238 | - If your code calls method which throws InterruptedException then: 239 | - Choice 1 - Throw InterruptedException when called 240 | - Choice 2 - Catch it, and restore the interrupted flag 241 | 242 | #### Synchronizers 243 | 244 | + Latches 245 | - Can act as a gate, where all threads stop at the gate, and allowed once gate is opened. 246 | - This binary closed-open action is good for implementing 'Resource is initialized, now dependent actions can begin' 247 | - Eg: Wait for all dependent services to init, wait for all players to arrive, wait until all worker threads finish etc. 248 | - CountDownLatch: await method, thread waits till count decrements to zero, or is interrupted or wait times out 249 | - FutureTask can also act as latch. future.get() method waits until task is completed and returns results. 250 | 251 | + Semaphores 252 | - Permits (acquire and release) 253 | - Useful in creating bounded collections 254 | - Can instead use BlockingQueue, if resources themselves are to be tracked. Eg: Object pool 255 | 256 | + Barriers 257 | - Similar to Latches with key difference 258 | - Latches are waiting for events, barriers are waiting for other threads 259 | - CyclicBarrier waits for fixed number of threads arrive at a point, repeatedly. 260 | - If all threads reach barrier point, barrier is passed and it resets. 261 | - await call returns arrival index to each thread, which can be used to "elect" 262 | - CyclicBarrier constructor accepts count (of threads) and Runnable (to run when threads reach this point). 263 | - Excellent for assigning sub-problems to threads and merging all results when barrier is reached. 264 | 265 | + Exchanger 266 | - Similar to Barrier that both wait until other arrives at same point. 267 | - Once reached they can exchange an object. 268 | - This is transfer of ownership of object (safe publication) 269 | - Example: Consumer exchanging an empty buffer with the producer, for a full buffer. 270 | 271 | ### Task Execution 272 | 273 | #### Thread Pools 274 | 275 | Threadpool with its bounded pool helps throttle the inputs/requests so as to not exhaust available resources. 276 | 277 | Single Threaded Executors provide synchronization guarantee that writes made by a task will be visible to subsequent tasks. 278 | 279 | **Types** 280 | 281 | - newFixedSizeThreadPool - creates new thread, if one dies due to exception 282 | - newCachedThreadPool - keeps increasing threads 283 | - newSingleThreadExecutor - consumes task based on queue type (FIFO, LIFO, Priority etc), resurrects thread if dead 284 | - newScheduledThreadPool - supports delayed and periodic execution similar to Timer 285 | 286 | Usually shutdown call is immediately followed by awaitTermination. 287 | 288 | #### Uncaught exception handlers 289 | 290 | Thread provides facility for UncaughtExceptionHandler. When thread dies due to some exception, JVM checks if it has exception handler, if not it checks its ThreadGroup, if not then its super ThreadGroup and so on. Final system level ThreadGroup just prints stack trace to System.err 291 | 292 | #### Shutdown hooks 293 | 294 | - JVM also provides Runtime.addShutdownHook for when it attempts to shut down. 295 | - Then it runs finalizers if runFinalizerOnExit is true 296 | - It does not attempt to shutdown application threads, they die abruptly 297 | - If these hooks do not complete, they hang the JVM. Thus do proper synchronization and not dead lock them. 298 | 299 | #### Daemon threads 300 | 301 | - Daemon threads do not stop JVM to shutdown 302 | - GC, housekeeping threads are daemon threads 303 | - Threads inherit daemon status of the owner thread 304 | - When JVM halts, they do not call finally for daemon, nor cleanup their stacks, nor call finalizers. 305 | - Thus better to use them sparingly 306 | 307 | #### Finalizers 308 | 309 | - Opportunity given by JVM to reclaim/free any resources being held up 310 | - Not guaranteed to run 311 | - Avoid as much as possible, catch-finally can more often do better job 312 | 313 | ### Applying Thread Pools 314 | 315 | #### Thread pool sizes 316 | 317 | - If its too big, it can exhaust memory (& lot of overhead of creating/managing them) 318 | - If its too small, not completely utilizing the CPU 319 | - Usually, N (number of CPU cores) is right size of pools 320 | - Though, if tasks do IO then, not all threads will be schedulable (tasks will be waiting for some resource), so its okay to increase size of threadpool. 321 | - int N\_CPUS = Runtime.getRuntime().availableProcessors(); 322 | - Other deciding factors: memory, file handles, socket handles, and database connections 323 | 324 | #### ThreadPoolExecutor 325 | 326 | #### Threads 327 | - newFixedThreadPool: corePoolSize == maximumPoolSize 328 | - newCachedThreadPool: corePoolSize = 0 and maximumPoolSize = Integer.MAX\_VALUE 329 | - Keep alive: how long to wait before unused thread is reclaimed (trade off) 330 | 331 | #### Task Queues 332 | 333 | - newFixedThreadPool and newSingleThreadedExecutor use unbounded LinkedBlockingQueue 334 | - Try to use bounded (LinkedBlockingQueue, ArrayBlockingQueue or PriorityQueue) 335 | 336 | #### Saturation Policy 337 | 338 | - When bounded queue is full, what to do when task is submitted 339 | - Abort - throw RejectedExecutionException 340 | - Discard - discard silently 341 | - Discard oldest - discards oldest from queue 342 | - Caller Runs - return task to caller, so that caller thread can run it instead 343 | 344 | #### Thread Factory 345 | 346 | - Used to create new threads 347 | - By default new non-daemon threads are created 348 | - Can be overridden to create special threads which do say logging 349 | 350 | ### Avoiding Liveness Hazards 351 | 352 | #### Deadlocks 353 | 354 | - Database systems are great at handling deadlocks; they back-off certain transactions such that locks are released. 355 | - JVM is not so kind. When threads are deadlocked, that's it, game over. 356 | 357 | Transfer money is classic examples (with synchronized block on from and to accounts). If 2 calls are made, where 1st case arguments are from then to, and in 2nd case, its to then from. They may deadlock. To solve, either get comparable int keys or System.identityHashcode(), and order which account to be synchronized first. So no matter what's order of arguments, you always lock same account first, avoiding deadlock. 358 | 359 | **How to avoid** 360 | 361 | - Use only 1 locks (so no ordering issues) 362 | - Order locks if multiple (ensure ordering is same no matter order of arguments) 363 | - Use tryLock method of lock classes 364 | 365 | #### Starvation and LiveLock 366 | 367 | - Starvation is when thread is stuck 368 | - Livelock is when thread keeps running (eg: message listener throws exception, rolls back then again tries processing of same object) 369 | 370 | ### Performance and Scalability 371 | 372 | Amdhal's law - How much a program can be theoretically sped up. 373 | 374 | Trick is to divide into multiple tasks with their own data structures, and converge the results (this last step will be only step that will be sequential) 375 | 376 | ConcurrentLinkedQueue is twice as fast as synchronizedLinkedList, because former has only final pointer updates as sequential while latter synchronizes on whole list. 377 | 378 | #### Costs on performance 379 | 380 | - Context switching 381 | - Synchronization 382 | - Data locality (memory cache) 383 | - Blocking on locks 384 | 385 | #### Steps 386 | 387 | - Reduce lock contention 388 | - Reduce scope - get in / get out 389 | - Reduce lock granularity (too many times in and out is not good too) 390 | - Lock striping 391 | - Avoid hot fields 392 | - Non blocking (compare-and-swap) 393 | - Say no to object pooling - Java is super fast at new allocation, but getting objects from pool requires synchronization 394 | 395 | ### Explicit Locks 396 | 397 | #### Lock and ReentrantLock 398 | 399 | Lock implementations must provide the same memory-visibility semantics as intrinsic locks, but can differ in their locking semantics, scheduling algorithms, ordering guarantees, and performance characteristics. 400 | 401 | 402 | #### Advantages of lock classes 403 | 404 | - More flexible. Need not release lock in same block of code unlike synchronized 405 | - "Synchronized block" threads cannot be interrupted while they are waiting for lock. 406 | - lockInterruptibly can stop waiting for lock on interrupt 407 | - Deadlock can be avoided by trying to acquire lock, and releasing already acquired, if cannot acquire new one. 408 | - Intrinsic locks can't release locks on timeout 409 | - Since Java 6, performance of intrinsic and reentrant lock is very similar. Earlier it used to be slower. 410 | 411 | Always do lock.unlock in finally block 412 | 413 | Locks can be fair/unfair. Fair locks implement queues to handle requests for a lock. Ofcourse, fairness comes with cost of performance. 414 | 415 | #### Read-Write lock 416 | 417 | - Allows multiple concurrent readers, but only single writer 418 | - Great for data structure with lot of reads 419 | - More complex to implement thus slightly slower than reentrant lock 420 | 421 | **Implementation factors** 422 | 423 | - Release preference - If writer is running, and readers+writers are waiting, preference to writer? 424 | - Reader barging - If reader is running, and readers+writers are waiting, preference to reader? Good for throughput but writer can become starved 425 | - Reentrancy - Are they reentrant 426 | - Downgrading - what if writer lock owners wants only reader lock 427 | - Upgrading - What if reader lock owner also wants writer lock 428 | 429 | #### Custom Synchronizer 430 | 431 | Conditional queues - Threads waiting for an object lock which reflects certain condition. 432 | 433 | Explicit class called Condition for implementing conditional queues (which can be implemented using intrinsic locks too). 434 | 435 | Condition is associated with single lock. Lock.newCondition() 436 | 437 | **Advantages** 438 | 439 | - Fairness in wait 440 | - Timeout facility (flexibility) 441 | -------------------------------------------------------------------------------- /topics/core/core-java.md: -------------------------------------------------------------------------------- 1 | ## Core Java 2 | 3 | This page focuses on oddities of Core Java from an interview perspective. For basic 4 | topics like inheritance, interfaces, etc. please read the book mentioned below. 5 | 6 | ### Resources 7 | 8 | - [OCA/OCP Java SE 7 Programmer I & II Study Guide](http://www.amazon.in/Programmer-Study-1Z0-803-1Z0-804-Certification/dp/0071772006) 9 | 10 | ### Default init values 11 | 12 | - For fields (class level variables), values are auto assigned default values. 13 | - Method local variables should be manually assigned. 14 | - Default values (references = null, primitives = 0, boolean = false) 15 | - Arrays initialize its elements: int[] numbers = new int[10]; will assign all ints in the array to 0. 16 | 17 | ### String pool 18 | 19 | - String constants are placed in a memory pool 20 | - When retrieved, returns reference to string in the pool. 21 | - Pool saves memory. New string constants with same value share same instance in the pool. 22 | - String is immutable thus these values are never changed. For any updates, new string constant is created. 23 | - String s = "abc" will place "abc" in pool and return its reference. 24 | - String s = new String("abc") will also place "abc" in pool, as well as allocate new memory 25 | - [implementation details](jvm-internals.md#string-interning) 26 | 27 | ### Wrapper class pool 28 | 29 | - Boolean 30 | - Byte 31 | - Character from \u0000 to \u007f (7f is 127 in decimal) 32 | - Short and Integer from –128 to 127 33 | 34 | ### Singleton options 35 | 36 | - Using: static final variable (init guarantee) 37 | - Using: Lazy loading (double checked) 38 | - Using: Enums (by default lazy, and init guarantee) 39 | 40 | ### Override method rules 41 | 42 | - Same method name and parameter types 43 | - Same or a subset of super methods' checked exceptions 44 | - Any number of runtime exceptions 45 | - Same or covariant return type 46 | 47 | ### Covariant variables 48 | 49 | - Variable types which are compatible. 50 | - Eg: an int is covariant of long 51 | - Eg: an Lion class is covariant of Animal class (only if Lion extends Animal) 52 | - Can be used in parameters, return types or assignments 53 | 54 | ### Varargs, boxing, widening 55 | 56 | - Primitive Widening > Boxing > Varargs. [Example](http://stackoverflow.com/a/2128068/3494368). 57 | - Widening then Boxing not allowed. 58 | - Boxing then Widening allowed. 59 | - Widening between wrapper classes not allowed (eg: Long n = new Integer(10); not allowed) 60 | 61 | ### Inner classes 62 | 63 | Personally I find this part of Java to be super annoying, unnecessary and hardly ever used in real-life (especially after Java 8). 64 | Also, this topic does not come up a lot in interviews, so just skimp through. 65 | 66 | - Inner class: Can access enclosing class's variables (even private ones) 67 | - Method local inner class: Same as above. Plus, it can access final variables in encapsulating method. 68 | - Anonymous inner class: Just no name, otherwise same as above. 69 | - Static inner class: No special relationship with outer class. 70 | 71 | ### Reference types 72 | 73 | - **Weak reference** - Eligible for GC if object not referenced by any other variables. Good for caches. Are enqueued in ReferenceQueue just before GC (object can be resurrected in finalize). Returns null once object is eligible for GC, even if object is resurrected, the weak-reference still is dead, and will return null. 74 | - **Soft reference** - Same as above, but its GC’ed only when memory is low. Excellent for caches. 75 | - **Phantom reference** - Even after GC, it references the object, until the memory is reclaimed. Enqueued in ReferenceQueue after complete reclamation. Always returns null, so that you cannot resurrect it. Can be helpful to check when memory is reclaimed so that you can load next large object. 76 | - **WeakHashMap** - Weak keys. Removes entry once key is GC’ed. 77 | 78 | ### Cloning 79 | 80 | - clone method (protected) of Object class returns shallow copy. Need to be explicitly cast back. 81 | - Requires class to implement Cloneable marker interface. Else returns CloneNotSupportedException 82 | - Singletons should override clone method and throw CloneNotSupportedException 83 | - [More details](../design/effective-java.md#clone) 84 | -------------------------------------------------------------------------------- /topics/core/garbage-collection.md: -------------------------------------------------------------------------------- 1 | ## Garbage Collection 2 | 3 | ### Resources 4 | 5 | - [GC Overview by Martin Thompson](http://mechanical-sympathy.blogspot.in/2013/07/java-garbage-collection-distilled.html) - Highly recommended 6 | - [Detailed overview of all GC collectors](https://plumbr.eu/handbook/garbage-collection-algorithms-implementations) 7 | - [Modern Garbage Collection (GC Trade-offs)](https://blog.plan99.net/modern-garbage-collection-911ef4f8bd8e#.qcnv033nr) 8 | - [Internals of G1 collector](https://www.youtube.com/watch?v=Gee7QfoY8ys) 9 | - [Overview of Shenondoah collector](https://www.youtube.com/watch?v=N0JTvyCxiv8) 10 | 11 | ### Quick Glance 12 | 13 | 14 | | Collector | Pros | Cons | Use-Case | 15 | | --- | --- | --- | --- | 16 | | Serial | Fast promotion and minor GC (Bump the pointer)
Smallest footprint | Single Thread | Limited memory (embedded).
CPU running lot of JVMs (helps limit GC impact other JVMs) | 17 | | Parallel | Fast promotion and minor GC (Bump the pointer)
Higher Throughput (doesn't run with application) | High worst-case latency (due to compaction) | Batch applications | 18 | | CMS | Low STW pauses (Concurrent mark).
Low worst case latency. | Slow promotion & Minor GC (free lists)
Reduced throughput
Higher footprint. | General applications | 19 | | G1 | Incremental collection
Lower worst case latency
Relatively faster promotion (no free lists)
More throughput (no compaction) | Higher footprint | Predictable/Target latency applications.
Large heaps | 20 | | Shenondoah | Lower latency | Higher footprint | Even lower latency
Much Larger heaps | 21 | 22 | 23 | ### Concepts 24 | 25 | - Throughput - Percentage of time application runs vs GC 26 | - Latency - Amount of pause time for application waiting for GC to complete 27 | - Memory - Amount of memory used to store the objects aka heap (along with GC related data structures) 28 | 29 | ### Trade offs 30 | 31 | - If memory is less, throughput is less, because JVM has to constantly do GC 32 | - If memory is more, latency is high, because JVM has to sweep huge space to do GC 33 | 34 | ### Use cases 35 | 36 | - For trading applications, deterministic (more average) latency is better than sudden spikes (increased worst case latency). 37 | - For batch applications, it might be ok for increase worst case latency, if it helps gain more throughput 38 | 39 | ### Tweaks 40 | 41 | - To large extent, more memory for GC helps in increasing throughput 42 | - Worst case latency can be reduced by keeping heap size small (& live set small) 43 | - Frequency of GC can be reduced by managing heap & generation sizes 44 | - Frequency of large pauses can be reduced by running GC with application, sometimes at cost of throughput (because it runs longer due to 2 STW pauses, and one thread is used by GC which could've been used by application). 45 | 46 | ### Object lifetimes 47 | 48 | - Infant mortality / Weak generational hypothesis - Most objects die young. 49 | - Thus, generational GC algorithms provide magnitude-of-order better throughput. 50 | - How? Region with newly allocated object is sparse for live objects, they can be quickly copied over and region can be wiped entirely. 51 | - If application keeps allocating objects that live too long. The generational split becomes useless, and GC takes long time. Because old generation is too big (& not so sparse). 52 | - Lifetime of object is recorded by JVM as number of GC cycles survived. 53 | 54 | ### Stop the World Events 55 | 56 | - Collectors need application execution to stop for practical reasons. 57 | - Threads are signalled to stop. Threads stop when they reach safe points of execution. 58 | - If thread is busy (copying large array, cloning a large object), it might be few milliseconds till this point. 59 | - ‑XX:+PrintGCApplicationStoppedTime this flag is used to print the time taken to reach safe point. 60 | - Once GC STW event is over, all threads are free to resume. An application with large number of threads can suffer scheduling pressure. It might be more efficient to use different collector then. 61 | 62 | ### Heap organization in HotSpot 63 | 64 | - Heap is split in Young and Old (Tenured) generation 65 | - Young generation is split in - Eden and Survivor (1,2) spaces 66 | - PermGen is used to store effectively immortal objects (Classes, static strings etc). 67 | - In Java 7, interned Strings were removed from PermGen. 68 | - In Java 8, PermGen space itself is replaced by MetaSpace. 69 | 70 | ### Object allocation 71 | 72 | - Each thread is assigned TLAB (Thread Local Allocation Buffer) to allocate new objects. 73 | - Since there is no conflict between threads, object allocation is just a bump-the-pointer, and is faster than MALLOC in C. Roughly 10 machine instructions. 74 | - When TLAB is exhausted new TLAB is requested from Eden. If Eden is filled, Minor GC is triggered. 75 | - If a large object (size greater than TLAB) is to be allocated, it is done directly in Eden or Old Generation. 76 | - -XX:PretenureSizeThreshold=<n> If this is smaller than TLAB, then small objects are still allocated in TLAB itself, not in Old generation. 77 | 78 | ### Minor Collection 79 | 80 | - Called when Eden is full. 81 | - Live objects are moved to one of the survivor spaces. 82 | - If survivor space is full or object has live too long (XX:MaxTenuringThreshold=<n>) it is moved to tenured generation. 83 | - Major cost of minor collection is in copying live objects to survivor / old generation. Thus, overall cost depends on number of objects to be copied not the size of Eden. 84 | - Thus, if new generation size is doubled, total minor GC time is almost halved (thus increasing the throughput). Assuming number of live objects remain constant. 85 | - Minor collections are STW events. This is becoming an issue as heaps are getting larger, with more and more live objects. 86 | - This algorithm is called mark-and-copy 87 | 88 | ### Marking Live Objects 89 | 90 | - All objects in graph starting from GC Roots 91 | - GC roots = references from application, JVM internal static fields and thread stack-frames 92 | - References from old generation to young generation (aka cross generational references) are also tracked 93 | - Card tables are used for this. Card tables are array of bytes. Each byte represents 512 bytes of old gen. If byte is set, it means corresponding 512 bytes of old gen has reference to young gen objects. 94 | - During minor collection, all such cards are checked, then all those 512 byte regions are checked for references. Thus, minor collection latency also depends on number of old gen to young gen references. 95 | 96 | ### Major Collection 97 | 98 | - JVM tries to predict, set % threshold and start collection when threshold is passed. 99 | - When object cannot be promoted from younger gen due to lack of space in old gen, then FullGC is triggered. 100 | - FullGC = minor collection + major collection (including compaction). 101 | - FullGC is also triggered when old gen size needs to be changed. This can be avoided by keeping Xms same as Xmx 102 | - Compaction is likely to cause largest STW 103 | 104 | ### Serial Collector 105 | 106 | - Smallest footprint of any collectors 107 | - Uses single thread for both minor and major collections. 108 | - Objects in old gen are allocated with simple bump the pointer technique 109 | - Major GC is triggered when old gen is full 110 | 111 | ### Parallel Collector 112 | 113 | - Parallel Collector - Multiple threads for minor GC, and single thread for major GC. 114 | - Parallel Old Collector - Multiple threads for both minor and major GC. Default since Java 7u4 115 | - Doesn't run with the application. 116 | - Greatest throughput in multi-processor systems. Great for batch applications. 117 | - Cost of Old GC, is proportional to number of objects, thus doubling old gen size can help in increasing throughput (larger but fewer GC pauses). 118 | - Minor GCs are fast because promotion in old gen is just bump-the-pointer. 119 | - Major GC takes 1-5 seconds per live data 120 | - Allows for -XX:+UseNUMA to allocate Eden space per CPU socket (can increase performance) 121 | 122 | ### Concurrent Mark and Sweep 123 | 124 | - Parallel (multiple threads) for Minor GC 125 | - Runs with application to try to avoid promotion failure. Promotion failure causes FullGC. 126 | - CMS = 127 | - Initial mark = Find GC roots 128 | - Concurrent mark = mark all objects from GC root 129 | - Concurrent pre-clean = check for updated object references & promoted objects during mark (Card Marking technique) 130 | - Re-mark = mark all objects in pre-clean 131 | - Concurrent sweep = reclaim memory and update free-lists 132 | - Concurrent reset = reset data structures used 133 | - During concurrent sweep, promotions can occur, but those are in free-lists which are not being swept anyways. So there is not conflict. 134 | - Minor GCs can keep happening while Major GC is happening! Thus the pre-clean phase. 135 | - Slower minor GCs during promotion. Cost of promotion is higher since, free-lists have to be checked for suitable sized hole. 136 | - CMS is not compacting collector, so when object promotion fails due to not having enough space in free-lists. CMS is followed by compaction. This latency can be worse than Parallel Old collector. 137 | - Decreases latency, but less throughput. Avg ¼ GC threads per 1 CPU core. 138 | - Throughput reduction between 20-40% compared to parallel collector (& based on object allocation rate). 139 | - 20% more space required. 140 | - "Concurrent mode failure" - When CMS cannot keep up with high promotion rates. Increasing heap makes it even worse, because sweeping will take even more time. 141 | 142 | ### [G1 Garbage First](https://www.youtube.com/watch?v=Gee7QfoY8ys) 143 | 144 | - Soft real-time targets. Spend x milliseconds in GC out of y milliseconds. 145 | - Divides heap into large regions ~2048 146 | - Categorizes regions in Eden, Survivor and Old gen spaces. 147 | - Minor GC is triggered, when all Eden regions are filled. 148 | - Selects closest set of nearly free regions (called Collection Set), to move live objects, essentially causing regions to be empty. Thus it approaches problem incrementally, as opposed to CMS which has to perform on entire Old gen. 149 | - Objects larger than 50% of region are saved in "humungous region" 150 | - Regions can have objects being referenced from multiple other regions. These are tracked using Reference Sets. Thus, while moving live objects, all the references to such objects need to be updated. Thus, even minor collections can potentially be longer than Parallel or CMS collector. 151 | - It avoids collecting (moving) from regions which have high references. Unless it has no other option. 152 | - G1 is target driven on latency –XX:MaxGCPauseMillis=<n>, default value = 200ms 153 | - G1 reduces worst case latency, at the cost of higher average latency. 154 | - Compactions are piggybacked on Young Gen GC. 155 | - During reference changes, cards (arrays pointing to 512 bytes of a region) are marked dirty, and source-target details are placed in dirty card queue. Depending on number of elements in queue (white, green, yellow, red) G1 starts threads which take information from queue and write to Remembered Set. More the queue is full, more G1 threads try to drain it. Remembered set will be heavily contended if all threads directly write to RS, its better if only specific G1 threads (1 or 2) write to them. 156 | - If Young GC cannot finish within maxTargetPauseTime, then # of Eden regions are reduced to finish within the target. 157 | - Old GC is triggered when total 45% is full, and is checked just after Young GC or after allocating humongous object. 158 | 159 | ### [Shenandoah](https://www.youtube.com/watch?v=N0JTvyCxiv8) 160 | 161 | - 10% hit in throughput, but 7x more responsive. 162 | - Avg Pause 5x better - 60ms (vs 600ms in G1). 163 | - Max Pause 3x better - 500ms (vs 1700ms). Lot of headroom. 164 | - Target - 10ms average, and max 100ms. 165 | - Region based like G1 (remembered sets, collection sets) 166 | - Concurrent mark and sweep same as CMS and G1 167 | - It does compaction though + concurrently while threads are running 168 | - Trick is to create indirection pointer to objects, and after copying live objects, atomically update the indirection pointer to copied version of the objects. 169 | - Not Generational. Claim is, Weak Generational Hypothesis is no longer applicable. 170 | 171 | ### Other pauses not related to GC 172 | 173 | - Networking, Disk read/writes, Waiting for DBs 174 | - OS interrupts (~5ms), this doesn't show up in logs 175 | - Lock contention 176 | 177 | -------------------------------------------------------------------------------- /topics/core/java-8.md: -------------------------------------------------------------------------------- 1 | ## Java 8 2 | 3 | * [Streams](#streams) 4 | * [Examples:](#examples-) 5 | * [Comparators](#comparators) 6 | * [Concurrency](#concurrency) 7 | * [CompletableFuture](#completablefuture) 8 | * [StampedLock](#stampedlock) 9 | * [@Contended](#-contended) 10 | 11 | ### Streams 12 | 13 | **Create** 14 | 15 | - Stream.of(T… a) 16 | - IntStream.rangeClosed(start, end) + LongStream & DoubleStream 17 | - Arrays.stream(array) 18 | - list.stream() 19 | - list.parallelStream() 20 | - Files.getLines() 21 | - Stream.generate(() -> Math.random()); 22 | 23 | **Filter** 24 | 25 | - findAny 26 | - findFirst 27 | - filter 28 | - distinct 29 | - limit(long) 30 | - skip(long) 31 | 32 | **Operations** 33 | 34 | - sorted 35 | - boxed 36 | - min(comparator) 37 | - max(comparator) 38 | - count 39 | - forEach 40 | - flatMap // when each element maps to n elements 41 | - toArray 42 | - reduce (0, (c, e) -> c + e); // accumulator, reducer function 43 | - reduce (0, Integer::sum); 44 | 45 | **Collectors** 46 | 47 | - Collectors.toList() 48 | - Collectors.toSet() 49 | - Collectors.toMap(keyMapper, valueMapper) 50 | - Collectors.toCollection(TreeSet::new) 51 | - Collectors.joining(", ") // needs stream of strings, use map(Object::toString) before this 52 | - Collectors.summingInt(Employee::getSalary) 53 | - Collectors.averagingInt(Employee::getSalary) 54 | - Collectors.summarizingInt(Employee::getSalary) [gives stats max,min,count,average] 55 | - Collectors.groupingBy(Employee::getDepartment) 56 | 57 | ### Examples: 58 | 59 | **FlatMap** 60 | 61 | ``` 62 | Stream lines = Files.lines(path, StandardCharsets.UTF_8); 63 | Stream words = lines.flatMap(line -> Stream.of(line.split(" +"))); 64 | ``` 65 | 66 | **Typical** 67 | 68 | ```java 69 | books.stream() 70 | .filter(book -> book.year > 2005) // filter out books published in or before 2005 71 | .map(Book::getAuthor) // get the list of authors for the remaining books 72 | .filter(Objects::nonNull) // remove null authors from the list 73 | .map(Author::getName) // get the list of names for the remaining authors 74 | .forEach(System.out::println); // print the value of each remaining element 75 | ``` 76 | 77 | **Read Large File** 78 | 79 | Does not load whole file in memory. Though exceptions are wrapped in UncheckedIOException. 80 | 81 | ```java 82 | try(Stream stream : Files.lines(Paths.get(“absolute-path”))){ 83 | stream.forEach(System.out::println); 84 | } 85 | ``` 86 | 87 | **Group By** 88 | 89 | 90 | ```java 91 | Map> byGender 92 | = roster.stream().collect(Collectors.groupingBy(Person::getGender)); 93 | 94 | ConcurrentMap> byGender 95 | = roster.parallelStream().collect(Collectors.groupingByConcurrent(Person::getGender)) 96 | 97 | // Group employees by department 98 | Map> byDept 99 | = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment)); 100 | 101 | // Compute sum of salaries by department 102 | Map totalByDept 103 | = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment,Collectors.summingInt(Employee::getSalary))); 104 | 105 | // Partition students into passing and failing 106 | Map> passingFailing 107 | = students.stream().collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD)); 108 | ``` 109 | 110 | 111 | ### Comparators 112 | 113 | vehicles.sort(Comparator.comparing(Vehicle::getWheels)); 114 | vehicles.sort(Comparator.comparing(Vehicle::getWheels)); 115 | vehicles.sort(Comparator.comparing(Vehicle::getWheels).thenComparing(Vehicle:getColor); //chaining 116 | 117 | 118 | ### Concurrency 119 | 120 | **HashMap** 121 | 122 | - compute 123 | - computeIfPresent (blocking, so write smaller computations) 124 | - computeIfAbsent (blocking, so write smaller computations) 125 | - putIfAbsent 126 | - merge 127 | - getOrDefault (k, def) 128 | 129 | **Adders/Accumulators** 130 | 131 | Much more performant than AtomicLong (have single copy across threads). Accumulators, each thread has own copy tracking its own counter, and when retrieval is triggered in any thread, all threads coordinate and perform total sum of all threads’ counts. 132 | 133 | Basically no contention, during increment, decrement, add, thus much faster. 134 | 135 | - LongAdder 136 | - DoubleAdder 137 | - LongAccumulator 138 | - DoubleAccumulator 139 | 140 | Operations 141 | 142 | - increment 143 | - decrement 144 | - add (long) 145 | - sum // retrieves result by coordinating between threads 146 | - reset 147 | 148 | ### CompletableFuture 149 | 150 | Similar to JavaScript promises. Multiple async tasks can be chained (performed one after another on separate thread). Better alternative to ```future``` where the method ```get``` is blocking (waits indefinitely for the result). In completableFuture the current thread is not blocked. Each task is executed once previous task is completed. 151 | 152 | Also, the program itself becomes more readable. 153 | 154 | ```java 155 | CompletableFuture.supplyAsync(() -> getStockInfo(“GOOGL”), executor) // if executor is not passed it uses internal pool 156 | .whenComplete((info, exec) -> System.out.println(info)) // triggered once previous operation is finished 157 | .thenApply(Stock::getRate) 158 | .thenAccept(rate -> System.out.println(rate)) 159 | .thenRun(() -> System.out.println(“done”))); 160 | ``` 161 | 162 | So when you trigger this, it immediately returns the CompletableFuture instance, which can be used to check its status and such. 163 | 164 | - supply method takes ```Supplier``` which returns a value 165 | - thenApply method argument is ```Function``` which takes input and returns value 166 | - thenAccept method argument is ```Consumer``` which takes input 167 | - thenRun method argument is ```Runnable``` which only runs 168 | - CompletableFuture has no control of tasks while they are running in the executor. So cancel method just sets returned value as Exceptional. 169 | 170 | ### StampedLock 171 | 172 | - Better alternative for ReadWriteLock 173 | - It does optimistic reads so works faster only on less contended operations 174 | - Not re-entrant 175 | 176 | ### @Contended 177 | 178 | For fields shared within same cache line and if only 1 field in it is volatile, then for multiple threads, the cache line will be flushed and will be updated. Thus use of cache is of no use. 179 | To fix this, set the field to hot field by using @Contented so that JVM can pad the field so that it takes entire cache line and is not shared with other fields. 180 | 181 | [Talk explaining the @Contented](https://www.youtube.com/watch?v=Q_0_1mKTlnY) 182 | 183 | 184 | -------------------------------------------------------------------------------- /topics/core/java-memory-model.md: -------------------------------------------------------------------------------- 1 | ## Java Memory Model 2 | 3 | ### Resources 4 | 5 | - [The Java memory model made easy by Rafael Winterhalter](https://vimeo.com/181788144) - Highly Recommended 6 | 7 | ### What is it? 8 | 9 | - Specification deciding how JVM can reorder instructions (for performance) aka ensures guaranteed ordering of of reads and writes under certain conditions (happens-before). Every JVM has to implement this spec. 10 | - Barriers that forbid reordering instructions (load-load, load-store, store-load, store-store) 11 | - Variables 12 | + volatile 13 | + final = all writes before volatile write will be reflected when/after volatile is read (potentially by other thread). Threads need to use the same volatile variable for this to work. For double/long (which occupy multiple word spaces, word-breakdown is forbidden to ensure integrity of data). 14 | - Methods - synchronized 15 | - Locks - normal objects used as locks, and lock classes like ReadWriteLock. 16 | - Threads - When a new thread is started, it is guaranteed to see all values written before thread started. 17 | 18 | ## More details 19 | 20 | This topic overlaps quite a bit with Concurrency. Please read [corresponding wiki page](concurrency.md) -------------------------------------------------------------------------------- /topics/core/jvm-internals.md: -------------------------------------------------------------------------------- 1 | ## JVM Internals 2 | 3 | Some of the topics listed below are tricks JVM uses to improve performance. Subset of these can be exploited to further improve 4 | application performance. 5 | 6 | Note: These topics are highly unlikely to come up in an interview. Feel free to just glance through without digging deep. 7 | 8 | ### Compressed pointers 9 | 10 | - 32 bit references can address 4GB, while 64 bit can reference 2^64 bytes (though limited by OS/RAM on the machine). 11 | - Having 64 bit reference for every object increases memory usage. JVMs use [compressed pointers](https://wiki.openjdk.java.net/display/HotSpot/CompressedOops) to address this issue. 12 | - Basic idea is to store 32-bits per reference and then add to a base address to find final 64-bit address. 13 | - Flag: `-XX:+UseCompressedOops`. Latest versions of 64-bit Java have this argument by default. 14 | - Addresses upto 4gb untranslated. 15 | - Addresses 4gb to 28gb, remove 3bits, because Java has 8 byte word aligned, thus 3 bits need not be stored. 16 | - Important because Java has more references. In C++ memory layout follows struct layout. 17 | - Java 8 has JVM args, `+XX:ObjectAlignmentInBytes=16` for heap between 32gb and 64gb. 18 | 19 | ### String interning 20 | 21 | - Interning = storing strings in a pool and re-using them 22 | - If you intern a set of all strings, you can compare them by == improving performance. 23 | - It is stored internally as a hashmap (it is native C code, not Java code). 24 | - More details [here](http://java-performance.info/string-intern-in-java-6-7-8/) and [here](http://java-performance.info/changes-to-string-java-1-7-0_06/) 25 | - How would you implement your own string interning? 26 | 27 | ```Java 28 | private static final WeakHashMap> s_manualCache 29 | = new WeakHashMap>(100000); 30 | 31 | private static String manualIntern(final String str){ 32 | final WeakReference cached = s_manualCache.get(str); 33 | if (cached != null){ 34 | final String value = cached.get(); 35 | if (value != null) 36 | return value; 37 | } 38 | s_manualCache.put(str, new WeakReference(str)); 39 | return str; 40 | } 41 | ``` 42 | 43 | ### Thread Affinity 44 | 45 | Makes the thread stick to a CPU core, even if it has no tasks left to perform. Unlike normal threads, this won't go into sleep/wait. 46 | Thread performs busy-spin. Note: This is wasting of CPU resources, and it can lead to thread starvation since other threads 47 | do not get access to that core. Thus, it needs to be used for the right applications. Helpful in latency critical applications like FX Trading. 48 | 49 | Thread affinity only works for Linux and there are [Java libraries available](https://github.com/OpenHFT/Java-Thread-Affinity) to use the same 50 | 51 | ### Other topics 52 | 53 | - [How does default hashCode method work?](https://srvaroa.github.io/jvm/java/openjdk/biased-locking/2017/01/30/hashCode.html) 54 | - [What is Biased locking](https://blogs.oracle.com/dave/entry/biased_locking_in_hotspot) 55 | - [JVM Threads link with OS threads](http://openjdk.java.net/groups/hotspot/docs/RuntimeOverview.html#Thread%20Management%7Coutline) 56 | - [Class Loaders](https://zeroturnaround.com/rebellabs/rebel-labs-tutorial-do-you-really-get-classloaders/) 57 | - [Memory consumptions of primitives and boxed variables](http://java-performance.info/overview-of-memory-saving-techniques-java/) 58 | - Hoisting variables: JVM can hoist variables out of for loops to improve performance. [example](http://stackoverflow.com/a/9338302/3494368) 59 | - Escape analysis: JVM can choose to place a method local object (if it never escapes the method) in Thread-stack instead of heap. 60 | Improves performance since that object doesn't go through GC (can be just deleted once method completes). -------------------------------------------------------------------------------- /topics/design/approach.md: -------------------------------------------------------------------------------- 1 | ## Resources 2 | 3 | - [Google Interview University](https://github.com/jwasham/google-interview-university#system-design-scalability-data-handling) 4 | - [High Scalability examples](https://www.hiredintech.com/classrooms/system-design/lesson/61) 5 | - [HiredInTech](https://www.hiredintech.com/classrooms/system-design/lesson/60) 6 | - Go through [this video](https://www.youtube.com/watch?v=PJKYqLP6MRE) 7 | 8 | ### Communication 9 | 10 | What do they look for? 11 | 12 | **Problem solving skills** 13 | 14 | - How many clarify problem statement 15 | - Ask questions and not make assumptions 16 | - Mention edge cases 17 | - Walk through the problem one thing at a time 18 | - Code beautifully (not syntax wise though) 19 | - Test the code once code completed and then only say it is done 20 | 21 | **Working on large systems** 22 | 23 | - How will you design systems 24 | - High QPS what will you do 25 | - If any issue how do you go about resolving it 26 | 27 | ### System Design 28 | 29 | **Sample Design questions** 30 | 31 | - Tic Tac Toe 32 | - Minesweeper 33 | - Web Crawler 34 | - TinyURL 35 | - Air Traffic Controller 36 | - Conference Scheduler 37 | - Adhaar enrollment 38 | - Healthcare data collection by government (Thoughtworks) 39 | 40 | ### Approach 41 | 42 | - Clarify assumptions regarding domain - features required 43 | - Expected traffic/volume/data (calculate/assume) 44 | - Expected frequency or repeated calls - Pre-processing of data (eg: Dictionary) 45 | - Constraints - Bandwidth/Latency, CPU/Memory/Disk 46 | - Scaling - Vertical / Horizontal(duplicate/load-balancing, key-hash, directory-based, service-based) 47 | - Caching - LRU, LFU, Timeouts 48 | - Heavy writes - Asynchronous (Task Queues) 49 | - Single point of failures 50 | - Monitoring/Analytics 51 | - Staggered/Back-pressure 52 | - Batching/Chunking 53 | - Geographic split (behavioral/regulatory) 54 | - CDN (static content) 55 | 56 | ### Scalability 57 | 58 | - Horizontal scaling 59 | - Caching 60 | - Load balancing 61 | - Database replication 62 | - Database partitioning 63 | - NoSQL 64 | - Asynchronous (Job Queues) 65 | 66 | -------------------------------------------------------------------------------- /topics/design/design-patterns.md: -------------------------------------------------------------------------------- 1 | ## Design Patterns 2 | 3 | ### Resources 4 | 5 | - [Design patterns explained too simply](https://github.com/kamranahmedse/design-patterns-for-humans) 6 | - [Examples of design patterns in Java libraries](http://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries/2707195#2707195) 7 | 8 | ### Creational 9 | 10 | - Singleton - Single instance of class. Either Eager (static) or Lazy (broken pre-JDK5). Eg: Logger, Configurer 11 | - Factory - Create types of instances. Eg: Trade type (Bonds, Bill, Notes) 12 | - Abstract Factory - Factory of factories of related products. Eg: Trade Type (GermanBond, EuroBond, GermanBill, EuroBill) 13 | - Builder - Eg: StringBuilder, PizzaMaker 14 | - Prototype - Copying costly-creation objects. Classes should implement clone or similar method. 15 | - Object pool - Re-use instances. Eg: Threadpool 16 | 17 | ### Behavioral 18 | 19 | - Observer - Reactive streams. 20 | - Strategy - Encapsulate algorithms and execute either. Eg: Trading strategy, select one and execute. 21 | - Command - Object encapsulates action with common interface which executor calls. Eg: Remote click. 22 | - State - Behavior based on current state of object. 23 | - Visitor - Object which visits all similar instances. Eg: File Traverse, or Calculate total bill from cart. 24 | - Iterator - Iterating through a collection of objects. 25 | - Chain of Responsibility - object passes through various instances, coordinated by Handler. Eg: Stream API 26 | - Template - Eg: HTML templates 27 | - Interpreter - Format converter. Eg: JVM converts byte to native for JVM. 28 | - Memento - Save and restore state of object. 29 | 30 | ### Structural 31 | 32 | - Adapter - Adapting to a non-direct-compatible class/module/system. 33 | - Decorator - Wrap class with another Eg: FileReader, BufferedReader 34 | - Facade - Hiding complexity behind simple interfaces. Eg: Turbo Tax 35 | - Proxy - Eg: Hibernate proxy for lazy fetch. @Spy instances for JUnit/Mockito. 36 | - Flyweight - Store common characteristics of multiple objects in single place. Eg: Glyph for all characters in a document. 37 | - Bridge - Decouple abstraction from implementation so that both can vary independently. Bridge pattern is often created using Adapter pattern. 38 | - Composite - Eg: Folder and files 39 | 40 | 41 | -------------------------------------------------------------------------------- /topics/design/effective-java.md: -------------------------------------------------------------------------------- 1 | ## Effective Java 2 | 3 | #### Resources 4 | 5 | - [Effective Java by Joshua Bloch](https://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683) -- Highly recommended 6 | 7 | ### Table of Contents 8 | 9 | - [Creating and Destroying Objects](#creating-and-destroying-objects) 10 | * [Consider static builders](#consider-static-builders) 11 | * [Service Interface Pattern](#service-interface-pattern) 12 | * [Builder pattern](#builder-pattern) 13 | * [Singleton with private instance or enum](#singleton-with-private-instance-or-enum) 14 | * [Private Constructor](#private-constructor) 15 | * [Avoid creating unnecessary objects](#avoid-creating-unnecessary-objects) 16 | * [Clear memory references](#clear-memory-references) 17 | * [Avoid finalizers](#avoid-finalizers) 18 | - [Methods common to all objects](#methods-common-to-all-objects) 19 | * [equals](#equals) 20 | * [hashcode](#hashcode) 21 | * [toString](#tostring) 22 | * [clone](#clone) 23 | * [comparable](#comparable) 24 | - [Classes and Interfaces](#classes-and-interfaces) 25 | * [Accessibility](#accessibility) 26 | * [Private fields with accessor methods](#private-fields-with-accessor-methods) 27 | * [Make fields as much immutable as possible](#make-fields-as-much-immutable-as-possible) 28 | * [Composition over inheritance](#composition-over-inheritance) 29 | * [Override in inheritance](#override-in-inheritance) 30 | * [Prefer interfaces to abstract classes](#prefer-interfaces-to-abstract-classes) 31 | * [Class hierarchies over tagged classes](#class-hierarchies-over-tagged-classes) 32 | * [Function objects to represent strategies](#function-objects-to-represent-strategies) 33 | * [Favor static member class over non-static](#favor-static-member-class-over-non-static) 34 | - [Generics](#generics) 35 | * [Don't use Raw types](#don-t-use-raw-types) 36 | * [Prefer Lists to arrays](#prefer-lists-to-arrays) 37 | - [Enums and Annotations](#enums-and-annotations) 38 | * [Enums instead of int constants](#enums-instead-of-int-constants) 39 | * [Prefer annotations over naming patterns](#prefer-annotations-over-naming-patterns) 40 | - [Methods](#methods) 41 | * [Definition](#definition) 42 | * [Var args](#var-args) 43 | * [Return empty collections instead of null](#return-empty-collections-instead-of-null) 44 | - [General](#general) 45 | * [Use Serializable Judiciously](#use-serializable-judiciously) 46 | 47 | ### Creating and Destroying Objects 48 | 49 | #### Consider static builders 50 | 51 | - They can have any name, thus can have multiple methods with same parameters (unlike constructors) 52 | - They can return cached objects (eg: Boolean.valueOf) 53 | - They can return their subtype, even class objects which are not public. Eg: Collection has 32 factory methods, return type of many are non-public classes. Ofcourse, the interface they extend is public. Returning such interface backed classes, also help in returning specific type based on argument. Eg: EnumSet returns RegularEnumSet or JumboEnumSet based on the argument. In future, JDK can add more types, without client/caller knowing about them. See service interface pattern below 54 | - They can reduce verbosity of parameterized types. Eg: Maps.newHashMap() 55 | 56 | #### Service Interface Pattern 57 | - Here same pattern as above, where the implementation classes are not even known upfront. 58 | - Example: JDBC connection driver classes. DriverManager.registerDriver, and DriverManager.getConnection. 59 | - It needs to provide, registration API and then get service API 60 | - Cannot subclass and take advantage of constructors. Though this enforces Composition instead of inheritance, so its not so bad. 61 | - Cannot easily distinguish between constructing methods, and other methods. Need to use some convention to make it easy. Eg: newInstance, valueOf, of etc. 62 | 63 | #### Builder pattern 64 | 65 | - When too many parameters use builders instead. 66 | - In Builders, each parameter setting can be through a good name method. In constructor its difficult to remember. 67 | - Can easily add optional parameter support. 68 | 69 | #### Singleton with private instance or enum 70 | 71 | - static final variable (also provides init guarantee) 72 | - Lazy loading (double checked) 73 | - Enums (by default lazy, and provides init guarantee) 74 | 75 | #### Private Constructor 76 | 77 | 78 | #### Avoid creating unnecessary objects 79 | - Eg: Sring abc = new String("some value"); instead use String abc = "some value"; 80 | - Choose primitives over boxed, check for unnecessary boxing and unboxing 81 | 82 | #### Clear memory references 83 | - Let objects go out of scope quickly 84 | - If not, nullify reference (eg: Stack.pop, within method, elements[size] = null) 85 | - Check caches and message listeners, they hold references 86 | 87 | #### Avoid finalizers 88 | - JVM does not guarantee they will be called 89 | - If called, they can be called anytime, not immediately after object is eligible for GC 90 | - Never release resource in finalizer, if it does not run, the resource will still be lock (or in inconsistent state) 91 | - Hampers performance 92 | - Instead use explicit close methods like OutputStream, java.sql.Connection etc 93 | - These classes also use finalizers, but that is safety net 94 | 95 | ----------- 96 | 97 | ### Methods common to all objects 98 | 99 | #### equals 100 | - If super class has implemented equals, then its okay to not implement (eg: Set used AbstractSet) 101 | - Reflexive (equal to self), transitive, symmetric, consistent (unless modified) 102 | - Maintain Liskov Substitution Principle, within equals (don't check o.getClass() == this.getClass() instead check with instanceof 103 | - Consistent - Don't use external resources (eg: IP address) 104 | 105 | #### hashcode 106 | - every class which overrides equals must have it 107 | - Consistent across multiple calls 108 | - Dont use any fields, which are not used for equals 109 | - You can exclude redundant fields (ones which are always same for all objects) 110 | - You can cache the hashcode and return that (like String class), but then need to track if value is modified. 111 | 112 | #### toString 113 | 114 | #### clone 115 | - Cloneable interface. Its a mixin interface. Does not have clone method. 116 | - Object class's clone method is protected 117 | - Atypical - Presence of Colenable modifies behavior of Object.clone() behavior. If present it returns object which is field by field copy, and if not present, then .clone method throws CloneNotSupportedException 118 | - Cloning is not done using constructor 119 | - If you override clone do return super.clone(), if all classes do that up the chain, then Object.clone will be called and you will get the right copy 120 | - This is important because spec doesnt enforce anything from Cloneable interface. So someone might override clone and not clone, nor call super.clone, causing problems 121 | - Note: Objects.clone() creates a shallow copy 122 | - If you override and write clone, ofcourse you cannot set final field, thus need to remove final modifiers 123 | - Object's clone method is declared to throw CloneNotSupportedException, but overriding clone methods can omit this declaration. 124 | - Like constructor, clone method should not call non-final methods, because super object might not be properly constructed yet, causing some data corruption 125 | - Clone method must be synchronized in case of concurrency 126 | - In short, you are better off, creating and using a copy-constructor 127 | 128 | #### comparable 129 | - Opposing sign for symmetry x.compareTo(y) == -y.compareTo(x) 130 | - If compareTo returns 0, objects should ideally be equal (but thats not in contract) 131 | - Weird: Inserting new BigDecimal("1.0") and new BigDecimal("1.00") in HashSet stores 2 elements (they use equals), while TreeSet stores only 1 element (they use compareTo) 132 | 133 | ----------- 134 | 135 | ### Classes and Interfaces 136 | 137 | #### Accessibility 138 | - Make fields, classes etc as much inaccessible as possible (private, protected, package, then public) 139 | - Anything that is public is now part of API, thus difficult to make private later 140 | 141 | #### Private fields with accessor methods 142 | - Helps in validating inputs (setters) 143 | - Helps in returning copies in outputs (getters) 144 | 145 | #### Make fields as much immutable as possible 146 | - Immutable objects are simple 147 | - They are thread-safe 148 | - They can be shared freely 149 | - They can expose their internals 150 | - Can take advantage of cached hashCode & lazyInit hashCode 151 | - Only disadvantage is memory use 152 | 153 | #### Composition over inheritance 154 | - Inheritance violates encapsulation, if super class changes sub-class behavior changes even if its not touched 155 | - Super class can later add method, sub-class havent thought of 156 | - In fact, it can add method which mutates the state which sub-class never promised to do. 157 | - If you add your own methods in sub-class, and later super-class adds same name method its a problem. Either it may not compile based on return type, or contract of that method in super might be different than subclass method. 158 | - Instead use composition and forward/delegate the calls 159 | - Such classes are called Wrapper classes (decoration pattern) 160 | - Only problem is library/frameworks do not know of your class type, and can't trigger message callbacks and such. 161 | 162 | #### Override in inheritance 163 | - Constructor must not call method (which is overridden), because super() constructor will call override() of subclass, which is not yet constructed 164 | - Same problems can occur with clone and readObject (so avoid inheritance with Cloneable and Serializable) 165 | 166 | #### Prefer interfaces to abstract classes 167 | - Classes can be retrofitted to have more interfaces 168 | - Interfaces allow mix-in types (markup), without need to implement any methods 169 | - Interfaces allow cross-types (eg: SingerWriter implements Singer, Writer) 170 | - Interfaces are not allowed methods, but Skeleton types can be created. Eg: AbstractSet, AbstractList etc. These classes help create concrete implementations by providing part of functionality 171 | - If class cannot extend Skeletal (Abstract) class, we can implement the Interface, and have Skeletal class instance as composition field, and delegate all interface methods, to skeletal class instance. This is called, simulated multiple inheritance. 172 | - Disadvantage: Once release, interfaces are impossible to change (all implementations need to be updated) 173 | 174 | #### Class hierarchies over tagged classes 175 | - Lot of boilerplate in tagged classes: Enums, fields, switch statements 176 | - Memory issue: Tagged classes can contains fields specific for one type, but object of all types will have those extra fields. 177 | 178 | #### Function objects to represent strategies 179 | - Use classes (stateless) to represent computation. This can be passed around. Ex: StringLengthComparator 180 | 181 | #### Favor static member class over non-static 182 | - Every non-static class object has instance of enclosing class. Takes more memory. 183 | - Non-static class instances cannot be created without creating instances of enclosing class 184 | - Though one valid use of non-static class is, implementing Iterator for the class 185 | - Static classes are typically used to create Helper classes 186 | - Defining them public or private depends on whether you want to expose it in API 187 | 188 | ----------- 189 | 190 | ### Generics 191 | 192 | #### Don't use Raw types 193 | - Using types in all reference variables, helps in safety and avoiding boilerplate of casting 194 | - Use generic fields (public E element) in class 195 | - Use generic methods (public static Set union(Set s1, Set s2)).. helps in type inference 196 | 197 | #### Prefer Lists to arrays 198 | - Arrays are covariant (Object[] a = new Long[]), but it fails at runtime (a[0] = "string value"); 199 | - Arrays retain types at runtime (reified) thus they throw ArrayStoreExceptions. Lists (generics) do type erasure at compile time. 200 | 201 | ----------- 202 | 203 | ### Enums and Annotations 204 | 205 | #### Enums instead of int constants 206 | - Enums provide name space. If you use int constants for 2 different Type hierarchies (AppleTypes & OrangeTypes), you can pass value of one to method of another, accidently, and compiler wont complain 207 | - Enums are iterable. Cannot iterate over int constants 208 | - Enums have default toString. Cannot sysout int constants (they will print numbers which are not helpful) 209 | - You can extend functionality of enums 210 | - Enums can be based on multiple fields 211 | - EnumSet instead of Bit set (way to define union of types eg: STYLE_BOLD | STYLE_ITALIC), instead just use EnumSet.of(STYLE_BOLD, STYLE_ITALIC). 212 | - EnumMap 213 | 214 | #### Prefer annotations over naming patterns 215 | - Eg: @Test instead of all method names starting with test 216 | - Annotations have retention policy. Eg: RetentionPolicy.RUNTIME 217 | - Annotations have target. Eg: @Target(ElementType.METHOD) 218 | 219 | ----------- 220 | 221 | ### Methods 222 | 223 | #### Definition 224 | - Choose method names carefully - they are part of API 225 | - Choose parameter types as interfaces instead of implementations 226 | - Long list of methods with identically typed parameters is wrong 227 | - Dont have too many parameters 228 | - Prefer Enum over boolean 229 | 230 | #### Var args 231 | - If method needs to take 1 or more, then have 1st param, then 2nd as var..args 232 | - Arrays.asList() was a mistake, because you can pass multiple values to it, but if you pass array to it, then it considers that as var..args with single element of type array. 233 | - Instead it should have had Arrays.gather(T... args) and then return Arrays.asList(args) 234 | 235 | #### Return empty collections instead of null 236 | - These return values are iterable 237 | 238 | ----------- 239 | 240 | ### General 241 | 242 | - Avoid float and double for exact answers use BigDecimal 243 | - Avoid boxed, (== does not work), and constant boxing-unboxing consumes CPU 244 | - Use StringBuilder instead of direct concatenation 245 | - Refer to objects by their interfaces 246 | - Use checked exceptions for recoverable conditions, and runtime exceptions for programming errors 247 | - Favor standard exception like IllegalStateException, IllegalArgumentException etc 248 | - Prefer Executors and Tasks to threads 249 | - Prefer concurrency classes instead of wait notify 250 | 251 | #### Use Serializable Judiciously 252 | - Like APIs once serialized, then cant change class structure 253 | - Increases testing burden (backwards compatible) 254 | - Increases security loopholes, because it does not use default constructor 255 | - Inheritance based classes should avoid serializable -------------------------------------------------------------------------------- /topics/design/solid.md: -------------------------------------------------------------------------------- 1 | ## SOLID principles 2 | 3 | - S = Single Responsibility - Each class/instance should have only 1 responsibility 4 | - O = Open Closed - Objects should be open for extension closed for modification 5 | - L = Liskov substitution - Instance objects can be replaced with subtypes without altering correctness 6 | - I = Interface Segregation - Multiple specific interfaces are better than big general one 7 | - D = Dependency Injection - High level and Low level modules should both depend on abstraction 8 | 9 | ## Other design principles 10 | 11 | - Code to interface not implementation 12 | - Favor composition over inheritance 13 | - Encapsulate what changes 14 | - Strive for loose coupling between objects 15 | - Principle of least knowledge = Talk only to immediate friends 16 | -------------------------------------------------------------------------------- /topics/design/testing.md: -------------------------------------------------------------------------------- 1 | ## Testing 2 | 3 | Mockito 4 | Mock 5 | Verify 6 | times 7 | capture 8 | Spy 9 | -------------------------------------------------------------------------------- /topics/opinion/myanswers.md: -------------------------------------------------------------------------------- 1 | ## Importance of Compile Time vs JIT 2 | 3 | - In compile - code is converted directly to architecture (machine language). Example: Go 4 | - In JIT - code is converted at runtime, just before 5 | - Advantage: it can check availability of resources (RAM, CPU etc) and decide on corresponding optimizations 6 | - Advantage: it can keep running for a while a find hot snippets of code, and optimize them even further. Eg: Android 7 7 | - Disadvantage: introduces latency during startup (for conversion) 8 | - Disadvantage: have to perform conversion every time during application start (cannot save and re-use the best optimization results) 9 | 10 | ## What do you like about Java 11 | 12 | - Performance (Eg: Memory allocation). Thanks to years of iterative work on the JVM it is very performant. JIT Compilation. 13 | - Garbage Collection. Algorithms keep improving. 14 | - Ecosystem (Vast number of mature, stable libraries, frameworks, IDEs, Tools available) 15 | - Applicable to multiple use cases - Low Latency Trading apps, Web server, Batch Backend, etc. 16 | 17 | 18 | ## What do you not like about Java 19 | 20 | - Verbosity - It is very difficult to write succinct code in Java. Too much boilerplate. Slightly subsidised by lambdas. 21 | - Threads could be less expensive akin to Go channels or Kotlin co-routines. 22 | - Message passing and Immutability are not baked-in. 23 | - Thread communication by sharing memory is brittle (that is why so many locks are introduced), difficult to developers at all skill levels to write correct code. 24 | - I wish primitives could be directly added to collections and used as list 25 | - Null-checks (no ?. operator). Lot of boilerplate code and time wasted in checking for nulls. Especially in finance industry where POJOs have deeply nested structure. Doing a.getB().getC().getD() cannot be written. Every object needs to be null checked. 26 | - No tuples (especially helpful in multiple return types which currently have to be put in HashMap) 27 | - In fact, just check the kotlin language list 28 | - All pojos have to write getter, setter, equals, hash, clone/copy… kotlin fixes this 29 | - No built-in lightweight UI framework - They failed with JavaFX, Applets, etc. 30 | 31 | -------------------------------------------------------------------------------- /topics/related/sql.md: -------------------------------------------------------------------------------- 1 | ## SQL 2 | 3 | ### Resources 4 | 5 | - [Cheat sheet](http://files.zeroturnaround.com/pdf/zt_sql_cheat_sheet.pdf) 6 | - [Clustered vs Non-clustered indexes](https://docs.microsoft.com/en-us/sql/relational-databases/indexes/clustered-and-nonclustered-indexes-described) 7 | - [DB Index Wiki](https://en.wikipedia.org/wiki/Database_index) 8 | 9 | ### Joins 10 | 11 | - [Pictorial Reference](https://commons.wikimedia.org/wiki/File:SQL_Joins.svg) 12 | - **Inner join**: Rows common in both T1 and T2 13 | - **Left outer join**: All rows in T1 14 | - **Right outer join**: All rows in T2 15 | - **Full join**: All rows in T1 and T2 16 | - **Cross join**: All rows in T1 * all rows in T2 17 | 18 | ### Keys 19 | 20 | - **Primary key**: Uniquely identify the row. Cannot be null. 21 | - **Candidate key**: Can be chosen as primary key 22 | - **Composite key**: Combination of multiple columns 23 | - **Foreign key**: Column referencing other table's primary key 24 | 25 | ### Indexes 26 | 27 | - Improves speed of data retrieval. 28 | - Primary and foreign keys are indexed by default. 29 | - **Non-clustered index**: Rows are unordered (stored in heap). While index is stored separately as sorted column. 30 | - **Clustered index**: The rows themselves are ordered (thus there can be only 1 clustered index per table). 31 | - **Composite index**: Index on multiple columns (c1,c2,c3). Order of columns should match the where clauses for maximum efficiency. 32 | - **Cardinality**: Uniqueness of rows (eg: PassportID vs Gender column values). 33 | - **Bitmap-index**: Used when cardinality is very low (eg: Gender column). 34 | - **Data structures used**: Bit arrays, hashmaps or B+Trees (most common). 35 | 36 | ### Queries 37 | 38 | - **Union**: Merges content of 2 structurally compatible tables 39 | - **Group By**: Used to aggregate (avg, sum, count) values. Aggregate column should be same as group-by column. 40 | - **Having**: Adding where clauses on top of group-by. 41 | 42 | ### Frequently asked queries 43 | 44 | - Find all departments with sales more than 1000 45 | 46 | ```sql 47 | SELECT department, SUM(sales) AS "Total sales" 48 | FROM order_details 49 | GROUP BY department 50 | HAVING SUM(sales) > 1000; 51 | ``` 52 | 53 | - Print all employee ids with their manager ids 54 | 55 | ```sql 56 | SELECT e1.emp_id, e1.emp_mgr_id 57 | FROM employee e1 LEFT JOIN employee e2 58 | ON e1.emp_mgr_id = e2.emp_id 59 | ``` 60 | 61 | - Print all manager names with count of directs 62 | 63 | ```sql 64 | SELECT e2.ename, count(e1.ename) 65 | FROM employee_s e1 LEFT OUTER JOIN employee_s e2 66 | ON e1.manager_id = e2.eid 67 | group by e2.ename; 68 | ``` 69 | 70 | 71 | - Print 10th highest salary 72 | 73 | ```sql 74 | SELECT Salary FROM 75 | ( SELECT DISTINCT Salary FROM Employee ORDER BY Salary DESC LIMIT 10 ) 76 | AS Emp ORDER BY Salary LIMIT 1; 77 | ``` 78 | -------------------------------------------------------------------------------- /topics/related/unix.md: -------------------------------------------------------------------------------- 1 | ## UNIX 2 | 3 | ### Resources 4 | 5 | - [Art of Command Line](https://github.com/jlevy/the-art-of-command-line#processing-files-and-data) 6 | 7 | ### Table of Contents 8 | 9 | * [Resources](#resources) 10 | * [Find](#find) 11 | * [Search](#search) 12 | * [Processes](#processes) 13 | * [File permissions](#file-permissions) 14 | * [List files](#list-files) 15 | * [Symlinks](#symlinks) 16 | * [Checking logs](#checking-logs) 17 | * [Text manipulation](#text-manipulation) 18 | * [Sed](#sed) 19 | * [Networking](#networking) 20 | * [Space](#space) 21 | * [Miscellaneous](#miscellaneous) 22 | 23 | 24 | ### Find 25 | 26 | - `find dir -type f` Find all files in the directory 27 | - `find dir -type d` File all directories within this directory 28 | - `find dir -name “a*.mp3” -print0` Find all files/directory with name like a***.mp3 29 | - `find dir -type f -name “a*.txt”` Find all files (recursively) with name like a***.txt 30 | - `find dir -type f -print0 | xargs -0 grep -l "word"` List file names with matching word 31 | - `find dir -type f -print0 | xargs -0 mv -t` Move all files from dir tree into single directory 32 | 33 | ### Search 34 | 35 | - `grep “word” file` All matching lines in the file 36 | - `grep -i “word” file` All matching lines - Ignore case 37 | - `grep -r “word” dir` All matching lines in (recursively) all files or directory 38 | - `grep -c “word” file` Count of matching lines 39 | - `grep “word” file | wc -l` Count of matching lines 40 | - `grep -v “word” file | wc -l` Count of non-matching lines 41 | - `grep -o -w “word” file | wc -w` Word count 42 | - `grep -l -r “word” dir` List file names with matching word 43 | - `find dir -type f -print0 | xargs -0 grep -l "word"` List file names with matching word 44 | 45 | ### Processes 46 | 47 | - `nohup program.sh > mylog.txt 2>&1 &` 48 | + `&` starts process as child process in the background 49 | + `nohup` Ctrl-C or terminating session sends kill signal to all child processes, `nohup` catches and ignores it 50 | + `>` redirect output (from left/source to right/target) 51 | + `2` error stream 52 | + `1` output stream 53 | + `2>&1` append all errors to output 54 | - `top` Check CPU and memory consumption 55 | - `kill -9 processId` kill the process with that pid 56 | - `kill -3 processId` for a JVM process, will write thread dump to output stream 57 | - `ps -ef | grep word` find process with matching word 58 | - `echo $?` print output of last process 59 | 60 | ### File permissions 61 | 62 | - `chmod file` Change 63 | - `chmod +x file` Add execute permission 64 | - `chmod +w file` Add write permission 65 | - `chmod +r file` Add read permission 66 | - `chmod 755 file` Change permission 67 | - `chmod -R 755 dir` Change permission recursively 68 | - `chmod g+w file` Add write permission at group level 69 | - Numbers: 1=x, 2=w, 3=w+x, 4=r, 5=r+x, 6=r+w, 7=r+w+x 70 | - References: u=user, g=group, o=others, a=all 71 | 72 | ### List files 73 | 74 | - `ls` list files in this directory 75 | - `ls -ltr` list files in this directory with more details and in reverse chronological order 76 | - `ls -ltra` same as above + list hidden files (names starting with `.`) 77 | - `ls -ltr | grep "^l"` Lists all symlinks (`ls -ltr` lists symlinks with `l` as first character of output) 78 | 79 | ### Symlinks 80 | 81 | - Symbolic or soft links. Pointer to a file. 82 | - `ln -s /java/jdk7 jdk` create symlink jdk which points to `/java/jdk7` 83 | - `ln -ns /java/jdk8 jdk` update symlink jdk to point to `/java/jdk8` 84 | 85 | 86 | ### Checking logs 87 | 88 | - `tail -f logfile` output appended data as file grows (f=follow) 89 | - `less +F logfile` open file, and output appended data as file grows 90 | 91 | ### Text manipulation 92 | 93 | - `head file` display first 10 lines 94 | - `head -20 file` display first 20 lines 95 | - `tail file` display last 10 lines 96 | - `tail -5 file` display last 5 lines 97 | - `head -20 file | tail -1` display 20th line 98 | - `cut -f3 file` display 3rd field for each line, tab as separator 99 | - `cut -d',' -f3 file` display 3rd field for each line, `,` as separator 100 | - `cut -c3-6 file` display characters from 3rd to 6th position for each line 101 | - `cut -c7- file` display characters from 7th to end of each line 102 | 103 | ### Sed 104 | 105 | - `sed s/unix/linux file` replace first occurrence of "unix with "linux" 106 | - `sed s/unix/linux/3 file` replace 3rd occurrence 107 | - `sed s/unix/linux/g file` replace all occurrences 108 | - `sed s/unix/linux/3g file` replace all occurrences starting from 3rd one 109 | - `sed -i '1 d' file` delete header of file 110 | - `sed -i '$ d' file` delete footer of file 111 | - `sed –n '10 p' file` print 10th line of the file 112 | 113 | ### Networking 114 | 115 | - `ping hostname` or `telnet hostname port` check if remote host is alive 116 | - `scp /dir/file user@hostname:/targetdir/file` copy file to different host 117 | - `netstat -a | grep "port"` check host connected to machine's port 118 | 119 | ### Space 120 | 121 | - `df -h` space in current drive (`-h` is human readable format) 122 | - `du -h .` sizes of all files in current directory 123 | - `du -sh .` sizes of current directory 124 | - `du /bin/* | sort -n` sort all files based on size (asc) 125 | 126 | 127 | ### Miscellaneous 128 | 129 | - `lsof file` list processes using the file 130 | - `rev file` reverses the text in each line 131 | - `echo "string" | rev ` reverses the string 132 | - `sort file` sorts file lines alphabetically 133 | - `sort -n file` sorts file lines numerically 134 | - `uniq file` filter out adjacent duplicate lines and print 135 | - `uniq -c file` print with count at the begining of each line of output 136 | - `uniq -d file` print only duplicates -------------------------------------------------------------------------------- /topics/related/web.md: -------------------------------------------------------------------------------- 1 | ## Web 2 | 3 | ### Resources 4 | 5 | - [IP Address Basics](http://www.deepakvadgama.com/blog/ipaddress-basics-for-developers/) 6 | - [HTTP Overview](https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview) 7 | - [HTTP Statuses](https://httpstatuses.com) 8 | - [HTTP Caching](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching) 9 | 10 | ### TCP 11 | 12 | - Transmission Control Protocol 13 | - Based on connections (involves 3-way handshake) 14 | - Guaranteed delivery of packets 15 | - Flow/Congestion control 16 | - 'TCP Fast Open' improves connection times 17 | - Good for sites, applications etc. 18 | 19 | ### UDP 20 | 21 | - User Datagram Protocol 22 | - Delivery not guaranteed 23 | - Stateless, not connection based 24 | - Doesn't support ordering (to be handled by application) 25 | - Good for games, videos etc. 26 | 27 | ### HTTP Verbs 28 | 29 | - HEAD, OPTIONS, GET, POST, PUT, DELETE 30 | 31 | ### HTTP Caching 32 | 33 | - **ETag**: Fingerprint of the resource (eg: MD5 checksum), to indicate if resource is changed. 34 | - **no-cache**: Cache but use only after re-validating if resource is updated. 35 | - **no-store**: Do not cache, and re-download for each request. 36 | - **max-age**: Amount in seconds the resource can be cached. 37 | - **must-revalidate, max-age:30**: Re-use cache for 30 seconds, after that must revalidate. (This can avoid download if resource has not been changed even after 30 seconds) 38 | - **Ideal**: Have html pages as no-cache, and rename all other resources with unique file name (like md5 checksum of the file). 39 | 40 | ### [HTTP Statuses](https://httpstatuses.com) 41 | 42 | - 200: Ok 43 | - 400: Bad request 44 | - 401: Not authenticated 45 | - 403: Not authorized 46 | - 404: Not found 47 | - 500: Internal server error 48 | 49 | ### [HTTP Statuses in a nutshell](https://twitter.com/stevelosh/status/372740571749572610?lang=en) 50 | - 20x: Success 51 | - 30x: Redirection 52 | - 40x: Client Error 53 | - 50x: Server Error 54 | 55 | ### HTTP 2 56 | 57 | - Why?: Top sites average 100 requests per page. Browsers allow max 6 connections. Min 35ms round trip per request. 80 byte header. 58 | - No head of line blocking. 59 | - Binary 60 | - Header compression. Does not send repeated headers. 61 | - Priority based 62 | - Prefetch 63 | - Server Push 64 | 65 | ### HTTPS (TLS) 66 | 67 | - Transport Layer Security 68 | - Server port 443 69 | - Certificate: Public-Private key. Signed by Certificate Authority (Verisign, Symantec, Thawte etc). These well known CAs are shipped and managed by the browser. 70 | - Additional handshake on top of TCP 71 | 72 | 73 | ### Security 74 | - **Origin**: protocol + host + port 75 | - **Same Origin Policy**: JavaScript can only access same origin. Can’t access other iframes. If you request JS from other origin the response cannot be read. 76 | - **CORS (Cross Origin Resource Sharing)**: Allow to get JS/CSS from other origins. Important for API providers. 77 | - **CSRF (Cross Site Request Forgery)**: Request originates from cross-site (potentially malicious) site. Can be avoided by Synchronized Token Pattern: Store token in cookie (can be read only by origin site) and pass that token along with every request as HTTP Param or Header (X-CSRF-TOKEN). 78 | - **XSS (Cross Site Scripting)**: Malicious scripts are injected into the HTML/JS resources. Can be avoided by escaping injected strings etc. 79 | 80 | 81 | 82 | --------------------------------------------------------------------------------