Model and scenarios first before coding, coding just implementation of model, focus on business, not on database or technologies

Model based language

Model description – UML, text, anything

Layered architecture – UI, application, domain, infrastructure

Bounded context – common ubiquitous (with domain experts) language, all terms are uniq in scope of the bounded context, if there are two meaning of the same form – this definitely means that they belong to two different bounded contexts

Ubiquitous language (best implemented by BDD – given/when/then)

There will be design anyway, good (common for everyone, verified by domain experts) or bad (mix of multiple designs from multiple developers)

All GC do stop-the-world pause while checking the eden, for not eden, CMS and G1 may do (lower CPU consumption) or with not stop-the-world pause (high CPU consumption)

Serial GC (x32, single core machine or Windows) – for client:

single threaded

stop-the-world for new or old generation processing

Throughput (Unix, multi-core, x62):

multi-threaded

stop-the-world for new or old generation processing

CMS:

– multiple threads for new generation

for old generation, one thread scans object to free in background with no stop, but old generation remains fragmented, stop-the-world still happens, but quite rare, to defragment the old generation heap, usually it happens when there is no space to allocate for new object

try-catch-finally can return a value, its a last computed line of try block or relevant catch block, or return statement of finally (with no return keyword finally returns Unit)

Nested scopes with variables will shadow variables from embraced scope with the same name (in Java it is forbidden)

Nested functions are allowed, they have an access to parameters of eclosing functions

Lambda

(parameter list) => {body to execute}

Placeholder _ – foreach _ parameter can appear at function body only once

Partially applied functions – bound variables

“funcName _” – produces function object with all parameters bound, actually it generates a class with “apply” method that takes all parameters of original function. In some cases (when function type is expected) it is possible just leave a name with no placeholder

val fooOneParamString = fooTwoParamIntAndString(1, _: String)

Is free variable from closure is changed after closure is created, closure sees these changes, opposite is true also, if closure changes free variable, it will be observed outside.

Free variables of closure live at heap (not at stack) so can be accessed all the time closure exists

Variable arguments list

foo(i: Int *)

inside it can be iterated as it would be an array

To pass an array at such function it should be appended with “: _*” sequence.

foo(arr: _*)

Named arguments

foo(argName = argValue), can be at any order

Default function parameters

foo(i: Int = 10)

Tail recursion optimisation – is applied by compiler by default

Currying

foo(x: Int)(y: Int) – called foo(1)(2), if only one parameter provided – new function is returned, but placeholder should be postfixed, like foo(1)_

Curly braces can be used instead of round for any method, that accepts only one argument

By-name parameters allows to drop empty parameter list of function type, that is passed as a parameter to other function

foo( boo: ()=> Int ) -> foo( boo: => Int )

So it can be called

foo(()=>2+3) -> foo(2+3)

“2+3” – will be (or not) executed within foo body (it allows optionally to avoid side effects of 2+3 calculation), but in case of “foo(i: Int)” 2+3 will be executed before foo call.

Abstract classes

abstract class cl

{

def foo(i: Int): Boolean

}

Abstract class can have both abstract and concrete methods, abstract methods just doesnt have a body

Parameterless methods are used by conventions when they do not change state of a class, dont have side effects and do not depend on mutable state, to provide uniform access principle, to give client ability to access properties or fields at the same way

def foo : Int = 5

Empty-paren methods – for other cases, when state is changed

def foo : Int = //change state here

extends keyword – like at Java inherits one class from another

scala.AnyRef like java’s java.lang.Object

Fields and method can be overridden, as well as parameterless method can override and be overriden by field with the same name

Method and field at the same class could not have the same name, so they at the same namespace.

copy method is added, it allows to create a copy of object with options new value for any parameter/parameters

case class Item(i : Int, s : String, l : Long)

val res = Item(3, “wer”, 5) match {

case Item(_, v, 5) => v

}

match like switch, but with no breaks and it returns a value

val res = itemToCheck match {

сase value => expression

case _ => defaultExpression

}

Three kinds of patterns:

v (any variable name) – bound variable, can be used at right side from =>, if it start with capital letter, scala check for constant value with such name, if not found or the first letter is not capital, it is considered as bound variable. If you need to have lower case variable not be considered as a bound variable, you can enclose it into back ticks (like `v`) or prepend with object identifier (like this.v or obj.v)

Sealed super-class cannot have other descendants than defined at the same file. If such classes are used at pattern matching, compiler will check that match covers all possible cases. It refers to class types, not to its parameters. Sealed class checks only match expressions mentioned all subclasses inherited from sealed one.

Arrays are covariant at Java, but type runtime checks that object has suitable types

Type bounds

Lower bound def enqueue[ U >: T]() – means U is supertype of T

Upper bound def enqueue[ U <: T]() – means U is subtype of T

trait AbstractTrait {

type T //abstract type

def foo( x: T): T

val field1: T

var field2: T

}

class Impl extends AbstractTrait {

type T = Int

def foo( x: Int ) = x + x

val field1 = 1

var field2= field1

}

def can be overridden with val but not vice vers

trait tr{

val i : Int

}

val t = new tr {

val i: Int = 1

}

if a field is initialized with an expression, in case of abstract val – expression is evaluated after constructor, in opposite to class parameters (new cl(param1)) which is evaluated before constructor

abstract var is represented only with abstract getter and setter, no field itself, it comes at implementation only

Pre-initialized fields – allows to initialize fields of child class before parent class constructor is called (in case these fields are used at parent constructor it is important) – just to put them within curly brackets between new and type name. It is not possible to refer itselfs with this, this would mean a wrapping class, not the constructed one.

implicit conversion item name (function or class) should be accessible with no qualifiers (path) as one word, there is only one exception – companion object can contain implicit conversion item and it is also observed by compiler

Only one implicit conversion is applied

If code works with no expression, no expression is applied

Name of implicit conversion is important in two cases:

If conversion is called explicitly, for debug purposes

If two conversions are available at some scope and you need to import only one

When implicit conversion are applied:

when some type is expected, but other is provided, implicit def int2string( x: Int): String = x.toString

converting receiver, when some method called on object that doesn’t have it, implicit conversion can convert it into other object that have it. There are implicit methods and implicit classes for this purpose. Class has a constructor that accept a initial type, and contains a method that is expected.

When parameters are expected, that nearest variable with corresponding type is used

Scala collection hierarchy

Traversable

Iterable

Seq

IndexedSeq

Vector

ResizableArray

GenericArray

LinearSeq

MutableList

List

Stream

Buffer

ListBuffer

ArrayBuffer

Set

SortedSet

TreeSet

HashSet (mutable)

LinkedHashSet

HashSet (immutable)

BitSet

EmptySet, Set1, Set2, Set3, Set4

Map

SortedMap

TreeMap

HashMap (mutable)

LinkedHashMap (mutable)

HashMap (immutable)

EmptyMap, Map1, Map2, Map3, Map4

Constructing a stream

val str = 1 #:: 2 #:: 3 #:: Stream.empty

Vector have a constant access time to any its part (slower than head access to list, but still constant – lists are quick only for accessing beginning)

Equality of containers – three categories: sequence, map, set. Containers from different category are always inequal. From the same – equal if contains the same elements (for sequence order should be the same). Mutability doesn’t matter.

Extractor – is an object with unapply method, it is opposite to appy. unapply take an object and returns its parts as Some(tuple of parts), or None. It can be zero or one variable, since there is no one element tuple, just option of value is returned in case of single element.

It is possible to pass a value of other type, not the one is defined as a single parameter of unapply method, but, the value should be castable to expected parameter type.

If a number return parameters of unapply method is not defined, means a sequence can be returned, such method should be called unapplySeq and return Option[Seq[T]]

Regular expressions are build over scala.util.matching.Regex type in form:

regex findFirstIn str

regex findAllIn str

regex findPrefixOf str

Annotations

@deprecated

@volatile

@serializable, @transient

@scala.reflect.BeanProperty

@tailrec

@unchecked

@native

@throws – emulating java’s throws exception list

XML

XML literal – just open a tag and write valid XML – it will be considered as scala.xml.Elem type.

Other types: Node, Text, NodeSeq

To serialize some object into XML, class should contain toXML method, for deserialization – fromXML, accepting scala.xml.Node and returning instance of the class itself.

Node object can be used at pattern matching, _* – means any sequence of nodes.

[[noreturn]], indicating that the function will not return using the normal call/return mechanism

override, indicating that it must be overriding a virtual function from a base class

final, indicating that it cannot be overriden in a derived class

That is, a prefix auto indicates that the return type is placed after the argument list. The suffix return type is preceded by −>.
The essential use for a suffix return type comes in function template declarations in which the return type depends on the arguments. For example:
template<class T, class U> auto product(const vector<T>& x, const vector<U>& y) −> decltype(x∗y);
However, the suffix return syntax can be used for any function.

A constexpr function cannot have side effects, so writing to nonlocal objects is not possible.

If there is a possible ambiguity, an initializer_list parameter takes priority.

Unspecified Number of Arguments

a variadic template

an initializer_list as the argument type

Terminate the argument list with the ellipsis ( … )

Automatic Overload Resolution

Exact match

Match using promotions

Match using standard conversions

Match using user-defined conversions

Match using the ellipsis … in a function declaration

Overloading takes place among the members of an overload set. By default, that means the functions of a single scope; functions declared in different non-namespace scopes do not overload.

The C++ standard library provides provides one of the following guarantees for every library operation:

The basic guarantee for all operations: The basic invariants of all objects are maintained, and no resources, such as memory, are leaked.

The strong guarantee for key operations: in addition to providing the basic guarantee, either the operation succeeds, or it has no effect.

The nothrow guarantee for some operations: in addition to providing the basic guarantee, some operations are guaranteed not to throw an exception.

Both the basic guarantee and the strong guarantee are provided on the condition that

user-supplied operations (such as assignments and swap() functions) do not leave container elements in invalid states

user-supplied operations do not leak resources

destructors do not throw exceptions

double compute(double) noexcept; // may not throw an exception. It terminates unconditionally by invoking std::terminate() if exception is thrown.

[3] If H and E are pointer types and [1] or [2] holds for the types to which they refer

[4] If H is a reference and [1] or [2] holds for the type to which H refers

The guiding principles are:

Don’t throw an exception while handling an exception.

Don’t throw an exception that can’t be caught.

The specific rules for calling terminate() are

• When no suitable handler was found for a thrown exception
• When a noexcept function tries to exit with a throw
• When a destructor invoked during stack unwinding tries to exit with a throw
• When code invoked to propagate an exception (e.g., a copy constructor) tries to exit with a throw
• When someone tries to rethrow ( throw; ) when there is no current exception being handled
• When a destructor for a statically allocated or thread-local object tries to exit with a throw
• When an initializer for a statically allocated or thread-local object tries to exit with a throw
• When a function invoked as an atexit() function tries to exit with a throw

By default, terminate() will call abort(). If that is not acceptable, the user can provide a terminate handler function by a call std::set_terminate() from <exception>

If an exception is not caught on a thread, std::terminate() is called.

Initialization X a1 {v}; – initializer list – prevents data gets lost, like narrowing (integer of float point datatypes) or floating integer type conversion but auto should be initialized with assignment auto z1 {99}; // z1 is an initializer_listauto z2 = 99; // z2 is an int difference for vector as well vector v1 {99}; // v1 is a vector of 1 element with the value 99vector v2(99); // v2 is a vector of 99 elements each with the default value 0 Prefer {} initialization over alternatives unless you have a strong reason not to. The empty initializer list, {} , is used to indicate that a default value is desired. Nice example – char buf[max] {}; // initialize every char to 0 If initialization is missed