Want to dive even deeper?

Take the course Play Framework for Web Application Development by Martin Gontovnikas and become an expert!
Play Framework for Web Application Development
by Martin Gontovnikas

Check it out!
You're watching a preview of this video, click the button on the left to puchase the full version from Devoxx'09.

Future-proofing collections: from mutable to persistent to parallel

Multicore processors are on every desk now. How are we going to make use of the extra power they provide? Some think that actors or transactional memory will save the day by making concurrent programming easier and safer. Even though these are welcome, I am skeptical about their ultimate success. Concurrency is fundamentally hard and no dressing up will be able to hide that fact completely. A safer and for the programmer much simpler alternative is to treat parallel execution as essentially an optimization. A promising application area are collections. Programing by transforming and aggregating collections is simple, powerful, and can optimized by executing bulk operations in parallel. To be able to do this in practice, any side effects of parallel operations need to be carefully controlled. This means that immutable, persistent collections are more suitable than mutable ones. In this talk I will describe the new Scala collections framework, and show how it allows a seamles...

Published on
  • 12.634
  • 107
  • 0
  • 9
  • 0
  • Future-Proofing Collections from mutable to persistent to parallel Martin Odersky Scala Solutions and EPFL
  • The challenge we are facing: How to pay for lunch? 2
  • The challenge we are facing: How to make use of rapidly increasing hardware parallelism? Example: Nvidia Fermi: – One processor needs 24’000 running threads to keep it happy. Currently: – Server: Distribute connections over cores – Client: Only parallelize special tasks such as graphics. This will not last! Need to deal with: – Big data – Massive simulations – High-res models PPP grand challenge 3
  • Concurrent Programming to the Rescue? • Today, an often heard answer is concurrent programming, using – – – – Threads and locks, or Actors with messages, or Agents, or STM //  asynchronous  message  send actor  !  message //  message  receive receive  {    case  msgpat1  =>  action1    …            case  msgpatn  =>  actionn } • • All these concepts are useful. But they will not solve the PPP Challenge. – Fundamental problem: non-determinism – Leads to Heisenbugs, different behavior on different hardware, etc 4
  • The Root of The Problem • Non-determinism caused by concurrent threads accessing shared mutable state. We can encapsulate state in actors or transactions, but the fundamental problem is the same. So, • • non-determinism = var  x  =  0 async  {  x  =  x  +  1  } async  {  x  =  x  *  2  } //  can  give  0,  1,  2 • • parallel processing + mutable state To get deterministic processing, avoid the mutable state! Avoiding mutable state means programming functionally. 5
  • Space vs Time Space (functional/parallel) Time (imperative/concurrent) 6
  • Scala 7
  • Scala is a Unifier Agile, with lightweight syntax Object-Oriented Scala Functional Safe and performant, with strong static tpying 8
  • Let’s see an example: 9
  • A class ... public  class  Person  {    public  final  String  name;    public  final  int  age;    Person(String  name,  int  age)  {            this.name  =  name;            this.age  =  age;    } } class  Person(val  name:  String,                            val  age:  Int)  {}
  • ... and its usage import  java.util.ArrayList; ... Person[]  people; Person[]  minors; Person[]  adults; {    ArrayList<Person>  minorsList  =  new  ArrayList<Person>();      ArrayList<Person>  adultsList  =  new  ArrayList<Person>();      for  (int  i  =  0;  i  <  people.length;  i++)              (people[i].age  <  18  ?  minorsList  :  adultsList)          .add(people[i]);      minors  =  minorsList.toArray(people); A function value      adults  =  adultsList.toArray(people); An infix method call A simple pattern match val  people:  Array[Person] val  (minors,  adults)  =  people  partition  (_.age  <  18)
  • Scala 2.8 Collections Building interesting things in space 12
  • ... and its usage import  java.util.ArrayList; ... Person[]  people; Person[]  minors; Person[]  adults; {    ArrayList<Person>  minorsList  =  new  ArrayList<Person>();      ArrayList<Person>  adultsList  =  new  ArrayList<Person>();      for  (int  i  =  0;  i  <  people.length;  i++)              (people[i].age  <  18  ?  minorsList  :  adultsList)          .add(people[i]);      minors  =  minorsList.toArray(people); A function value      adults  =  adultsList.toArray(people); An infix method call A simple pattern match val  people:  Array[Person] val  (minors,  adults)  =  people  partition  (_.age  <  18)
  • Scala 2.8 Collections Building interesting things in space 12
  • The Scala Way of Collections • • De-emphasize destructive updates Focus on transformers that map collections to collections Have a complete range of persistent collections scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3) scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3) scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4) scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4) • 13
  • Collection Properties • • • • object-oriented generic: List[T],  Map[K,  V] optionally persistent, e.g. collection.immutable.Seq higher-order, with methods such as foreach,  map,   filter. Uniform return type principle: Operations return collections of the same type (constructor) as their left operand, as long as this makes sense. scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3) scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3) scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4) scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4) • This makes a very elegant and powerful combination. 14
  • ... and its usage import  java.util.ArrayList; ... Person[]  people; Person[]  minors; Person[]  adults; {    ArrayList<Person>  minorsList  =  new  ArrayList<Person>();      ArrayList<Person>  adultsList  =  new  ArrayList<Person>();      for  (int  i  =  0;  i  <  people.length;  i++)              (people[i].age  <  18  ?  minorsList  :  adultsList)          .add(people[i]);      minors  =  minorsList.toArray(people); A function value      adults  =  adultsList.toArray(people); An infix method call A simple pattern match val  people:  Array[Person] val  (minors,  adults)  =  people  partition  (_.age  <  18)
  • Scala 2.8 Collections Building interesting things in space 12
  • Collection Properties • • • • object-oriented generic: List[T],  Map[K,  V] optionally persistent, e.g. collection.immutable.Seq higher-order, with methods such as foreach,  map,   filter. Uniform return type principle: Operations return collections of the same type (constructor) as their left operand, as long as this makes sense. scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3) scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3) scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4) scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4) • This makes a very elegant and powerful combination. 14
  • The Scala Way of Collections • • De-emphasize destructive updates Focus on transformers that map collections to collections Have a complete range of persistent collections scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3) scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3) scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4) scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4) • 13
  • ... and its usage import  java.util.ArrayList; ... Person[]  people; Person[]  minors; Person[]  adults; {    ArrayList<Person>  minorsList  =  new  ArrayList<Person>();      ArrayList<Person>  adultsList  =  new  ArrayList<Person>();      for  (int  i  =  0;  i  <  people.length;  i++)              (people[i].age  <  18  ?  minorsList  :  adultsList)          .add(people[i]);      minors  =  minorsList.toArray(people); A function value      adults  =  adultsList.toArray(people); An infix method call A simple pattern match val  people:  Array[Person] val  (minors,  adults)  =  people  partition  (_.age  <  18)
  • Using Collections: Map and filter scala> val xs = List(1, 2, 3) xs: List[Int] = List(1, 2, 3) scala> val ys = xs map (x => x + 1) ys: List[Int] = List(2, 3, 4) scala> val ys = xs map (_ + 1) ys: List[Int] = List(2, 3, 4) scala> val zs = ys filter (_ % 2 == 0) zs: List[Int] = List(2, 4) scala> val as = ys map (0 to _) as: List(Range(0, 1, 2), Range(0, 1, 2, 3), Range(0, 1, 2, 3, 4)) 15
  • Using Collections: flatMap and groupBy scala> val bs = as.flatten bs: List[Int] = List(0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4) scala> val bs = ys flatMap (0 to _) bs: List[Int] = List(0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4) scala> val fruit = Vector("apples", "oranges", "ananas") fruit: Vector[String] = Vector(apples, oranges, ananas) scala> fruit groupBy (_.head) res11: scala.collection.immutable.Map[Char,Vector[String]] = Map(a -> Vector(apples, ananas), o -> Vector(oranges)) 16
  • Using Collections: For Notation scala> for (x <- xs) yield x + 1 res14: List[Int] = List(2, 3, 4) scala> for (x <- res14 if x % 2 == 0) yield x res15: List[Int] = List(2, 4) scala> for (x <- xs; y <- 0 to x) yield y // same as map // ~ filter // same as flatMap res17: List[Int] = List(0, 1, 0, 1, 2, 0, 1, 2, 3) 17
  • Using Maps scala> val m = Map(1 -> "ABC", 2 -> "DEF", 3 -> "GHI") m: Map[Int, String] = Map(1 -> ABC, 2 -> DEF, 3-> GHI) scala> m(2) res0: String = DEF scala> m + (4 -> "JKL") res1: Map[Int, String] = Map(1 -> ABC, 2 -> DEF, 3 -> GHI, 4 -> JKL) scala> m map { case (k, v) => (v, k) } res8: Map[String,Int] = Map(ABC -> 1, DEF -> 2, GHI -> 3) 18
  • An Example • Task: Phone keys have mnemonics assigned to them. val  mnemonics  =  Map(            '2'  -­‐>  "ABC",  '3'  -­‐>  "DEF",  '4'  -­‐>  "GHI",  '5'  -­‐>  "JKL",              '6'  -­‐>  "MNO",  '7'  -­‐>  "PQRS",  '8'  -­‐>  "TUV",  '9'  -­‐>  "WXYZ") • Assume you are given a dictionary dict as a list of words. Design a class Coder with a method translate such that new  Coder(dict).translate(phoneNumber)   produces all phrases of words in dict that can serve as mnemonics for the phone number. Example: The phone number “7225276257” should have the mnemonic Scala  rocks • as one element of the list of solution phrases. 2-19
  • Program Example: Phone Mnemonics • This example was taken from: Lutz Prechelt: An Empirical Comparison of Seven Programming Languages. IEEE Computer 33(10): 23-29 (2000) • • Tested with Tcl, Python, Perl, Rexx, Java, C++, C Code size medians: – 100 loc for scripting languages – 200-300 loc for the others 2-20
  • Outline of Class Coder import  collection.mutable.HashMap   class  Coder(words:  List[String])  {        private  val  mnemonics  =  Map(            '2'  -­‐>  "ABC",  '3'  -­‐>  "DEF",  '4'  -­‐>  "GHI",  '5'  -­‐>  "JKL",              '6'  -­‐>  "MNO",  '7'  -­‐>  "PQRS",  '8'  -­‐>  "TUV",  '9'  -­‐>  "WXYZ")                /**  Invert  the  mnemonics  map  to  give  a  map  from  chars  'A'  ...  'Z'  to  '2'  ...  '9'  */    private  val  upperCode:  Map[Char,  Char]  =  ??                        /**  Maps  a  word  to  the  digit  string  it  can  represent,  e.g.  “Java”  -­‐>  “5282”  */    private  def  wordCode(word:  String):  String  =  ??        /**  A  map  from  digit  strings  to  the  words  that  represent  them,          *  e,g.  “5282”  -­‐>  Set(“Java”,  “Kata”,  “Lava”,  ...)  */    private  val  wordsForNum:  Map[String,  Set[String]]  =  ??    /**  Return  all  ways  to  encode  a  number  as  a  list  of  words  */    def  encode(number:  String):  Set[List[String]]  =  ??             2-21
  • Class Coder  (1) import  collection.mutable.HashMap   class  Coder(words:  List[String])  {        private  val  mnemonics  =  Map(            '2'  -­‐>  "ABC",  '3'  -­‐>  "DEF",  '4'  -­‐>  "GHI",  '5'  -­‐>  "JKL",              '6'  -­‐>  "MNO",  '7'  -­‐>  "PQRS",  '8'  -­‐>  "TUV",  '9'  -­‐>  "WXYZ")                /**  Invert  the  mnemonics  map  to  give  a  map  from  chars  'A'  ...  'Z'  to  '2'  ...  '9'  */    private  val  upperCode:  Map[Char,  Char]  =                                      /**  Maps  a  word  to  the  digit  string  it  can  represent  */    private  def  wordCode(word:  String):  String  =  ??        /**  A  map  from  digit  strings  to  the  words  that  represent  them  */    private  val  wordsForNum:  Map[String,  List[String]]  =  ??    /**  Return  all  ways  to  encode  a  number  as  a  list  of  words  */    def  encode(number:  String):  Set[List[String]]  =  ??                /**  Maps  a  number  to  a  list  of  all  word  phrases  that  can  represent  it  */ 2-22
  • Class Coder  (1) 2-23
  • Class Coder  (2) 2-24
  • Class Coder  (2) 2-25
  • Class Coder  (3) 2-26
  • Class Coder  (3) 2-27
  • Class Coder  (4) class  Coder(words:  List[String])  {  ...    /**  Return  all  ways  to  encode  a  number  as  a  list  of  words  */    def  encode(number:  String):  Set[List[String]]  =        /**  Maps  a  number  to  a  list  of  all  word  phrases  that  can  represent  it  */ 2-28
  • Class Coder  (4) 2-29
  • Class Coder  (4) 2-30
  • Class Coder  (4) 2-31
  • Class Coder  (4) 2-32
  • Going Parallel 2-33
  • In Summary Problem solved with under 20 LOC Essential: Collection abstractions. Easily upgradable to parallel. Think collection transformers, not CRUD! 2-34
  • The Future Scala’s persistent collections are • easy to use: few steps to do the job • concise: one word replaces a whole loop • safe: type checker is really good at catching errors • fast: collection ops are tuned, can be parallelized • universal: one vocabulary to work on all kinds of collections 2-35
  • That was The Bright Side 36
  • Now to the Dark Side 37
  • How is all this implemented? 38
  • Everything is a Library • Collections feel like they are an organic part of Scala • But in fact the language does not contain any collectionrelated constructs – no collection types – no collection literals – no collection operators • Everything is done in a library • Everything is extensible – You can write your own collections which look and feel like the standard ones 2-39
  • Some General Scala Collections Constructed automatically using decodify. 4-40
  • Mutable or Immutable? • All general collections come in three forms, and are stored in different packages: scala.collection scala.collection.mutable scala.collection.immutable • • • Immutable is the default, i.e. predefined imports go to scala.collection.immutable General collections in scala.collection  can be mutable or immutable. There are aliases for the most commonly used collections. scala.collection.immutable.List     where it is defined scala.List               List                         the alias in the scala package because scala._ is automatically imported 4-41
  • Immutable Scala Collections 4-42
  • Mutable Scala Collections 4-43
  • New Implementations: Vectors and Hash Tries • • • • • Trees with branch factor of 32. Persistent data structures with very efficient sequential and random access. Invented by Phil Bagwell, then adopted in Clojure. New: Persistent prepend/append/update in constant amortized time. Next: Fast splits and joins for parallel transformations.
  • The Uniform Return Type Principle Bulk operations return collections of the same type (constructor) as their left operand. (DWIM) scala> val ys = List(1, 2, 3) ys: List[Int] = List(1, 2, 3) scala> val xs: Seq[Int] = ys xs: Seq[Int] = List(1, 2, 3) scala> xs map (_ + 1) res0: Seq[Int] = List(2, 3, 4) scala> ys map (_ + 1) res1: List[Int] = List(2, 3, 4) This is tricky to implement without code duplication!
  • Pre 2.8 Collection Structure trait  Iterable[A]  {      def  filter(p:  A  =>  Boolean):  Iterable[A]  =  ...    def  partition(p:  A  =>  Boolean)  =          (filter(p(_)),  filter(!p(_)))    def  map[B](f:  A  =>  B):  Iterable[B]  =  ... } trait  Seq[A]  extends  Iterable[A]  {    def  filter(p:  A  =>  Boolean):  Seq[A]  =  ...    override  def  partition(p:  A  =>  Boolean)  =          (filter(p(_)),  filter(!p(_)))    def  map[B](f:  A  =>  B):  Seq[B]  =  ... }         4-46
  • Types force duplication filter needs to be re-defined on each level partition also needs to be re-implemented on each level, even though its definition is everywhere the same. The same pattern repeats for many other operations and types. ideal conditions for Bit Rot 4-47
  • Signs of Bit Rot Lots of duplications of methods. – Methods returning collections have to be repeated for every collection type. Inconsistencies. – Sometimes methods such as filter, map were not specialized in subclasses – More often, they only existed in subclasses, even though they could be generalized “Broken window” effect. – Classes that already had some ad-hoc methods became dumping grounds for lots more. – Classes that didn’t stayed clean. 4-48
  • Excerpts from List.scala 4-49
  • How to do better? Can we abstract out the return type? Look at map: Need to abstract out the type constructor, not just the type. trait  Iterable[A]   def  map[B](f:  A  =>  B):  Iterable[B] trait  Seq[A]   def  map[B](f:  A  =>  B):  Seq[B]   But we can do that using Scala’s higher-kinded types!
  • HK Types Collection Structure trait  TraversableLike[A,  CC[X]]  {      def  filter(p:  A  =>  Boolean):  CC[A]    def  map[B](f:  A  =>  B):  CC[B] } trait  Traversable[A]  extends  TraversableLike[A,  Traversable] trait  Iterable[A]        extends  TraversableLike[A,  Iterable] trait  Seq[A]                  extends  TraversableLike[A,  Seq] Here, CC is a parameter representing a type constructor.
  • Implementation with Builders All ops in Traversable are implemented in terms of foreach and newBuilder. trait  Builder[A,  Coll]  {    def  +=  (elem:  A)      //  add  elems    def  result:  Coll      //  return  result } trait  TraversableLike[A,  CC[X]]  {    def  foreach(f:  A  =>  Unit)    def  newBuilder[B]:  Builder[B,  CC[B]]    def  map[B](f:  A  =>  B):  CC[B]  =  {        val  b  =  newBuilder[B]        foreach  (x  =>  b  +=  f(x))        b.result    } }
  • Unfortunately ... ... things are not as parametric as it seems at first. Take: class  BitSet  extends  Set[Int] scala>  val  bs  =  BitSet(1,  2,  3) bs:  scala.collection.immutable.BitSet  =  BitSet(1,  2,  3) scala>  bs  map  (_  +  1) res0:  scala.collection.immutable.BitSet  =  BitSet(2,  3,  4) scala>  bs  map  (_.toString  +  "!") res1:  scala.collection.immutable.Set[java.lang.String]  =  Set(1!,  2!,  3!) Note that the result type is the “best possible” type that fits the element type of the new collection. Other examples: SortedSet,  String, Array
  • How to advance? We need more flexibility. Can we define our own type system for collections? Question: Given old collection type From, new element type Elem, and new collection type To: Can an operation on From build a collection of type To with Elem elements? Captured in: CanBuildFrom[From,  Elem,  To]
  • Facts about CanBuildFrom Can be stated as axioms and inference rules: CanBuildFrom[Traversable[A],  B,  Traversable[B]]     CanBuildFrom[Set[A],  B,  Set[B]] CanBuildFrom[BitSet,  B,  Set[B]] CanBuildFrom[BitSet,  Int,  BitSet] CanBuildFrom[String,  Char,  String] CanBuildFrom[String,  B,  Seq[B]] CanBuildFrom[SortedSet[A],  B,  SortedSet[B]]    :-­‐    Ordering[B] where A and B are arbitrary types.
  • Objections 4-58
  • 4-59
  • Use Cases • How to explain def  map[B,  To](f:  A  =>  B)                                            (implicit  cbf:  CanBuildFrom[Coll,  B,  To]):  To • • to a beginner? Key observation: We can approximate the type of map. For everyone but the most expert user   def  map[B](f:  A  =>  B):  Traversable[B]    //  in    class  Traversable def  map[B](f:  A  =>  B):  Seq[B]                    //  in    class  Seq,  etc • is detailed enough. These types are correct, they are just not as general as the type that’s actually implemented. 4-60
  • Part of the Solution: Flexible Doc Comments 4-61
  • Going even further But how do we keep a bunch of Fermi’s happy? – How to find and deal with 10000+ threads in an application? – Parallel collections are necessary but not sufficient for this. Our bet for the far future: parallel embedded DSLs. – Find parallelism in domains: physics simulation, machine learning, statistics, ... Joint work with Kunle Olukuton, Pat Hanrahan @ Stanford. 63
  • Producer or Consumer? Scala feels radically different for producers and consumers of advanced libraries. For the consumer: – Really easy – Things work intuitively – Can concentrate on domain, not implementation For the producer: – Sophisticated tool set – Can push the boundaries of what’s possible – Requires expertise and taste 64
  • How to find out more Series: “What’s new Scala 2.8?” on scala-lang.org and artima.com Programming in Scala 2nd ed 65
  • Thank You 66

Comments

Be the first one to add a comment

Thumbnail for: Refactoring to Functional (slides only)

Refactoring to Functional (slides only)

Hadi Hariri

subscription
Thumbnail for: 10 NoSQL databases you have to know

10 NoSQL databases you have to know

Tom Bujok

subscription
Thumbnail for: Functional Programming: Technical Reasons to Adapt (slides only)

Functional Programming: Technical Reasons to Adapt (slides only)

Venkat Subramaniam

subscription
Thumbnail for: What's New in WildFly 9

What's New in WildFly 9

Tomasz Adamski

subscription
Thumbnail for: PubSub++ - few tips that make your life with kafka easier. (slides only)

PubSub++ - few tips that make your life with kafka easier. (slides only)

Krzysztof Debski

subscription
Thumbnail for: Apache Spark - when things go wrong (slides only)

Apache Spark - when things go wrong (slides only)

Paweł Szulc

subscription
Thumbnail for: My running shoes - Continuous Delivery

My running shoes - Continuous Delivery

Grzegorz Krumpholz

subscription
Thumbnail for: Vaadin Designer, the visual design tool for modern web apps

Vaadin Designer, the visual design tool for modern web apps

Maciej Przepióra

subscription
Thumbnail for: Effective SCRUM in distributed teams (slides only)

Effective SCRUM in distributed teams (slides only)

Rafał Udziela

subscription
Thumbnail for: Get Past the Syntax, The Real Scare is in the Semantics

Get Past the Syntax, The Real Scare is in the Semantics

Venkat Subramaniam

subscription
Thumbnail for: Ścisły przewodnik po aspektach miękkich - część II: Jesteś ekspertem i co dalej? (slides only)

Ścisły przewodnik po aspektach miękkich - część II: Jesteś ekspertem i co dalej? (slides only)

Slawomir Sobotka

free
Thumbnail for: Flavors of Concurrency in Java

Flavors of Concurrency in Java

OLEG ŠELAJEV

free
Thumbnail for: Coding Culture

Coding Culture

Sven Peters

free
Thumbnail for: The end of server management : hosting have to become a commodity (slides only)

The end of server management : hosting have to become a commodity (slides only)

Quentin ADAM

subscription
Thumbnail for: Software architecture as code

Software architecture as code

Simon Brown

subscription
Thumbnail for: Modern Web Architecture

Modern Web Architecture

Ted Neward

subscription
Thumbnail for: HTTP/2 : why upgrading the web? (slides only)

HTTP/2 : why upgrading the web? (slides only)

Quentin ADAM

subscription
Thumbnail for: Failing Continuous Delivery (slides only)

Failing Continuous Delivery (slides only)

Daniel Sawano , Daniel Deogun

subscription
Thumbnail for: A Gentle and useful introduction to Reactive Extensions (slides only)

A Gentle and useful introduction to Reactive Extensions (slides only)

Hadi Hariri

subscription
Thumbnail for: Scalable Is Awesome, Literally! (slides only)

Scalable Is Awesome, Literally! (slides only)

Garrett Smith

subscription
Thumbnail for: From Docker To Kubernetes: A Developer's Guide To Containers (slides only)

From Docker To Kubernetes: A Developer's Guide To Containers (slides only)

Marek Grabowski

subscription
Thumbnail for: Kill the mutants, test your tests

Kill the mutants, test your tests

Roy van Rijn

subscription
Thumbnail for: Unlocking the magic of monads in Java 8

Unlocking the magic of monads in Java 8

OLEG ŠELAJEV

subscription
Thumbnail for: Lazy Evaluations (slides only)

Lazy Evaluations (slides only)

Venkat Subramaniam

subscription
Thumbnail for: Make sense of your (BIG) data! (slides only)

Make sense of your (BIG) data! (slides only)

David Pilato

subscription
Thumbnail for: Painfree Object-Document Mapping for MongoDB

Painfree Object-Document Mapping for MongoDB

Philipp Krenn

subscription
Thumbnail for: Core Software Design Principles for Programmers (slides only)

Core Software Design Principles for Programmers (slides only)

Venkat Subramaniam

subscription
Thumbnail for: Reviewing Architectures

Reviewing Architectures

Nathaniel Schutta

subscription
Thumbnail for: Clean Architecture - how to improve your system architecture

Clean Architecture - how to improve your system architecture

Andrzej Bednarz

subscription
Thumbnail for: Principles Of Microservices

Principles Of Microservices

Sam Newman

subscription
Thumbnail for: Caching reboot: javax.cache & Ehcache 3 (slides only)

Caching reboot: javax.cache & Ehcache 3 (slides only)

Louis Jacomet

subscription
Thumbnail for: Microservices and Conversion Hunting - How to build software architectures for changeableness (slides only)

Microservices and Conversion Hunting - How to build software architectures for changeableness (slides only)

Bernd Zuther

subscription
Thumbnail for: Microservices - enough with theory, let's code some (slides only)

Microservices - enough with theory, let's code some (slides only)

Marcin Grzejszczak , Tomasz Szymanski

subscription
Thumbnail for: User Acceptance Testing - Looking for the Holly Grail (slides only)

User Acceptance Testing - Looking for the Holly Grail (slides only)

Boguslaw Osuch

subscription
Thumbnail for: Vagrant up your enviroment (slides only)

Vagrant up your enviroment (slides only)

Yann Larrivee

subscription
Thumbnail for: Scala and Clojure: Playing well together

Scala and Clojure: Playing well together

David Pollak

subscription
Thumbnail for: The Silver Bullet Syndrome (slides only)

The Silver Bullet Syndrome (slides only)

Hadi Hariri

subscription
Thumbnail for: Security Platform as a Service with Docker and Weave

Security Platform as a Service with Docker and Weave

David Pollak

subscription
Thumbnail for: The Go Language (slides only)

The Go Language (slides only)

Brad Fitzpatrick

subscription
Thumbnail for: Functional Data Storage (slides only)

Functional Data Storage (slides only)

Greg Young

subscription
Thumbnail for: Event Sourcing & Functional Programming - a pair made in heaven

Event Sourcing & Functional Programming - a pair made in heaven

Paweł Szulc

subscription
Thumbnail for: Refactoring meets big money

Refactoring meets big money

Michal Gruca

subscription
Thumbnail for: What's new in Spring Data? (slides only)

What's new in Spring Data? (slides only)

Thomas Darimont

subscription
Thumbnail for: Functional patterns for scala beginners (slides only)

Functional patterns for scala beginners (slides only)

Clément Delafargue

subscription
Thumbnail for: Babun - a Windows shell you will love, finally! (slides only)

Babun - a Windows shell you will love, finally! (slides only)

Tom Bujok , Lukasz Pielak

subscription
Thumbnail for: IDE Wizard? CLI Command? Get both for the price of one! (slides only)

IDE Wizard? CLI Command? Get both for the price of one! (slides only)

Koen Aers

subscription

BigData on Azure for architects – Machine Learning, HDInsight (Hadoop), Event Hub – what to use when (and – how) (slides only)

Tomasz Kopacz

subscription
Thumbnail for: Hystrix – managing failures in distributed systems (slides only)

Hystrix – managing failures in distributed systems (slides only)

Tomasz Nurkiewicz

subscription
Thumbnail for: Deep dive into Reactive Java

Deep dive into Reactive Java

Tomasz Kowalczewski

subscription
Thumbnail for: Nashorn, what is the whole buzz about

Nashorn, what is the whole buzz about

Michal Gruca

subscription
Thumbnail for: Things about microservices you wish you never knew

Things about microservices you wish you never knew

Marek Ko-w

subscription
Thumbnail for: "Bootiful" Microservices with Spring Cloud

"Bootiful" Microservices with Spring Cloud

Josh Long

subscription
Thumbnail for: Is your profiler speaking the same language as you? (slides only)

Is your profiler speaking the same language as you? (slides only)

Simon Maple

subscription
Thumbnail for: Agile Development Meets Connected Devices - Lessons Learned

Agile Development Meets Connected Devices - Lessons Learned

subscription
Thumbnail for: Distributed algorithms for Big Data (slides only)

Distributed algorithms for Big Data (slides only)

DuyHai DOAN

subscription
Thumbnail for: JRebel under the covers - how is it even possible? (slides only)

JRebel under the covers - how is it even possible? (slides only)

Simon Maple

subscription
Thumbnail for: Case Study: Agile @gov.pl (slides only)

Case Study: Agile @gov.pl (slides only)

Matt Harasymczuk

subscription
Thumbnail for: Ansible to rule them all – o provisioningu i deploymencie aplikacji Java

Ansible to rule them all – o provisioningu i deploymencie aplikacji Java

Wojciech Podgorski , Rafal Piotrowski

subscription
Thumbnail for: Supler: complex web forms, not so complex

Supler: complex web forms, not so complex

Adam Warski , Tomasz Szymanski

subscription
Thumbnail for: Deploying Microservice Architectures with Spring Cloud on Cloud Foundry

Deploying Microservice Architectures with Spring Cloud on Cloud Foundry

Pieter Humphrey

subscription
Thumbnail for: 5-10-15 years with Java - from junior to master and back again (slides only)

5-10-15 years with Java - from junior to master and back again (slides only)

Wojciech Seliga

subscription
Thumbnail for: "Bootiful" Applications with Spring Boot

"Bootiful" Applications with Spring Boot

Josh Long

subscription
Thumbnail for: You're an Architect...Now What?

You're an Architect...Now What?

Nathaniel Schutta

subscription
Thumbnail for: Co było pierwsze: kod czy architektura? (slides only)

Co było pierwsze: kod czy architektura? (slides only)

Slawomir Sobotka

subscription
Thumbnail for: From API to protocol (slides only)

From API to protocol (slides only)

Quentin ADAM

subscription
Thumbnail for: Everything Works In Java EE?--Then Try Microservices :-) (slides only)

Everything Works In Java EE?--Then Try Microservices :-) (slides only)

Adam Bien

subscription
Thumbnail for: OAuth2 for native apps and beyond (slides only)

OAuth2 for native apps and beyond (slides only)

Erik Jan de Wit

subscription
Thumbnail for: Building an Asynchronous Reactive NoSQL SDK with RxJava

Building an Asynchronous Reactive NoSQL SDK with RxJava

Simon Baslé

subscription
Thumbnail for: Agile Project Management Anti-Patterns (slides only)

Agile Project Management Anti-Patterns (slides only)

Kasia Mrowca

subscription
Thumbnail for: What's Coming in Java EE 8

What's Coming in Java EE 8

Reza Rahman

subscription
Thumbnail for: WebVR - democracy in Virtual Reality

WebVR - democracy in Virtual Reality

Marcin Lichwala

subscription
Thumbnail for: Why software developers should care about deployment and monitoring

Why software developers should care about deployment and monitoring

Michał Kosmulski

subscription
Thumbnail for: Social Coding - tools and techniques

Social Coding - tools and techniques

Maciej Pleśnar

subscription
Thumbnail for: Applications secure by default (slides only)

Applications secure by default (slides only)

Sławomir Jasek

subscription
Thumbnail for: Busy Java Developer’s Guide to Three REST API Frameworks (slides only)

Busy Java Developer’s Guide to Three REST API Frameworks (slides only)

Ted Neward

subscription
Thumbnail for: High Performance JavaScript Web Apps

High Performance JavaScript Web Apps

Pratik Patel

subscription
Thumbnail for: JCP, Adopt-a-JSR & You

JCP, Adopt-a-JSR & You

Reza Rahman

subscription
Thumbnail for: The Smartwatch Revolution begins: Developing for Android Wear (slides only)

The Smartwatch Revolution begins: Developing for Android Wear (slides only)

Pratik Patel

subscription
Thumbnail for: Wykorzystanie podejścia Domain-Driven Design w systemach legacy (slides only)

Wykorzystanie podejścia Domain-Driven Design w systemach legacy (slides only)

Piotr Wyczesany

subscription
Thumbnail for: Apache Cassandra 101 (slides only)

Apache Cassandra 101 (slides only)

Christopher Batey

subscription
Thumbnail for: The Creative Networker

The Creative Networker

Jurgen Appelo

subscription
Thumbnail for: Using JavaScript/HTML5 Rich Clients with Java EE 7 (slides only)

Using JavaScript/HTML5 Rich Clients with Java EE 7 (slides only)

Reza Rahman

subscription
Thumbnail for: From Docker To Kubernetes: A Developer's Guide To Containers (slides only)

From Docker To Kubernetes: A Developer's Guide To Containers (slides only)

Marek Grabowski

subscription
Thumbnail for: Lessons learned from scaling software

Lessons learned from scaling software

Bartek Nowakowski

subscription
Thumbnail for: Everybody lies

Everybody lies

Tomasz Kowalczewski

free
Thumbnail for: Clean JavaScript code - only dream or reality (slides only)

Clean JavaScript code - only dream or reality (slides only)

Sebastian Łaciak

subscription
Thumbnail for: React.js: Super-fast Single Page Web Applications (slides only)

React.js: Super-fast Single Page Web Applications (slides only)

Pratik Patel

subscription
Thumbnail for: Building fault tolerant microservices

Building fault tolerant microservices

Christopher Batey

subscription
Thumbnail for: Modern Java Component Design with Spring 4.2

Modern Java Component Design with Spring 4.2

Juergen Hoeller

subscription
Thumbnail for: Designing software with security in mind? (slides only)

Designing software with security in mind? (slides only)

Daniel Deogun

subscription
Thumbnail for: From spaghetti with no src/test to green CI, good coverage and well-sleeping developers (slides only)

From spaghetti with no src/test to green CI, good coverage and well-sleeping developers (slides only)

Michał Matłoka , Jacek Kunicki

subscription
Thumbnail for: Technical leadership – from an expert to a leader

Technical leadership – from an expert to a leader

Mariusz Sieraczkiewicz

subscription
Thumbnail for: Modularity in post microservice world

Modularity in post microservice world

Michal Gruca

subscription
Thumbnail for: Level up your dev skills with static analysis

Level up your dev skills with static analysis

David Lindsay

subscription
Thumbnail for: Why I love Logstash and you should too. (slides only)

Why I love Logstash and you should too. (slides only)

João Duarte

subscription
Thumbnail for: Java Bytecode Explained (slides only)

Java Bytecode Explained (slides only)

OLEG ŠELAJEV

subscription
Thumbnail for: Corporate startup and Scala (slides only)

Corporate startup and Scala (slides only)

Filip Rogaczewski

subscription
Thumbnail for: Need for Async: In hot pursuit of internet-scale app architectures

Need for Async: In hot pursuit of internet-scale app architectures

Konrad Malawski

subscription
Thumbnail for: Groovier BDD with Spock (slides only)

Groovier BDD with Spock (slides only)

Michał Kordas

subscription
Thumbnail for: Building systems that are #neverdone

Building systems that are #neverdone

James Lewis

subscription
Thumbnail for: OnConnectionLost: The life of an offline web application

OnConnectionLost: The life of an offline web application

Stefanie Grewenig , Johannes Thönes

subscription