Mind Map of Backend

Backend tends to have a totally different topics than Web (frontend). What’s more, before putting too many items into “Mind Map of Web”, creating a new mind-map slot for backend is quite reasonable. Additionally, classical topics about algorithm are also appropriate here for the reason of an obvious different focus from frontend. So all these facts bring about a new mind map for backend.

Map

Keywords Comment & Reference
distributed system Nginx (read as “engine X”) Concepts of Distributed System
dynamic programming Comment, introduction by comic
compile compile introduction
bitwise operation is-power-of-2, find-odd-number
greatest common divider introduction by comic
max difference within array introduction by comic
circular linked list detect Given node length known introduction by comic
js dependency Comment a js project template
git merge rebase fixup autosquash feature branch see my post “Feature Branch Workflow”, cheat-sheet
slf4j logback MDC kafka Comment
CAP Eventual Consistency nosql kafka RabbitMQ MongoDB HBase Cassandra Redis Neo4j Comment
https Introduction
git mergetool kdiff3 Comment
flashcard with Anki and Studies Anki Studies
IDE vim, intellij Comment, java8-compile-idea
java nio Comment
java concurrency Comment
linux command commands
disk clean (for Mac) link
e-book site (for IT) finelybook (down since 2017.9, not sure the future), salttiger, archive.org
math support for markdown codecogs.com
unicode [unicode][#unicode]

unicode

For UTF-16, each code point is encoded in two bytes so that a special char U+FEFF (invisible) at the beginning of text can help to decide whether it is little-enndian. UTF-8 doesn’t need this but could have that special char for whatever reason.

ide tips

Question Answer
01.How to format XML in vim gg=G
02.How to import Java8 maven projects into Intellij project structure->module->source, and change compiler level (see reference 23)

java concurrency

Question Answer
Singleton in double-checked locking 1) synchronized on getInstance is unnecessary for the case of initialized instance and therefore inefficient; 2) a nest synchronized block of the first null check on the singleton class, containing the second null check; 3) add volatile modifier to instance property to prevent other threads from seeing half-initialized instance (also see happen-before guarantee).
happen-before guarantee Without it, CPU won’t guarantee changed variable is written to memory (so that other threads can see it) in the order of statement in source code. Thread.start and join have this guarantee so that statements happen before are ensured to be available in main memory.
Singleton in Enum thread-safety guarantee by JVM and working in case of serialization
CAS Compare-And-Swap, the fundamental of non-blocking algorithm. Compare the value with the expected one and give up setting to the new value if the compare fails. CPU provides instruction for CAS, resulting better performance over synchronized lock in most cases. Also see Java’s atomic types, which are used by many concurrent classes.
aThread.join The current thread blocks until ‘aThread’ terminates.
Reentrant Synchronization A thread can acquire a lock that it already owns.
Java Memory Model 1) Each thread has its own stack, containing local primitives and object references, while object instances are kept in shared heap. 2) On the other hand, each CPU has its own registers and cache, which keep changed value and sync with the main memory from time to time. 3) Therefore without volatile and synchronized lock, the changed value made by one CPU may be invisible to other CPU.
BlockingQueue & BlockingDeque It provides operations in 4 ways: throw runtime exceptions; return special value; blocking; return after timeout.
ConcurrentMap It has multiple table buckets, write operation locks only one bucket and read operation doesn’t block.
When volatile is enough In case only one thread updates the value while other threads are reading the value.
ExecutorService Executors as a factory can generate multiple ExecutorService like normal thread pool, scheduled thread pool and ForkJoinPool. It can accept(submit) Runnable or Callable tasks and manage lifecycle of these tasks via shutDown and awaitTermination.
ForkJoinPool(FJP) Threads in the pool try to execute submitted tasks. execute is fire-and-forget style; invoke is blocking; submit returns ForkJoinTask.
ForkJoinTask A lightweight form of Future for tasks running within FJP. fork starts execution and join wait for the result. The efficiency comes from the use of pure function and isolated objects as the computation.
CopyOnWrite(COW) Copy internal data on mutate operation, and no lock on read-only operation. Suitable for the case that mutate operation happens much less than read. What’s more, it’s better to support batch mode for mutate operation.
CompletableFuture Promise in Java available from Java 8.
Lock vs synchronized bloc lock acquire and release should be put in try-final block, while synchronization has no such an issue.

java nio

Question Answer
Types of Channel File, TCP and UDP; normal(blocking) and asynchronous
Transfer between channels FileChannel.transferFrom and transerTo are more efficient than read&write since it can rely on file system cache without copy operation.
Transfer between threads with Pipe Thread A writes data to Pipe.SinkChannel, which then sends the data to Pipe.SourceChannel which can be read by Thread B.
Channel and Buffer For inbound, data reads from Channel and is put in Buffer; for outbound, Channel gets data from Buffer.
Channel and Selector For non-blocking channels, multiple channels can register with a selector for events like connect, accept, read and write. Selector.select(it’s blocking) returns the number of channels that have events. Selector.selectedKeys is used to iterate these events.
Capacity, limit and position of Buffer Invariant: 0 <= mark <= position <= limit <= capacity
Buffer clear position <- 0; limit <- capacity. (ready for put operations)
Buffer flip limit <- position; position <- 0. (ready for get operations)
Buffer rewind position <- 0. (for re-reading)
Buffer mark and reset mark keeps a position so that later reset can restore to this position.
Java io vs nio Stream doesn’t provide a built-in buffer, and is blocking but can simplify data processing, while Channel and Buffer need more control over buffered data. Another difference is the possibility of non-blocking operation in nio. Two ways to invoke asynchronous operation: one is Future(though Future.get is blocking), the other is via callback.

git mergetool kdiff3

kdiff3 is a cross-platform 3-way merge tool. To configure it with git, run:

1
2
3
4
5
6
7
$ git config --global merge.tool kdiff3
$ git config --global mergetool.kdiff3.path <path-to-kdiff3>
// it will generate the following contents in ~/.gitconfig
[merge]
tool = kdiff3
[mergetool "kdiff3"]
path = /Applications/kdiff3.app/Contents/MacOS/kdiff3

cap nosql

In the absence of network failure, both consistency and availability can be satisfied. On the other hand, in the presence of network partition, distributed system has to choose between consistency and availability.

Note that CAP is not saying of choosing two of three. No trade-off when no network issues, though for large scale distributed systems network partition can’t be avoided.

No matter which to choose, reconciliation should be made via Eventual Consistency, which serves the fundamental of many NoSQL databases.

HBase: distributed hashmap
MongoDB: distributed json
Redis: distributed hashmap in memory

log

Simple log facade for Java(slf4j) defines logger interface for log libraries like java logging, log4j and logback. Check its manual for details. Note to introduce dependency in maven, don’t directly use slf4j API (but use their adapted packages with log implementation).

Logback is the next generation of log4j. Use log.debug("foo {}", bar); to avoid concat string if logger level is higher than DEBUG. Also check Mapped Diagnostic Context MDC for the support of multi-thread, remote client request (e.g. servlet filter) and microservice.

Another article about log-central system from the author of kafka

js dependency

Check current dependency with npm ls --depth=0

Before introducing a new dependency, check the maturity with npm view <package-name>

List outdated dependencies with npm outdated

Analyse dependency usage with depcheck

Run test on npm package with Snyk

dynamic programming

Regarding gold mine puzzle, the key is the generate function of F(n, w) = max(F(n-1, w), F(n-1, w-p[n-1]) + g[n-1]).
See implementation at my git