#enoughcs
#enoughcs
.
Why
Diversity matters
Science matters
If you remember only 1 thing
Mathy version
¬(a ⋁ b) ≡ ¬a ⋀ ¬b
¬(a ⋀ b) ≡ ¬a ⋁ ¬b
Java version
!(a || b) == !a && !b
!(a && b) == !a || !b
if (!(product.price() <= 10 || order.amount() <= 5)) {
applyDiscount();
}
if (!(a || b)) {
applyDiscount();
}
a = product.price() <= 10
b = order.amount <= 5
if (!a && !b) {
applyDiscount();
}
a = product.price() <= 10
b = order.amount <= 5
if (!(product.price() <= 10) && !(order.amount() <= 5)) {
applyDiscount();
}
if (product.price() > 10 && order.amount() > 5) {
applyDiscount();
}
a |
b |
!(a || b) |
!a && !b |
---|---|---|---|
0 | 0 | 1 | 1 |
0 | 1 | 0 | 0 |
1 | 0 | 0 | 0 |
1 | 1 | 0 | 0 |
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
│ EqualsVerifier │ jqno.nl │ jqno
#enoughcs
I studied
computer science
so you don’t have to
Lots of interesting people
1930 - 2002
“Testing shows the presence, not the absence of bugs.”
“The question of whether machines can think is about as relevant
as the question of whether submarines can swim.”
“The teaching of BASIC should be rated as a criminal offence:
it mutilates the mind beyond recovery.”
Lots of interesting history
1815 - 1864
1804
1791 - 1871 1815 - 1852
Programming was considered a women’s job
1945 - 1955
present day
Lots of interesting science
1934 -
“I call it my billion-dollar mistake.
It was the invention of the null reference in 1965.”
{Precondition}
Statement
{Postcondition}
{x = 3}
x += 1;
{x = 4}
Q.E.D.
Linear Search
int[] haystack = ...;
int needle = ...;
int i = 0;
while (haystack[i] != needle) {
i += 1;
}
var b: array[0..N] of int = ...;
var n: int = ...;
i := 0
; do b[i] ≠ n →
i := i + 1
od
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
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
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
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
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.
Algorithm
Proving algorithms is hard
Speaking of algorithms
? - 850
? - 850
? - 850
Algorithm
We live in an
age of libraries
Implement an algorithm
Implement an algorithm
Prove an algorithm
Implement an algorithm
Prove an algorithm
Test an algorithm
Implement an algorithm
Prove an algorithm
Test an algorithm
Choose an algorithm
how?
Have someone do it for you
1918 - 2020
2016
Linear 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
Proving algorithms is hard
❯ ~/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 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 ❯ 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
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
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'
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
❯ ~/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
❯ ~/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™
❯ ~/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™
[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
1914 - 2000
Complexity
How many steps?
N = input size
public int linearSearch(int needle, int[] haystack) {
for (int i : haystack) {
if (haystack[i] == needle) {
return true;
}
}
return false;
}
N steps
public int get(int[] ints, int index) {
return ints[index];
}
1 step
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
public int fibonacci(int i) {
if (i <= i) {
return i;
}
return fibonacci(i - 2) + fibonacci(i - 1);
}
2N steps
Brute-forcing travelling salesman
N! steps
Binary search
log2 N steps
Binary search
log2 N steps
🤔🤔🤔
Binary search
Way less than N steps
Abstraction
over complexity
1938 -
“Beware of bugs in the above code;
I have only proved it correct, not tried it.”
“Premature optimization is the root of all evil.”
“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%.”
steps | Big O |
---|---|
1 | O(1) |
log N | O(log N) |
N | O(N) |
N2 | O(N2) |
2N | O(2N) |
steps | Big O |
---|---|
2N | O(N) |
42N2 + 2N + 3 | O(N2) |
log2 N | O(log N) |
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 | 🤯 |
N | name |
---|---|
O(1) | constant |
O(log N) | logarithmic |
O(N) | linear |
O(N2) | quadratic |
O(2N) | exponential |
O(N!) | factorial |
N | |
---|---|
O(1) | |
O(log N) | |
O(N) | |
O(N2) | ↑ Polynomial |
O(2N) | ↓ Slow |
O(N!) |
Why do we care about this?
1912 - 1954
2014
Disclaimer
Cracking codes
worse than polynomial
Verifying codes
polynomial
“nondeterministic-polynomial”
finding an answer: slow
checking an answer: P
Obviously, P ≠ NP
jè.
In practice
1906 - 1992
Know the big O of your algorithms
Know your
data structures
operation | big O |
---|---|
access | O(1) |
search | O(N) |
prepend | O(N) |
append | O(1) |
operation | big O |
---|---|
access | O(N) |
search | O(N) |
prepend | O(1) |
append | O(N) |
operation | big O |
---|---|
access | n/a |
search | O(1) |
iteration | O(N) |
insert | O(1) |
How do I do this in Java?
1955 -
Data structures
Immutable collections
Vavr, Eclipse Collections, Guava
Variable declaration
No:
ArrayList<String> myList = new ArrayList<>();
Yes:
List<String> myList = new ArrayList<>();
Yes:
List<String> myList = new LinkedList<>();
Yes:
List<String> myList = new CopyOnWriteArrayList<>();
Equality
class ComputerScientist {
private final String name;
// constructor, getters & setters
}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");
class ComputerScientist {
private final String name;
// constructor, getters & setters
}
var cs1 = new ComputerScientist("James Gosling");
var cs2 = new ComputerScientist("James Gosling");
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
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 🥳
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 🥳
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
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 🥳
Override equals
?
Override equals
and hashCode
!
The bigger picture
1936 -
2017
If you remember only 3 things
It depends
🙂 Set<T> set;
🧐 LinkedHashSet<T> set;
Let’s
wrap up
1903 - 1957
1903 - 1957
Thing 1:
De Morgan’s Laws
Thing 2:
Truth tables
Thing 3:
It depends
Algorithms
Linear Search
Binary Search
Complexity
& Big O
Choose wisely
Data structures
Choose wisely
Hash-based algorithms?
Implement equals
and hashCode
Now you know enough CS!
What’s next?
Keep this stuff in the back of your mind
Look it up when you need to decide
Tip: Google “Big O cheat sheet”
Experiment
Experiment
Tip:
Implement your own HashMap!
Experiment
Advanced tip:
Implement your own compression algorithm!
#enoughcs
image credits: see website