Just enough computer science for the busy developer

#enoughcs

Just enough computer science for the busy developer

#enoughcs

.

Why

Diversity matters

Science matters

If you remember only 1 thing

De Morgan’s Laws

Mathy version

 ¬(a ⋁ b) ≡ ¬a ⋀ ¬b
 ¬(a ⋀ b) ≡ ¬a ⋁ ¬b

De Morgan’s Laws

Java version

!(a || b) == !a && !b
!(a && b) == !a || !b

For example

if (!(product.price() <= 10 || order.amount() <= 5)) {
  applyDiscount();
}

For example

if (!(a || b)) {
  applyDiscount();
}
a = product.price() <= 10
b = order.amount <= 5

For example

if (!a && !b) {
  applyDiscount();
}
a = product.price() <= 10
b = order.amount <= 5

For example

if (!(product.price() <= 10) && !(order.amount() <= 5)) {
  applyDiscount();
}

For example

if (product.price() > 10 && order.amount() > 5) {
  applyDiscount();
}

Real talk

Truth table

a b !(a || b) !a && !b
0 0 1 1
0 1 0 0
1 0 0 0
1 1 0 0

Truth table

a b !(a && b) !a || !b
0 0 1 1
0 1 1 1
1 0 1 1
1 1 0 0

If you remember only 2 things

Jan Ouwens

 

EqualsVerifierjqno.nl jqno

#enoughcs

I studied

computer science

 

so you don’t have to

Lots of interesting people

Edsger Dijkstra

1930 - 2002

Edsger Dijkstra

“Testing shows the presence, not the absence of bugs.”

Edsger Dijkstra

“The question of whether machines can think is about as relevant
as the question of whether submarines can swim.”

Edsger Dijkstra

“The teaching of BASIC should be rated as a criminal offence:
it mutilates the mind beyond recovery.”

Lots of interesting history

George Boole

1815 - 1864

Jacquard Loom

1804

Charles Babbage & Ada Lovelace

1791 - 1871                          1815 - 1852

Programming was considered a women’s job

ENIAC

1945 - 1955

Modern supercomputer

present day

Lots of interesting science

Tony Hoare

1934 -

Tony Hoare

“I call it my billion-dollar mistake.
It was the invention of the null reference in 1965.”

Precondition + Postcondition

   {Precondition}
    Statement
   {Postcondition}

Precondition + Postcondition

   {x = 3}
    x += 1;
   {x = 4}

Q.E.D.

Linear Search

Linear Search

Linear Search

Linear Search

Linear Search

Linear Search

  int[] haystack = ...;
  int needle = ...;
  
  
  int i = 0;
  
  while (haystack[i] != needle) {
  
    i += 1;
  
  }

Linear Search

  var b: array[0..N] of int = ...;
  var n: int = ...;


  i := 0

; do b[i] ≠ n →

    i := i + 1

  od

Linear Search

  var b: array[0..N] of int = ...;
  var n: int = ...;

  { ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
  i := 0

; do b[i] ≠ n →

    i := i + 1

  od

Linear Search

  var b: array[0..N] of int = ...;
  var n: int = ...;

  { ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
  i := 0
  { i = 0 ⋀ ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
; do b[i] ≠ n →

    i := i + 1

  od

Linear Search

  var b: array[0..N] of int = ...;
  var n: int = ...;

  { ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
  i := 0
  { i = 0 ⋀ ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
; do b[i] ≠ n →
    { 0 ≤ i < N ⋀ ⟨∀x : 0 ≤ x ≤ i : b[x] ≠ n⟩ ⋀ ⟨∃x : i < x < N : b[x] = n⟩ }
    i := i + 1

  od

Linear Search

  var b: array[0..N] of int = ...;
  var n: int = ...;

  { ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
  i := 0
  { i = 0 ⋀ ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
; do b[i] ≠ n →
    { 0 ≤ i < N ⋀ ⟨∀x : 0 ≤ x ≤ i : b[x] ≠ n⟩ ⋀ ⟨∃x : i < x < N : b[x] = n⟩ }
    i := i + 1
    { 0 < i < N ⋀ ⟨∀x : 0 ≤ x < i : b[x] ≠ n⟩ ⋀ ⟨∃x : i ≤ x < N : b[x] = n⟩ }
  od

Linear Search

  var b: array[0..N] of int = ...;
  var n: int = ...;

  { ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
  i := 0
  { i = 0 ⋀ ⟨∃x : 0 ≤ x < N : b[x] = n⟩ }
; do b[i] ≠ n →
    { 0 ≤ i < N ⋀ ⟨∀x : 0 ≤ x ≤ i : b[x] ≠ n⟩ ⋀ ⟨∃x : i < x < N : b[x] = n⟩ }
    i := i + 1
    { 0 < i < N ⋀ ⟨∀x : 0 ≤ x < i : b[x] ≠ n⟩ ⋀ ⟨∃x : i ≤ x < N : b[x] = n⟩ }
  od
  { 0 ≤ i < N ⋀ b[i] = n ⋀ ⟨∀x : 0 ≤ x < i : b[x] ≠ n⟩ }

Q.E.D.

What it looked like for me

Algorithm

Proving algorithms is hard

Speaking of algorithms

محمد خوارزمی

? - 850

Muhammad al-Khwarizmi

? - 850

Algorithmi

? - 850

Algorithm

We live in an

age of libraries

Libraries

Implement an algorithm

Libraries

Implement an algorithm

Prove an algorithm

Libraries

Implement an algorithm

Prove an algorithm

Test an algorithm

Libraries

Implement an algorithm

Prove an algorithm

Test an algorithm

Choose an algorithm

how?

Have someone do it for you

Katherine Johnson

1918 - 2020

Katherine Johnson

2016

Linear Search

Linear Search

Binary Search

Binary Search

Binary Search

Binary Search

Binary Search

Binary Search

public static int binarySearch(Comparable[] a, Object key) {
    int low = 0;
    int high = a.length - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int cmp = a[mid].compareTo(key);
        if (cmp < 0)
            low = mid + 1;
        else if (cmp > 0)
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found
}

Source: Java APIs, but simplified

Binary Search

Proving algorithms is hard

Git bisect

Git bisect

Git bisect

Git bisect

Git bisect

Git bisect

Git bisect

Git bisect

❯ ~/my-project ❯ main ❯ git log
13439df  (HEAD -> main) updates dependencies
a50dab8  processes review comments
24908d8  applies formatting
3b6483a  extracts local variable
ebf5221  adds tests
cdfe9ed  replaces MySQL with BlockChain Technology™
77590b0  fixes typo
a0be795  fixes bug
99dc85b  updates README





Git bisect

❯ ~/my-project ❯ main ❯ git log
13439df  (HEAD -> main) updates dependencies
a50dab8  processes review comments
24908d8  applies formatting
3b6483a  extracts local variable
ebf5221  adds tests
cdfe9ed  replaces MySQL with BlockChain Technology™
77590b0  fixes typo
a0be795  fixes bug
99dc85b  updates README

❯ ~/my-project ❯ main ❯ git checkout 99dc85b9



Git bisect

❯ ~/my-project ❯ main ❯ git log
13439df  (HEAD -> main) updates dependencies
a50dab8  processes review comments
24908d8  applies formatting
3b6483a  extracts local variable
ebf5221  adds tests
cdfe9ed  replaces MySQL with BlockChain Technology™
77590b0  fixes typo
a0be795  fixes bug
99dc85b  updates README

❯ ~/my-project ❯ main ❯ git checkout 99dc85b9

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect start

Git bisect

13439df  (HEAD -> main) updates dependencies
a50dab8  processes review comments
24908d8  applies formatting
3b6483a  extracts local variable
ebf5221  adds tests
cdfe9ed  replaces MySQL with BlockChain Technology™
77590b0  fixes typo
a0be795  fixes bug
99dc85b  updates README

❯ ~/my-project ❯ main ❯ git checkout 99dc85b9

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect start

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect good

Git bisect

ebf5221  adds tests
cdfe9ed  replaces MySQL with BlockChain Technology™
77590b0  fixes typo
a0be795  fixes bug
99dc85b  updates README

❯ ~/my-project ❯ main ❯ git checkout 99dc85b9

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect start

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect good

❯ ~/my-project ❯ @99dc85b9 ❯ git checkout main
Previous HEAD position was 99dc85b updates README
Switched to branch 'main'

Git bisect

99dc85b  updates README

❯ ~/my-project ❯ main ❯ git checkout 99dc85b9

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect start

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect good

❯ ~/my-project ❯ @99dc85b9 ❯ git checkout main
Previous HEAD position was 99dc85b updates README
Switched to branch 'main'

❯ ~/my-project ❯ main ❯ git bisect bad
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[ebf5221] adds tests

Git bisect

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect start

❯ ~/my-project ❯ @99dc85b9 ❯ git bisect good

❯ ~/my-project ❯ @99dc85b9 ❯ git checkout main
Previous HEAD position was 99dc85b updates README
Switched to branch 'main'

❯ ~/my-project ❯ main ❯ git bisect bad
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[ebf5221] adds tests

❯ ~/my-project ❯ @ebf52218 ❯ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[77590b0] fixes typo

Git bisect

❯ ~/my-project ❯ @99dc85b9 ❯ git checkout main
Previous HEAD position was 99dc85b updates README
Switched to branch 'main'

❯ ~/my-project ❯ main ❯ git bisect bad
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[ebf5221] adds tests

❯ ~/my-project ❯ @ebf52218 ❯ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[77590b0] fixes typo

❯ ~/my-project ❯ @77590b0d ❯ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[cdfe9ed] replaces MySQL with BlockChain Technology™

Git bisect

❯ ~/my-project ❯ @ebf52218 ❯ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[77590b0] fixes typo

❯ ~/my-project ❯ @77590b0d ❯ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[cdfe9ed] replaces MySQL with BlockChain Technology™

❯ ~/my-project ❯ @cdfe9ed1 ❯ git bisect bad
cdfe9ed1f1f8ad11ec48703e90d482996322ad1a is the first bad commit
commit cdfe9ed1f1f8ad11ec48703e90d482996322ad1a
Author: Jan Ouwens <jan.ouwens@example.com>
Date:   Mon Mar 7 10:19:22 2022 +0100

    replaces MySQL with BlockChain Technology™

Git bisect

[77590b0] fixes typo

❯ ~/my-project ❯ @77590b0d ❯ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[cdfe9ed] replaces MySQL with BlockChain Technology™

❯ ~/my-project ❯ @cdfe9ed1 ❯ git bisect bad
cdfe9ed1f1f8ad11ec48703e90d482996322ad1a is the first bad commit
commit cdfe9ed1f1f8ad11ec48703e90d482996322ad1a
Author: Jan Ouwens <jan.ouwens@example.com>
Date:   Mon Mar 7 10:19:22 2022 +0100

    replaces MySQL with BlockChain Technology™

❯ ~/my-project ❯ @ebf52218 ❯ git bisect reset

Better than Linear Search!

Let’s look at the fundamentals

Hedy Lamarr

1914 - 2000

Complexity

How many steps?

Let’s define


N = input size

Complexity

public int linearSearch(int needle, int[] haystack) {
  for (int i : haystack) {
    if (haystack[i] == needle) {
      return true;
    }
  }
  return false;
}

N steps

Complexity

public int get(int[] ints, int index) {
  return ints[index];
}

1 step

Complexity

public boolean hasDuplicates(int[] ints) {
  for (int i : ints) {
    for (int j : ints) {
      if (i != j && ints[i] == ints[j]) {
        return true;
      }
    }
  }
  return false;
}

N2 steps

Complexity

public int fibonacci(int i) {
  if (i <= i) {
    return i;
  }
  return fibonacci(i - 2) + fibonacci(i - 1);
}

2N steps

Complexity

Brute-forcing travelling salesman

N! steps

Complexity

Binary search

log2 N steps

Complexity

Binary search

log2 N steps

🤔🤔🤔

Complexity

Binary search

Way less than N steps

Abstraction

over complexity

Donald Knuth

1938 -

Donald Knuth

“Beware of bugs in the above code;
I have only proved it correct, not tried it.”

Donald Knuth

“Premature optimization is the root of all evil.”

The full quote


“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.”

Book

Book

Big O notation

steps Big O
1 O(1)
log N O(log N)
N O(N)
N2 O(N2)
2N O(2N)

Big O notation

steps Big O
2N O(N)
42N2 + 2N + 3 O(N2)
log2 N O(log N)

Big O notation

N 2 10 100 1000
O(1) 1 1 1 1
O(log N) 1 3,3 6,6 10
O(N) 1 10 100 1000
O(N2) 1 100 10.000 1.000.000
O(2N) 2 1024 1,2×1030 1,1×10301
O(N!) 1 3.628.800 9,3×10157 🤯

Big O notation

Big O notation

N name
O(1) constant
O(log N) logarithmic
O(N) linear
O(N2) quadratic
O(2N) exponential
O(N!) factorial

Big O notation

N
O(1)
O(log N)
O(N)
O(N2) ↑ Polynomial
O(2N) ↓ Slow
O(N!)

Why do we care about this?

Alan Turing

1912 - 1954

Alan Turing

2014

Disclaimer

Cracking codes

worse than polynomial

Verifying codes

polynomial

NP

  • nondeterministic-polynomial”

  • finding an answer: slow

  • checking an answer: P

NP

  • Rubik’s cube
  • Sudoku
  • Logistics
  • Bitcoin

NP

Obviously, P ≠ NP

jè.

Depending on P≠NP

  • banking
  • secure messaging
  • society as a whole

In practice

Grace Hopper

1906 - 1992

Know the big O of your algorithms

Know your

data structures

Array

Array

Array

Array

operation big O
access O(1)
search O(N)
prepend O(N)
append O(1)

Linked list

Linked list

Linked list

operation big O
access O(N)
search O(N)
prepend O(1)
append O(N)

Hash map

Hash map

Hash map

operation big O
access n/a
search O(1)
iteration O(N)
insert O(1)

How do I do this in Java?

James Gosling

1955 -

Data structures

Data structures in Java

  • ArrayList
  • LinkedList
  • CopyOnWriteArrayList
  • Stack
  • Vector

Data structures in Java

  • HashMap
  • EnumMap
  • LinkedHashMap
  • SortedMap
  • TreeMap

Data structures in Java

  • HashSet
  • EnumSet
  • LinkedHashSet
  • SortedSet
  • TreeSet

Data structures in Java

  • Queue
  • Deque

Immutable collections

Vavr, Eclipse Collections, Guava

Variable declaration

Variable declaration

No:

ArrayList<String> myList = new ArrayList<>();

Variable declaration

Yes:

     List<String> myList = new ArrayList<>();

Variable declaration

Yes:

     List<String> myList = new LinkedList<>();

Variable declaration

Yes:

     List<String> myList = new CopyOnWriteArrayList<>();

Equality

Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters


}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");





Equality

Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters


}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");





Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters
    // no equals!

}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");

cs1.equals(cs2) // false



Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters
    public boolean equals(Object obj) { ... }

}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");

cs1.equals(cs2) // true 🥳



Equality

Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters
    public boolean equals(Object obj) { ... }

}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");

cs1.equals(cs2) // true 🥳



Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters
    public boolean equals(Object obj) { ... }
    // no hashCode!
}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");

cs1.equals(cs2) // true 🥳

cs1.hashCode()  // 253
cs2.hashCode()  // 875

Equality

class ComputerScientist {
    private final String name;

    // constructor, getters & setters
    public boolean equals(Object obj) { ... }
    public int hashCode() { ... }
}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");

cs1.equals(cs2) // true 🥳

cs1.hashCode()  // 253
cs2.hashCode()  // 253 🥳

Equality

Equality

Override equals?

Equality

Override equals and hashCode!

The bigger picture

Margaret Hamilton

1936 -

Margaret Hamilton

2017

Software engineering

  • Programming
  • Analysis
  • Architecture
  • UX design
  • Testing
  • Computer science

Software engineering

If you remember only 3 things

Software engineering

It depends

Big O notation

Big O notation

Big O notation

Readability

 🙂 Set<T> set;
 🧐 LinkedHashSet<T> set;

Let’s

wrap up

Neumann János Lajos

1903 - 1957

John von Neumann

1903 - 1957

Recap

Thing 1:

De Morgan’s Laws

Recap

Thing 2:

Truth tables

Recap

Thing 3:

It depends

Recap

Algorithms

Recap

Linear Search

Recap

Binary Search

Recap

Complexity

& Big O

Choose wisely

Recap

Data structures

Choose wisely

Recap

Hash-based algorithms?

Implement equals and hashCode

Now you know enough CS!

What’s next?

What’s next?


Keep this stuff in the back of your mind

What’s next?


Look it up when you need to decide


Tip: Google “Big O cheat sheet”

What’s next?

What’s next?


Experiment

What’s next?


Experiment


Tip:
Implement your own HashMap!

What’s next?


Experiment


Advanced tip:
Implement your own compression algorithm!

Questions?


jqno.nl/talks/enoughcs

#enoughcs

image credits: see website