REA Tech Blog Scribbles

About

Just going through REA’s blog in no particular order as of September 15, 2016.

Getting Shit Done

Well-written: http://rea.tech/getting-shit-done/

What prevents us from “Getting Shit Done” is the last time we got shit done.

Pair programming lessons

  • There is only so much we can learn by watching someone else type
  • Driving helps us gain confidence as a member of the team and feel comfortable working with our pair
  • It gives us a sense of ownership
  • The fastest way to feel comfortable making mistakes, is to do it while someone is watching
  • Breaks comfort zones (less slacking, pushed to learn more)
  • Take breaks
  • Be prepared to say “I don’t know”

Why team managed infrastructure makes sense

  • Conway’s Law states that as an engineer you inevitably create a system that has the same structure as that of your organization.
  • Increases autonomy, responsibility, ownership, satisfaction and skills
  • Developers become dev-ops and support 24/7, incentivized not to make mistakes
  • Anyone in team should be able to deploy to production at any moment
  • Teams free to choose their own solutions, but should communicate/share with other teams
  • Some holistic solutions/standards will need to be adhered to by teams as deemed necessary

Category Theory

http://rea.tech/how-we-used-category-theory-to-solve-a-problem-in-java/

The Six QA Hats

tmp

Micro services, what even are they?

  • Different intent that SOA. SOA describes the organisation business logic, micro services describe the services themselves
  • Should do one thing well (narrow responsibility), have a small codebase (rewrite and redeploy within 2 weeks) and can be written in any language (cross-cutting logging and monitoring)
  • Mitigates bad design by restricting to a small service
  • More complexity in overall architecture, responsibilities and data integrity (scattered databases!)

Micro services are just tiny, focused SOA services. Too many micros and you push the complexity from the codebase to the architecture (contracts, responsibilities, data integrity). Like most things, use experience and common sense to do what’s right for a project.

A microservices implementation retrospective

What is the right size for a microservice? Varies between projects — balance between complexity (lots of repos, builds, clusters), maintainability (shared functionality, code) and the traditional benefits of SOA.

  • REA template projects
    • Logger (aggregation and rotation configs)
    • HAL (index and health check) and HAL Browser gems for exposing links between resources (i.e. RESTful HATEOAS)
    • Sample environment variable, database connection, async job, deployment config and monitoring
  • Non-blocking, idempotent (i.e. calling repeatedly is not harmful) APIs exposing meaningful events
  • Pact for contract testing
    • REA-developed open-source Ruby gem
    • Enables CDC (Consumer Driven Contract) testing (i.e. providers list set of endpoints, consumers inform provider of what services/data being used). Suited for when you control the provider and consumer.
    • Used for unit tests and mocks only, not ‘real’ integration testing
    • Checks consumer and provider contracts are in sync using a generated-then-shared pact file
  • Data integrity through idempotent job retries, job monitoring, change events triggering retrieval of current data, clear source of truth systems, unidirectional data flow (i.e. one-way sync).
  • Aggregated logging across many modules through Splunk (aggregation) and Nagios (monitoring). New Relic could also have been adopted.

Personally I’m not currently a huge fan of hyperlinked resources (i.e. HAL). They add extra weight to responses which 99% of the time will be ignored as users don’t tend to browse JSON and developers tend to read the documentation. Also, endpoints rarely change so additional calls for dynamic support are inefficient. My preference is RESTish or EBTH (everything but the hyperlinks).

Distributed Agile — Extreme Communication

  • Email is not the primary source of communication (face-to-face, video conf, IM)
  • Always-on video conferencing for offsite teams (China)
  • Remote pairing
  • Virtual card walls, physically replicated

Really interesting that REA needs so much development power that they need to outsource, which is never better except for cost-cutting. Pioneering the new global workplace I suppose!

Feeling Validated – A different way to validate your input

  • Validation requirements constantly change = refactoring
  • Use a Validation abstract class that only has two concrete subclasses: Success and Failure (with message)
  • Chain validation using flatMap. It will only continue to the next validation if passed the previous validation (otherwise map is empty) — and eventually returns a Success object.
validateInput(Map("postCode" -> "3121"), "postCode")
.flatMap(postCode => postCode.parseInt.leftMap(nfe => "post code must be a number"))
.flatMap(postCode => postCodeLookup(postCode).toSuccess("not in a valid area"))

For comprehensive validation, add metadata (i.e. annotations, directives) to elements and auto-validate.

The abject failure of weak typing

  • Ruby play-dough typing
  • Types are a proposition (i.e. assertion) applied by the compiler and known up-front. Implementation is it’s proof.
  • Tags are runtime type information (e.g. string, array, map) used by dynamic languages
  • Dynamic languages are actually unityped, not untyped
  • “Don’t write software that isn’t broken; write software that can’t be broken.”
  • “It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.”
  • Algebraic Data Type (ADT) are an abstract set of ‘objects’ and their operators. Very flexible objects that can return many types and apply functions depending on type. Objects with finite possibilities — a set. Still don’t really understand…!
  • Nulls
    • Ticking time bombs of NullPointerExceptions
    • Employ default values (e.g. “”, 0) or a safe Null object (that can respond in a sensible way)
    • What does “initialised piecemeal” mean?
    • Write immutable objects initialised in the constructor (to avoid null objects)
    • Java 8 Optional class, which checks for null and can handle missing methods
  • Exceptions
    • Don’t throw exceptions unless unavoidable
    • Checked exceptions are widely despised and frequently ignored (unsubstantiated)
    • When a result could be success or failure, use an Either or Validation (Success/Failure) object instead
    • Define your own ADT
  • Primitives
    • Possible astronomical number of values (e.g. integers). How to test all possible values?
    • Strings are vertitile and often used wrongly. Should only be for unstructured free text, not anything that has a constraint or structure (e.g. name, URL, email).
    • If there are a finite number of possibilities, used an ADT
    • Use wrappers to encapsulate the structure and make it impossible to create invalid variables. Can also be used to normalise as well.

References

Consumer-Driven Contracts: A Service Evolution Pattern

ConsumerDrivenContracts

About

Reading up on Pact for contract testing between API providers and consumers led me to a whitepaper by Ian Robinson from ThoughtWorks.

Cliffnotes

CDC (Consumer-Driven Contracts, or Derived Contracts) pattern for evolving API contracts as an alternative to schema extension (versioning) or “just enough” validation.

  • SOA
    • High-value business logic in discrete, reusable, encapsulated, testable, modifiable, connected services
    • Fully realise if services can evolve independently
    • Paradoxically, APIs couple providers and consumers rather than decouple (i.e. providers scared to make changes)
  • Existing strategies:
    • Update API: best for providers (simple change), worst for consumers (potentially all consumers must re-implement)
    • Extend API maintaining backwards compatibility: worst for providers (more complexity, less elegant, harder maintain), best for consumers (no change). Really big changes still require providers and consumers to jump at the same time.
  • W3C Technical Architecture Group (TAG) has proposed versioning strategies from none (no versioning) to big bang (abort if any changes), backwards/forwards-compatible 
  • Provider contracts
    • Term introduced meaning a complete set of business functions (i.e. APIs)
    • Stable and immutable for a set period of time!!
  • Consumer contracts
    • Consumers send providers expectations of what specific data is being used based of Schematron assertions (i.e. incomplete schemas validating only what the consumer actually uses)
  •  CDC:
    • CDC container consists of schemas, interfaces (endpoint definitions and possibly links), conversations (provider state!!), policy (usage of data) and quality of service (availability, latency and throughput) for a provider contract
    • Allows providers to track and analyse how services are being used in order to better meet customer demands
    • Adds complexity and protocol-dependence
    • Doesn’t protect from breaking changes or reduce coupling, but rather adds visibility
  • Misc:
    1. When developing a consumer, do “just enough” validation to get the data you need in accordance with the Robustness Principle (i.e. liberal attitude towards incoming data)
    2. Would be nice for consumer responses to possibly include data fields they want in the future (i.e. feature requests)

Conclusion

CDC violates REST (stateful), relies on immutable periods of time (fragility), adds too much complexity and overhead. A better standard for receiving feedback from consumers would be an optional (yet standardised) header in the request, which the provider could track.

Resources

Default Rails Application Demystified

rails-flow-mapping

Intro

When you run ‘rails new helloworld’ it creates 41 folder, 41 files and 10 gem dependencies! Below is a default Rails 4.1.6 project contents presented (comments edited for brevity) and demystified.

Simplified Flow

bin/rails > boot.rb > application.rb > environment.rb > server started

Ruby Files

Ignoring backtrace_silencers.rb, inflections.rb and mime_types.rb (empty).

/config/application.rb

Runs boot and loads all gem files. Called by the rails executable.

require File.expand_path(‘../boot’, __FILE__)
require ‘rails/all’
Bundler.require(*Rails.groups)
module HelloWorld class Application < Rails::Application end
end

/config/boot.rb

Sets environment variable to the location of the Gemfile then calls Bundler setup, which uses ENV to find the dependencies.

ENV[‘BUNDLE_GEMFILE’] ||= File.expand_path(‘../../Gemfile’, __FILE__)
require ‘bundler/setup’ if File.exist?(ENV[‘BUNDLE_GEMFILE’])

/config/environment.rb

Generic config file defining the application. Runs all initialiser classes.

require File.expand_path(‘../application’, __FILE__)
Rails.application.initialize!

/config/routes.rb

Map requests to controllers.

Rails.application.routes.draw do
end

/config/environments/development.rb

Overriding /config/application.rb settings when run in development mode.

Rails.application.configure do
# Changes don’t require a server restart
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports and disable caching. 
config.consider_all_requests_local = true 
config.action_controller.perform_caching = false
# Don’t care if the mailer can’t send. 
config.action_mailer.raise_delivery_errors = false
# Print deprecation notices to the Rails logger. 
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations. 
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets. 
config.assets.debug = true
# Adds additional error checking when serving assets at runtime. 
config.assets.raise_runtime_errors = true
# Raises error for missing translations # 
config.action_view.raise_on_missing_translations = true
end

/config/environments/production.rb

Overriding /config/application.rb settings when run in production mode.

Rails.application.configure do
# Code is not reloaded between
requests. config.cache_classes = true
# Load most of Rails and app object in memory for performance 
config.eager_load = true
# Full error reports are disabled and caching is turned on. 
config.consider_all_requests_local = false 
config.action_controller.perform_caching = true
# Disable Rails’s static asset server (Apache or nginx will already do this). 
config.serve_static_assets = false
# Compress JavaScripts and CSS. 
config.assets.js_compressor = :uglifier
# Do not fallback to assets pipeline if a precompiled asset is missed. 
config.assets.compile = false
# Generate digests for assets URLs. 
config.assets.digest = true
# Log level not debug to keep file size down. 
config.log_level = :info
# Send deprecation notices to registered listeners. 
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed. 
config.log_formatter = ::Logger::Formatter.new
# Do not dump schema after migrations. 
config.active_record.dump_schema_after_migration = false
end

/config/environments/test.rb

Overriding /config/application.rb settings when running test suites.

Rails.application.configure do 
# Code is not reloaded between requests. 
config.cache_classes = true
# Do not eager load code on boot. 
config.eager_load = false
# Configure static asset server for tests with Cache-Control for performance. 
config.serve_static_assets = true 
config.static_cache_control = ‘public, max-age=3600'
# Show full error reports and disable caching.
config.consider_all_requests_local = true 
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates. 
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment. 
config.action_controller.allow_forgery_protection = false
# Tell Action Mailer not to deliver emails to the real world. 
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
end

/config/initializers/assets.rb

# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = ‘1.0'

/config/initializers/cookies_serializer.rb

# Serialise cookies in JSON.
Rails.application.config.action_dispatch.cookies_serializer = :json

/config/initializers/filter_parameter_logging.rb

# Configure sensitive parameters which will be filtered from the log file.
Rails.application.config.filter_parameters += [:password]

/config/initializers/session_store.rb

# Cookie and session name based of app name.
Rails.application.config.session_store :cookie_store, key: ‘_hello-world_session’

/config/initializers/wrap_parameters.rb

Wraps the parameters hash into a nested hash allowing POST requests without having to specify any root elements.

# Enable parameter wrapping for JSON.
ActiveSupport.on_load(:action_controller) do wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
end

YAML Files

/config/database.yml

Define which database, locations and basic settings.

# Default settings
default: &default adapter: sqlite3 pool: 5 timeout: 5000
development: <<: *default database: db/development.sqlite3
test: <<: *default database: db/test.sqlite3
production: <<: *default database: db/production.sqlite3

/config/secrets.yml

Security-related configs such as signed cookie validation. Never push this file to a public Git repository!

development: secret_key_base: randomlygeneratedkeyatleast30characterslong
test: secret_key_base: randomlygeneratedkeyatleast30characterslong
# Read production key from environment (can’t start app if doesn’t exist)
production: secret_key_base: <%= ENV[“SECRET_KEY_BASE”] %>

/config/locales/en.yml

Internationalisation (i18n) properties file.

en: hello: “Hello world”

Other Files

Ignoring .gitignore, Gemfile.lock and README.rdoc.

/config.ru

Rackup file for running the Rack-compliant (adheres to a spec) web server.

require ::File.expand_path(‘../config/environment’, __FILE__)
run Rails.application

/Gemfile

Dependencies for the project. Managed by Bundler.

source ‘https://rubygems.org'
# Rails
gem ‘rails’
# Use sqlite3 as the database for Active Record
gem ‘sqlite3'
# Use SCSS for stylesheets
gem ‘sass-rails’, ‘~> 4.0.3'
# Use Uglifier as compressor for JavaScript assets
gem ‘uglifier’, ‘>= 1.3.0'
# Use CoffeeScript for .js.coffee assets and views
gem ‘coffee-rails’, ‘~> 4.0.0'
# Use jquery as the JavaScript library
gem ‘jquery-rails’
# Turbolinks makes following links in your web application faster.
gem ‘turbolinks’
# Build JSON APIs with ease.
gem ‘jbuilder’, ‘~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem ‘sdoc’, ‘~> 0.4.0', group: :doc
# Speed up development by keeping your application running in the background.
gem ‘spring’, group: :development

/Rakefile

Load web application when rake is called.

require File.expand_path(‘../config/application’, __FILE__)
Rails.application.load_tasks

/bin/bundle

Bundler gem management executable.

ENV[‘BUNDLE_GEMFILE’] ||= File.expand_path(‘../../Gemfile’, __FILE__)
load Gem.bin_path(‘bundler’, ‘bundle’)

/bin/rails

Main Rails executable.

begin load File.expand_path(“../spring”, __FILE__)
rescue LoadError
end
APP_PATH = File.expand_path(‘../../config/application’, __FILE__)
require_relative ‘../config/boot’
require ‘rails/commands’

/bin/rake

Build tool executable (Ruby equivalent to Make).

begin load File.expand_path(“../spring”, __FILE__)
rescue LoadError
end
require_relative ‘../config/boot’
require ‘rake’
Rake.application.run

/bin/spring

For development, keeps a copy of the running app in the background. Injects code into rails and rake executables.

unless defined?(Spring) require “rubygems” require “bundler”
if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ spring \((.*?)\)$.*?^$/m) ENV[“GEM_PATH”] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR) ENV[“GEM_HOME”] = “” Gem.paths = ENV
gem “spring”, match[1] require “spring/binstub” end
end

References

Ruby observations from a Java guy

rails
About

After a decade of Java experience currently learning Ruby/Rails because it’s the Hot Shit™.

Overall

  • Fun. A cowboy language (see: monkey patching).
  • Rapid development great for new projects, startups, messing about. Productive.
  • Low enterprise adoption in Australia yet lots of smaller companies looking for developers.
  • Lots of freedom for developers (patching, overriding) relies on discipline of programmers, and since all humans make mistakes, eventual loss of control — especially for large projects. Mitigate risk with comprehensive regression testing and small modular components.
  • ERB (Embedded RuBy) reminds me of JSP on pages in Java — a practice frowned upon because it mixes languages (used HTML-valid taglibs).
  • Lots of files generated with a new project (41 folders, 41 files)!
  • Lots of objects per request (Rails3 ‘hello world’ ~8.5k objects, GC every ~6 requests)!
  • MRI (Matz’s Ruby Interpreter, CRuby) was replaced by YARV (Yet Another Ruby Vm, KRI) in Ruby 1.9 as the default executable. Other implementations include JRuby (runs on Java’s JVM), Rubinius, RubyMotion etc.
  • Ruby doesn’t support true concurrency (Global Interpreter Lock). Use JRuby threads or fibres and non-blocking IO. Headaches of dealing with code and gems that aren’t thread-safe.

Conventions

  • Convention over configuration (“The Rails Way”), lean principles.
  • No service folder/layer by default? Rails way to put business logic in models — can get messy.
  • GDD (Gem-Driven-Development): Before coding, check what gems exist, don’t reinvent the wheel. For serious projects, can lead to security and performance (i.e. object creation) issues.
  • Brackets for method parameter/arguments? No consensus.
  • Symbols don’t get GC’d so don’t use for dynamic data or else memory leak.
  • “Fat model, skinny controller.” Only logic for sessions, cookies, request parameters, model selection, rendering/redirecting.
  • Don’t put too much logic in the view — leverage partials, decorators, helper classes.
  • Don’t put too much logic in the model. Only logic for ActiveRecord relations/validation, database interaction, property helpers (e.g. fullname), sophisticated queries. Use POROs (Plain Old Ruby Objects) instead (i.e. services, SOA).

Production

  • Define secret_key_base in secrets.yml.
  • Set config.assets.compile to true in production.rb (otherwise CSS not included).

Heroku

  • No support for SQLite, must add ‘pg’ (PostgreSQL) gem to Gemfile for production. Pain in the ass adding the pg gem (requires install of Postgres locally even though not used…WTF).
  • Very easy to deploy.

Testing

  • Huge necessity for BDD/TDD and regression testing to ensure confidence. Poor static code analysis due to loosely-typed, difficult to enforce design patterns with interfaces/abstract/access modifiers/encapsulation.
  • Minitest or RSpec? Both good.
  • Domain Specific Language (spec) notation (e.g. “describe calling foo it should return bar”), matches user stories, easier for non-programmers to understand, personal preference.
  • Minitest supplied with Ruby, replacement for older Test::Unit gem, unit testing (Ruby or spec), mocking, benchmarks, lightweight, BDD requires configuration (capybara = start browser), require ‘test_helper’ for web application context (loads initialisers/configs, slower).
  • RSpec many ways to do the same thing, advanced features (before all, around each, shared groups/contexts, powerful mocks, verifying doubles = mock checks methods exist…awesome), BDD out of the box.
  • Additional gems: Mocha (mocking), Shoulda (matchers).

RubyMine

  • Generated test classes do not work out of the box.
  • Can’t get Heroku deployment to work (terminal only).
  • Poor code completion and IDE errors due to loosely-typed. Not knowing off-by-heart end up Googling (read: Stack Overflow) a lot. BDD/TDD guesswork because not sure if even syntax is correct until at the implementation stage — run and see if it breaks!

Conclusions

  • Very enjoyable and ideally suited for non-critical projects/modules with manageable numbers of developers (80/20 rule).
  • BDD/TDD is essential.
  • Standard Rails may have performance issues due to high object creation and inefficient GC.

References

Java Interview Questions Cheat Sheet

java

About

For refreshing one’s memory before an interview.

Core Java

  • About: Strict typed, class-based, OO, platform-agnostic
  • Lifecycle: compile .java to .class bytecode, run just-in-time by the JVM, no reference, finalize(), GC
  • Keywords: import, finally, super, class, package, int, synchronized (one thread at a time, avoids data race [multiple threads access same data], method or block), volatile (modified by other threads)…many more!
  • Objects:
    • state = fields, behaviour = methods
    • == (compares references i.e. same object in memory, shallow comparison), equals method can be overridden for deep comparison of properties
    • hashCode (unique hash) — used by maps, same object should produce same hash must override both
    • Dog puppy [declaration] = new [instantiation] Dog(“fido”) [initialisation]
  • Class: object creation blueprint, load manually by ClassLoader (dynamic plugins), top-level can’t be private/protected, auto loads java.lang.package, inner classes, nested class (static within class)
  • Interface: collection of abstract methods, Externalizable (serialisation), Enumerator (loops), Iterator (looping with support for removing, thread safe), Comparable (natural order), Comparator (custom order), Marker (empty, use annotation instead)
  • Scope: local (within method), instance (property), class (static)
  • Constructor: invoked only once on creation, if private no instantiation no subclassing (e.g. singletons)
  • Primitives: boolean, char (16-bit unicode), byte (8-bit), short (16), int (32), long (64), float (32), double (64)
  • Wrappers: Autoboxing, unboxing (e.g. Integer)
  • Collections:
    • Set (no duplicates), TreeSet (sorted), Vector (heterogeneous [different types], dynamic, sync), ArrayList (dynamic, random access), LinkedList (sequential add/remove), Map, HashTable (sync, no null)
    • ordered longer insert, faster lookup
  • Loops: do executes at least once
  • Streams: Reader/Writer (char), Input/OutputStream (byte, serialisation), System.out (PrintStream)
  • Modifiers:
    • final (variable = immutable, methods = no override, class = no extend)
    • protected (access by same package and subclasses)
    • default (same package)
  • Switch: byte, short, int, char (why?)
  • Strings: immutable, final (can’t subclass and make a mutable string), stored on stack, thread-safe, StringBuffer (sync), StringBuilder
  • OO: simple, modular, modifiable, extensible, maintainable, reusable
  • Abstraction: partial implementation, enforcing blueprint, class only extended
  • Encapsulation: data hiding through getters/setters, maintainability, modifiable
  • Inheritance: no multiple inheritance (no circular dependency, ambiguous calls e.g. super = diamond problem), extend one class, implement many interfaces
  • Polymorphism: Dynamic Method Dispatch, “many forms”, method overloading at runtime, method overriding at runtime
  • Acronyms: JAR (Java ARchive), WAR (Web ARchive), JDBC (Java DataBase Connectivity), Java EE (Enterprise Edition), Java SE (Standard Edition), JDK (Java Development Kit), JRE (Java Runtime Environment)
  • JDBC: PreparedStatement precompiled faster
  • Threads:
    • single execution in a process
    • sleep, wait (up to until notify), yield, suspend, notify, notifyAll, isAlive,
    • newborn > runnable > running > blocked > dead
    • daemon = background low priority
    • implement Runnable or extend Thread (manage manually)
  • Errors:
    • Error: irrecoverable (e.g. OutOfMemory)
    • Exception: recoverable (e.g. FileNotFoundException), Checked: throws BadInputException
    • Assertion: never-happen scenarios and tests (e.g. assert dependency exists)
  • Binding: dynamic (late, generics, polymorphism), static (static, final, private)
  • Sockets: lightweight TCP/IP (Transmission Control Protocol)
  • Env: CLASSPATH (.class files), PATH (executables)
  • Casting: downcast to a more specific type down the hierarchy (e.g. Animal > Dog), implicit (inferred, lossy), explicit, promotion (e.g. short to int)
  • Big O Notation: O(1) constant, O(n) linear loop, O(n2) quadratic nested loop, O(n3) cubic double-nested loop, O(log n) logarithmic half list each time binary search
  • Cookies: client-side sent every request, Session: server-side (or encrypted cookies)
  • Date: sql date (no time) extends util
  • Parameters:
    • definitions, Arguments: actual values
    • pass by value, object properties can still be modified!
  • Bean: encapsulation (getters/setters), public constructor, serialisable
  • Terms:
    • Referential Transparency: no outside influence, don’t need to understand full context/globals.
    • Boundary Condition: extreme inputs.
    • Composition: class holding reference to another class.
    • SOLID Principle: open to extension, closed to modification.
    • Demarcate: to define boundaries (e.g. transaction).
    • Non-blocking API: don’t wait for 3rd party API calls (e.g. threads).
    • Single responsibility principle: each variable/method/class should define a single responsibility (only one reason to change).
    • Idempotent: calling same method multiple times doesn’t hurt (e.g. remove item from list).
    • Separation of concerns: modular.
    • (String) Interpolation: String with placeholders (e.g. $foo).
    • Method vs function: methods are functions tied to an object (e.g. it’s behaviour).
  • Memory Leaks: Thread running ClassLoader (ThreadLocal keeps reference), String.intern, unclosed streams/connections, static, setAttribute (context, session)
  • Improve Java: less verbose (e.g. getters/setters), as-needed modular (Jigsaw), kill servlets, not Oracle
  • Performance: monitoring, java startup arguments (e.g. heap), pooling, caching, refactoring, latest versions, scale up, scale out
  • Sort:
    • Bubble (quad, compare and swap adjoining elements, pass through until no swaps, low memory > performance, simple)
    • Insertion(quad, one element at a time, insert in the right spot, linked list pointers, simple, efficient small data)
    • Quick (log to quad, choose pivot/middle value, from left>right if value less than pivot, replace with first lesser value working from the right, recursive)
    • Merge (log, divide and conquer, split until single elements, combine in order until sorted, simple, requires space)
  • Search: linear (n, for loop), binary (sorted, half each pass, recursion)
  • Annotations:
    • meta-data through introspection, less code, dev time (documentation, checking), runtime (wiring, descriptions)
    • @NotNull, @Controller, @Transaction, @Entity, @Override
  • IDE: auto-completion, code generation, static code checks, plugins, highlighting (CheckStyle, FindBugs)
  • Java Versions:
    • 5 (generics, annotations, enums, for-each), 6 (meh), 7 (string switch, try with resources, <> operator), 8 (lamdbas)
    • Java SE = JVM, JDK = JRE + compilers
  • Testing: mock objects, stub methods, unit = smallest component (e.g. a method), integration = multiple components together (e.g. log in), user acceptance = customer expectations, non-regression = re-running all tests for confidence (e.g. Continuous Integration), spec = declarative specification style (non-programmers, readable, Domain Specific Language)
  • Design Patterns: singleton (instantiated once, shared resources e.g. log, pooling), prototype (copy), facade (abstract away complexity), factory (create objects), abstract factory (create factories), observer (notifies, AOP), MVC, MVVM (ViewModel = exposed data bindings to the view rather than rendering, separate UI), adapter (connect two interfaces), strategy (common functionality e.g. sort), state (?), proxy (control access), DI, builder (create complex objects), chain of responsibility (pass request e.g. filter, log), template (outline, subclasses do steps), decorator (add functionality to existing e.g. override). Gang of Four (GoF) authors.

Spring

  • About: framework, open-source, IoC container
  • Modules: core, bean, context, JDBC, ORM, JMS, web (context, binding), AOP, transactions…
  • Inversion of Control (IoC): loose coupling of code from metadata and dependencies, easier to test in isolation, Dependency Injection (DI via constructor or setters)
  • Service-Oriented Architecture (SOA): Loosely coupled services (Law of Demeter), interact as black boxes, distributed, modular, interoperability
  • BeanFactory: creates container
  • Container: lifecycle of a bean (invokes, config, dependencies, security, transactions, management, destroy), override setup/destroy methods
  • Pattern: default Singleton, otherwise prototype (inner bean)
  • Annotations: declarative management, @Autowired (auto resolve dependencies), @Required (must be initialised at runtime), @Service/Component/Repository (labels), @Transactional, @Test(expected=IOException.class), @Before, @After
  • AOP: Aspect (encapsulation), Joinpoint, Pointcut (1+ Joinpoints), Advice (actual code)
  • DAO: JPA and Hibernate, lazy/eager loading
  • JMS: Message-Driven Beans (MDB), queues, process messages async
  • Dispatcher: DispatcherServlet reads incoming requests, calls the right class/method, combines result with the right view and returns response
  • Context: WebAppContext extends AppContext and adds ServletContext (resources, defined contexts in web.xml)
  • Deployment Descriptor: web.xml, describes classes, resources, config, request mapping
  • Classloader: Executes hierarchy top to bottom (superclasses first), different strategies per app server
  • TDD: JUnit (assertEquals), Mockito (mock foo, when foo.bar thenReturn, verify foo.doh), Hamcrest (assertThat, is, not, any, anything, equalTo, isA)

JavaScript

  • About: ECMAScript, scripting language, loosely typed, prototypical (prototype-based), object-based
  • Modules: wrap in function block, namespacing, alias (e.g. $.foo)
  • Scope: var foo (local), foo (global). Only functions create new scope, not blocks.
  • Data Types: undefined (default), number, string, boolean, object (e.g. foo = {}, foo = new Array), function, null
  • Operators: == (type conversion), === (no type conversion)
  • Inheritance: prototype (i.e. chained parent refs, inherit properties, parent not modified) or Object.create(Object.create) = recommended
  • Strict Mode: no accidental globals, duplicate property names etc.
  • Number: no integer, floating point precision (nearest binary point) = weird stuff! Don’t use for precision!
  • DOM: Document Object Model, object of rendered page, interact with
  • Event Bubbling: parent nodes triggered
  • jQuery: lightweight, cross-browser, plugins, CSS3, supported, selectors, manipulation, loops, events, animations, AJAX, utilities…
  • Hoisting: Variable declarations and function declarations (not function expressions) are invisibly moved to the top of their scope.
  • Isomorphic: Code that can be run client or server-side.
  • Function Types: Function expression (i.e. unnamed/anonymous, parse-time available when assignment line hit) vs function declaration (i.e. named, run-time scope before any step-by-step code is executed, can’t put inside conditional blocks such as if/try/while, proper name when debugging). It’s possible to combine both styles, but has IE8 issues. Never use the Function() constructor. ECMAScript6 will attempt to infer expression names from context.
    // Function expression
    var foo = function() {}
    // Function declaration
    function foo() {}
    // Combined/Named Function Expression
    var foo = function bar(){};
    // Combined with proper aliasing across browsers
    function bar(){};
    var foo = bar;
  • Cross Browser: JavaScript can’t POST cross-domain (use a library like easyXDM or back-end)
  • Weird: null is an object (default undefined), foo(2)(3) returns annon function, semicolons optional, negative infinity (negative / 0)

Functional

  • Predicate: function that runs against every item in a collection — returning true or false. Used for filtering without nested for/if statements.
  • Lambdas: function that can be passed around like an object.
  • Closures: private variables made possible through self-invoking functions (i.e. outer function contains private variables and returns function expression — outer only ever called once). Example:
// self-invoking run only once
var add = (function () {
  // counter protected by anonymous scope (private)
  var counter = 0;
  // add function associated with returned function expression
  return function () {return counter += 1;}
})();

add(); // counter = 1
add(); // counter = 2

Tips

  • BDD/TDD!
  • Whiteboarding use pseudo code placeholders to guide the thought process — then replace pseudo with implementation. Don’t get stuck on implementation before solution is mapped out.
  • Don’t commit boilerplate code, IDE files and comments to the repository
  • Be involved in the community (follow people, read blogs, stream, attend events, network, work on projects)
  • Commit often to your local Git repository and every day or so to the remote origin
  • Never say “can’t” — don’t lie, but back yourself to learn it. Most things are not that hard.

Room For Improvement

  • Encoding, bit shifting, octal/hex, Applets (Swing, AWT), JVM heap, GC (WeakReference), PermGen (class metadata), RMI, Servlets/JSP, Angular, monoids.