Algorithms

Arrays - indexed
Linked List - contains data and pointer to next elem, uses iterators
Stacks - LIFO, can be implemented at array or LL

Hashes:
- hash table is used to impl and associative (k:v) array
- uses a hash function to create buckets
- distribute the entries (key/value pairs) across an array of buckets
- given a key, the algorithm computes an index that suggests where the entry can be found
- collision (two keys resolving to the same bucket) is a constant potential problem

Priority Queues:
- like a queue (FIFO) but with priority
- usually implemented as a heap
- a heap is a binary tree with nodes ordered such that the children are all less (min heap) or greater than (max heap) parent

Big-O notation: (O is for order)
  O(1) - constant
  O(log(n) - logarithmic (better than linear)
  O(n) - linear
  O(n^2) - quadratic
  O(n^c) - polynomial
  O(c^n) - exponential

Sorting:
  Merge Sort - bottom up, compare pairs then larger groups; O(n log n)
  Quicksort - top down, find avg, lo and hi, then recurse into subgroups; O(n^2)
  Bubble Sort - sideways, compare pairs, iterate, repeat: O(n^2)
  Selection Sort - find smallest, swap into position 1, iterate, O(N^2)
  Insertion Sort - move elems one by one to a new list, sorting as you go; O(N^2)
  Tree Sort - build a BST from the list then serialize it back; O(n log n)
  Heapsort - like an imporved slection sort, uses a heap, good for large data set on disk and a small amount of ram to work with
  BST - binary search tree - is a tree with nodes ordered so that left child is less and right child greater than the parent, as well as globally

Graphs:
- breadth-first search (iterative) and depth-first search (recursive)
- 3 ways to represent a graph in memory: objects & pointers, matrix, and adjacency list

Operating Systems

Processes vs Threads:
- a thread is a path of execution within a process. Also, a process can contain multiple threads
- a process, in the simplest terms, is an executing program. One or more threads run in the context of the process. A thread is the basic unit to which the operating system allocates processor time. A thread can execute any part of the process code, including parts currently being executed by another thread

Concurrency Issues - Atomicity, Visibility, Reordering, Race Conditions, Livelock, Starvation, Deadlock

Mutex vs Semaphore:
- mutex and semaphore are kernel resources that provide synchronization services monitors
- a mutex provides mutual exclusion, either producer or consumer can have the key
- a semaphore is a generalized mutex, across multiple buffers
- mutex is binary (0|1), semaphore can in incremented/decremented
- use a mutex to protect an increment operation, it's lower-level

Deadlock vs Livelock:
- a lock occurs when multiple processes try to access the same resource at the same time; one process loses out and must wait for the other to finish
- a deadlock occurs when the waiting process is still holding on to another resource that the first needs before it can finish
- the canonical technique for deadlock avoidance is to have a lock hierarchy
- a livelock is similar to a deadlock, except that the states of the processes involved in the livelock constantly change with regard to one another, none progressing
- in Java, synchronized keyword keeps a var in synch across threads

System Architecture

Command and Query Responsibility Segregation (CQRS):
- a pattern that segregates the operations that read data (Queries) from the operations that update data (Commands) by using separate interfaces
- this implies that the data models used for querying and updates are different

REST vs SOAP:
- REST is an architectural style, while SOAP is a protocol
- REST (Representational State Transfer) is for exposing a public API over the internet to handle CRUD operations on data. REST is focused on accessing named resources through a single consistent interface
- SOAP (Simple Object Access Protocol) brings it's own protocol and focuses on exposing pieces of application logic (not data) as services. SOAP exposes operations. SOAP is focused on accessing named operations, each implement some business logic through different interfaces

How are cookies passed in the HTTP protocol?
- as HTTP headers, both in the request (client -> server) and the response (server -> client)

How does congestion control work in the TCP protocol?
- TCP uses a round-trip delay estimate for its adaptive windowing scheme to transmit data reliably over an unreliable network with time varying bandwidth

Java

In Java, what is the difference between final, finally, and finalize?
- final var/method/class cannot be modified/overridden/inherited
- finally is for try/catch cleanup
- finalize if for pre-GC cleanup

In Java, what is the difference between static, final, and const?
- static is a class var/method
- final see above
- const is not used, it's C++

java Overloading vs Overriding:
- overloading is having multiple constructors w/ diff sigs
- overriding is making a new version of a method in a subclass

Hashtable vs Hashmap in Java:
- Hashtable is synchronized, whereas HashMap is not
- this makes HashMap better for non-threaded applications
- Hashtable does not allow null keys or values
- HashMap allows one null key and any number of null values
- One of HashMap's subclasses is LinkedHashMap, so in the event that you'd want predictable iteration order (which is insertion order by default), you could easily swap out the HashMap for a LinkedHashMap

Scala

Scala - functional programming language, compiles to JVM, loves cons

Some Weird Scala Operators:
  =>  used in function literals to separate the argument list from the function body, e.g. in case statement separates the condition from the result
  ->   returns a two-element tuple containing the key and value
  <-   used in for comprehensions in generator expressions, e.g. for (item <- items)
  _     empty or wildcard placeholder

Higher Order Functions - functions that take other functions as parameters

Currying:
- a curried function is applied to multiple argument lists, instead of just one
- currying is the technique of transforming a function that takes more than one parameter into a function that takes multiple parameter lists
- the primary use for currying is to specialize functions for particular types of data

Closure - a function that has a variable supplied from outside

Tail Recursion (tail call optimization):
- if the recursive call is the last action in the function body, compiler is able to replace the call with a jump back to the beginning of the function, after updating param values
- because of the JVM instruction set, tail call optimization cannot be applied for two mutually recursive functions nor if the final call goes to a function value (function wraps the recursive call)

Scala Case Class
- regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching
- syntactically, case classes are standard classes with a special modifier: Case

- Case signals the compiler to define certain boiler-plate:
  - constructor parameters become public "fields" (via associated accessor/mutator methods)
  - methods toString(), equals() and hashCode() are defined based on the constructor fields
  - a companion object containing an apply() constructor based on the class constructor
  - an extractor based on constructor fields

- can be seen as plain and immutable data-holding objects that should exclusively depend on their constructor arguments; this functional concept allows us to:
  - use a compact initialisation syntax (Node(1, Leaf(2), None)))
  - decompose them using pattern matching
  - have equality comparisons implicitly defined

- good for pattern matching
- saves writing boilerplate code
- used in combination with inheritance to mimic algebraic datatypes
- if an object performs stateful computations on the inside or exhibits other kinds of complex behaviour, it should be an ordinary class

Scala Null, null, Nil, Nothing and None
- Null – is a Trait
- null – is an instance of Null, similar to Java null
  - never use null. Option replaces most usages of null
- Nil – represents an empty List of anything of zero length
- Nothing - is a Trait, a subtype of everything but not superclass of anything; there are no instances of Nothing
- None – used to represent a sensible return value, just to avoid null pointer exception
  - Option has exactly 2 subclasses: Some and None; none signifies no result from the method
- Unit – Type of method that doesn't return a value of anys sort

- never use null
- if you're using a Java library that returns null, convert the result to a Scala Option
- never call get() on an Option; always access Options using map or flatMap, the for comprehension, or pattern matching
- if you need to create uninitialized fields in a Scala class, use one of these approaches:
  - Assign a default to the field that isn't null, such as an empty list, array, or vector
  - If the field can be accessed before its initialized, declare it as an Option, with a default value of None
- in writing methods, never return null; return Option[T] instead

Scala Implicits (implicit classes, methods and params)
- an implicit class is a class marked with the implicit keyword
- this keyword makes the class' primary constructor available for implicit conversions when the class is in scope
  - They must be defined inside of another trait/class/object
  - They may only take one non-implicit argument in their constructor
- a method with implicit parameters can be applied to arguments just like a normal method
- in this case the implicit label has no effec
- however if such a method misses arguments for its implicit parameters, such arguments will be automatically provided

Web Development

AngularJS - web application framework, MVC, 2-way data binding, directives, controllers, actions, services, resources, etc.

Bootstrap - mobile-first front-end framework: UI widgets, layouts, themes in Less/CSS

Json - JavaScript Object Notation, structured data, serialization

jQuery - DOM manipulation library
- simplified syntax for finding, selecting, and manipulating DOM elements
- provides a paradigm for event handling
- Encourages separation of JavaScript and HTML
- Brevity and clarity
- Eliminates cross-browser incompatibilities
- Json support
- extensible via plugins

node.js - compiled server-side javascript

GIT - code repository, branch/merge
Vagrant - deployable work/server environment, built on top of Virtual Box
Less - dynamic style sheets compile into CSS
Bower - package management, dependency, discovery
Gulp - automated build system for JS, minify, unit testing, linting, deploy
Grunt - automation, minify, compilation, unit testing, linting
Lint - validation
Karma - automated testing, spawns server, executes source code vs test code for connected browsers, generates coverage reports
Protractor - test framework for AngularJS applications, runs tests in browser

MySQL, MongoDB, Solr - DB basics: tables, rows, columns, primary keys, normalize

Javascript

JS Classes:
- JavaScript is a prototype-based language
- does have the class/instance distinction: it simply has objects
- a prototype object is used as a template to get the initial properties for a new object
- any object can specify its own properties, either when you create it or at run time
- any object can be associated as the prototype for another object, allowing the second object to share the first object's properties

Instantiation:
- JS does not have a class definition separate from the constructor
- define a constructor function to create objects with an initial set of properties and values
- any JS function can be used as a constructor
- use the New operator with a constructor function to create a new object

Subclassing and Inheritance:
- JS implements inheritance by allowing you to associate a prototypical object with any constructor function
- define the BaseClass constructor function, specifying properties
- define the SubClass constructor function, calling the BaseClass constructor and specifying add'l properties
- assign a new object derived from BaseClass.prototype as the prototype for the SubClass constructor function
- when you create a new SubClass it inherits properties from the BaseClass object

Example:
        function Employee() {
          this.name = "";
          this.dept = "general";
        }
        
        function Manager() {
          Employee.call(this);
          this.reports = [];
        }
        Manager.prototype = Object.create(Employee.prototype);
        
        function Worker() {
          Employee.call(this);
          this.projects = [];
        }
        Worker.prototype = Object.create(Employee.prototype);
        
        function Engineer() {
           Worker.call(this);
           this.dept = "engineering";
           this.machine = "";
        }
        Engineer.prototype = Object.create(Worker.prototype);
        
Variables and Scope:
- if you assign a value to a variable that has not been declared, it will automatically become a GLOBAL variable
- JS has function-level scope
- this is radically different from the C family: blocks, such as if statements, do not create a new scope, only functions create a new scope

Hoisting:
- vars can be used before they're declared
- not considered best practice
- seriously, why would someone even do this?

Closure: (in JS)
- a closure is an inner function that has access to the outer (enclosing) function's variables, or scope chain
- the closure has access to three scope chains: its own variables (defined between its curly brackets), the outer function's variables, and to global variables
- you create a closure by adding a function inside another function
- closures store references to the outer function's vars; not the actual value
- you can call the inner function after the outer function returns
- you can use a closure anywhere that you might normally use an object with only a single method
- closures are used extensively in Node.js; they are workhorses in Node.js' asynchronous, non-blocking architecture
- closures are also frequently used in jQuery

Apply, Call, and Bind:
- Call - invokes the function and allows you to pass in arguments one by one
- Apply - invokes the function and allows you to pass in arguments as an array
- Bind - returns a new function, allowing you to pass in a This array and any number of arguments
- Apply and Call are used for borrowing methods and for setting the This value explicitly
- Apply and Call are almost identical except that you pass the params to Apply as an array, while with Call you list them individually
- Bind is used to call a function with the This value set explicitly
- allows us to set which specific object will be bound to This when a function is invoked
- Bind allows us to borrow methods
- Bind allows us to curry a function (partial function with some args defined)

Dependency Injection:
- is a method to achieve inversion of control
- basically passing in a function as an arg to another function
- your dependencies are given to your object instead of your object creating or explicitly referencing them
- can provide a different dependency based on the context of the situation
- enables us to write more maintainable code by decoupling our objects from their implementations
- facilitates better testing by allowing us to mock dependencies in testing environments so that we only test one thing at a time
- for example, your tests might pass a fake version of your services API that doesn't make requests but returns static objects instead, while in production it provides the actual services API

undefined vs null:
- null is a special value meaning "no value"
  - typeof null is Object
  - assign a var a value of null to indicate it has no value
- undefined means that the variable has not been declared, or not initialized
  - typeof undefined is undefined

json compare - use deep recursion and === to compare elements
- lots of 3rd party diff tools out there
- or roll your own: recurse thru one json object and compare its structure to the other
- compare values using ===

event_stopPropagation vs event_stopImmediatePropagation
- both part of jquery
- stopPropagation will prevent any parent handlers from being executed
- stopImmediatePropagation will also prevent other handlers from executing

window.onload vs document.ready - 4 differences
- document.ready
  - fired first, earliest opportunity to manipulate the DOM. put event handlers here
  - Can be used multiple times
  - part of jQuery
  - doesn't wait for images, styles etc.)
  - in modern browsers it's replaced by the native event DOMContentLoaded)
- window.onload
  - built-in Javascript function
  - waits for images, styles, banner ads and everything
  - there can be only one

useStrict:
- no undeclared vars, no changing type, etc.
- helps avoid syntax an other errors by giving actual errors

AngularJS

Directives - markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or to transform the DOM element and its children
- built-in, e.g. ngApp, ngBind, ngModel, ngController, ngClass

Creating Directives:
- like controllers, directives are registered on modules
- to register a directive use the module.directive API
- module.directive takes the normalized directive name followed by a factory function
- this factory function should return an object with the different options to tell $compile how the directive should behave when matched

Four ways to invoke a custom AngularJS directive:
- as an attribute
- as a class
- as an element
- as a comment

Restrict - the restrict option is typically set to:
'A' - only matches attribute name
'E' - only matches element name
'C' - only matches class name
'M' - only matches comment

Compile vs Link:
- "compilation" means attaching directives to the HTML to make it interactive
- $compile can match directives based on element names, attributes, class names, as well as comments

How directives are born: (compilation and instantiation)
- when the DOM is done loading and the AngularJS process starts, the browser parses the HTML into a DOM tree
- this tree is then parsed using AngularJS's $compile() method: $compile runs through the DOM tree and looks for directive declarations for the different DOM elements
- once all directive declarations are found for each DOM element and sorted (by priority), the directive's compile function is run
- it is expected to return a link() function that wraps all of the containing DOM element's directives' linking functions
- finally the linking function is invoked with the containing scope that attaches all of the associated directives to that scope
- the result of this process is the live data-binding between the scope and the DOM tree

- use $compile() to both manipulate the DOM before it's rendered and return a link function
- this also is the place to put any methods that need to be shared with all of the instances
- use link() to register all listeners on a specific DOM element (that's cloned from the template) and set up our bindings to the page.
- this is where we'll do most of the work when building directives, as this is where we can register listeners, set up watches, and add functionality

Isolate Scope:
- we want to be able separate the scope inside a directive from the scope outside, and then map the outer scope to a directive's inner scope
- we do this by creating what we call an isolate scope. by use a directive's scope option: true
- as the name suggests, the isolate scope of the directive isolates everything except models that you've explicitly added to the scope: {} hash object
- this is helpful when building reusable components because it prevents a component from changing your model state except for the models that you explicitly pass in

Factory vs Service: - Angular provides us with three ways to create and register our own service:
  Factory - creates an object, adds properties to it, then return that same object
  - when you pass this service into your controller, those properties on the object will now be available in that controller through your factory
  Service - instantiated with the 'new' keyword. add properties to 'this' and the service will return 'this'
  - when you pass the service into your controller, those properties on 'this' will now be available on that controller through your service
  Provider - the only service you can pass into your .config() function
  - use a provider when you want to provide module-wide configuration for your service object before making it available

Can you use jquery w/ angular?
- yes, but it's tricky, cuz both manipulate the dom
- not considered best practice
- Angular has a built-in subset of jQuery under the name jQLite