Skip to content

Commit 6f5a043

Browse files
committed
📝 add java, database cursor, and misc zettelkasten notes
1 parent 8071566 commit 6f5a043

5 files changed

Lines changed: 491 additions & 0 deletions

File tree

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
🗓️ 06072026 1200
2+
3+
# database_cursor
4+
5+
```ad-note
6+
A database cursor is a server-side object that holds an open, stateful pointer into a result set, allowing row-by-row traversal instead of operating on the set all at once.
7+
```
8+
9+
## What It Is
10+
11+
- Declared with `DECLARE CURSOR`, then driven with `OPEN` / `FETCH` / `CLOSE`
12+
- The database allocates resources to track your position — memory, and sometimes locks, for as long as the cursor is open
13+
- Lives for the duration of a single session or transaction — not shareable across requests
14+
- Built for **row-by-row procedural processing** inside a stored procedure or batch job, where the logic can't be expressed as a single set-based query
15+
16+
See [[mysql_cursor]] for the concrete syntax and lifecycle in MySQL.
17+
18+
## When to Use
19+
20+
- Iterating a result set row-by-row to apply procedural logic per row
21+
- Multi-step transformations that can't be expressed in a single SQL statement
22+
- Processing large datasets in smaller chunks without loading everything into memory
23+
24+
## When to Avoid
25+
26+
Set-based operations are almost always faster and simpler. Prefer cursors only when the per-row logic genuinely can't be expressed as a `JOIN`, subquery, or batched `UPDATE`/`INSERT`/`DELETE`.
27+
28+
```ad-warning
29+
An open database cursor holds server-side state. If a web request opens one and the client never comes back (closed tab, dropped connection), that state leaks until it times out. This is why database cursors are the wrong tool for API pagination — see [[keyset_cursor]] for the pattern actually used there.
30+
```
31+
32+
---
33+
34+
## References
35+
- [[mysql_cursor]]
36+
- [[keyset_cursor]]
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
🗓️ 06072026 1200
2+
3+
# keyset_cursor
4+
5+
```ad-note
6+
A keyset cursor isn't a database object at all — it's an application-level convention. The "cursor" is just the last row's sort-key values, encoded and handed back to the client.
7+
```
8+
9+
## What It Is
10+
11+
- Client sends back `(last_seen_id, last_seen_created_at)` — or an opaque token that encodes the same thing
12+
- Next page: `WHERE (created_at, id) > (:last_created_at, :last_id) ORDER BY created_at, id LIMIT :n`
13+
- No server-side state at all — the "position" lives entirely in the token, so it's stateless and shareable across requests, servers, even days apart
14+
- Requires an index on the sort-key columns to stay fast (see [[b_plus_tree_indexes]]) — the `WHERE` clause seeks directly via the index instead of scanning
15+
16+
```ad-info
17+
Also called **seek pagination** or the **seek method** in the wild — "keyset" refers to the indexed column(s) that make the seek fast.
18+
```
19+
20+
## Why It Replaces Offset Pagination
21+
22+
`LIMIT`/`OFFSET` pagination forces the database to skip over every discarded row before reaching the requested page — the deeper the page, the slower the query. A keyset cursor seeks directly to the next row via the index, so cost stays flat regardless of page depth. See [[mysql_cursor_vs_pagination]] for the full comparison.
23+
24+
Elasticsearch's `search_after` is the same idea applied to search results — sort values from the last document become the seek point for the next page. See [[es_search_after]].
25+
26+
```ad-example
27+
When people say an API is "cursor-paginated" (Stripe, GitHub, Relay's `after`/`before`), they mean a keyset cursor — an opaque string encoding the last row's sort key. No database cursor (see [[database_cursor]]) is open anywhere in that request.
28+
```
29+
30+
## Trade-offs
31+
32+
- Can only move forward/backward relative to a known row — no "jump to page 50" like offset pagination allows
33+
- Requires a stable, indexed sort order (usually a unique or tie-broken key) so the seek is unambiguous
34+
- Slightly more work to implement than `OFFSET`, but the performance and consistency gains dominate at scale
35+
36+
---
37+
38+
## References
39+
- [[database_cursor]]
40+
- [[mysql_cursor_vs_pagination]]
41+
- [[es_search_after]]
42+
- [[b_plus_tree_indexes]]
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
🗓️ 06072026 1200
2+
3+
# leetcode_java_cheatsheet
4+
5+
**What it is:**
6+
- Syntax reference for the data structures used most often in LeetCode-style problems, in Java
7+
- Focused on the operations that come up under time pressure — construction, common methods, iteration, gotchas
8+
- Not a DSA concepts primer — assumes you know what a heap/deque/trie *is*, just not the Java spelling of it
9+
10+
## Arrays
11+
12+
```java
13+
int[] arr = new int[10]; // fixed size, zero-initialized
14+
int[] arr = {1, 2, 3}; // literal
15+
int[][] grid = new int[rows][cols]; // 2D, zero-initialized
16+
int[][] grid = {{1, 2}, {3, 4}}; // 2D literal
17+
18+
Arrays.fill(arr, -1); // fill all
19+
Arrays.sort(arr); // ascending, in place
20+
Arrays.sort(arr, from, to); // sort sub-range [from, to)
21+
int[] copy = Arrays.copyOf(arr, arr.length);
22+
int[] slice = Arrays.copyOfRange(arr, from, to); // [from, to)
23+
Arrays.equals(a, b); // element-wise equality
24+
String s = Arrays.toString(arr); // "[1, 2, 3]" for debugging
25+
26+
// Sort descending (Integer[] only — primitives have no Comparator overload)
27+
Integer[] boxed = {3, 1, 2};
28+
Arrays.sort(boxed, Collections.reverseOrder());
29+
30+
// Sort 2D array by a column
31+
Arrays.sort(grid, (a, b) -> a[0] - b[0]); // by col 0 ascending
32+
Arrays.sort(grid, (a, b) -> b[0] - a[0]); // by col 0 descending
33+
```
34+
35+
```ad-warning
36+
`Arrays.sort` on `int[]` uses dual-pivot quicksort (O(n log n) avg, O(n²) worst). On `Object[]` (including `Integer[]`) it uses TimSort — stable, guaranteed O(n log n). Prefer `Integer[]` when a stable sort or custom comparator matters.
37+
```
38+
39+
## ArrayList
40+
41+
```java
42+
List<Integer> list = new ArrayList<>();
43+
list.add(5); // append
44+
list.add(0, 5); // insert at index — O(n)
45+
list.get(i);
46+
list.set(i, val); // overwrite
47+
list.remove(i); // remove by INDEX — O(n)
48+
list.remove(Integer.valueOf(5)); // remove by VALUE (autobox to disambiguate)
49+
list.contains(5); // O(n)
50+
list.indexOf(5); // O(n), -1 if absent
51+
list.size();
52+
list.isEmpty();
53+
Collections.sort(list);
54+
Collections.reverse(list);
55+
Collections.max(list);
56+
Collections.min(list);
57+
58+
// int[] <-> List<Integer> conversions (no direct cast)
59+
List<Integer> fromArr = Arrays.stream(arr).boxed().collect(Collectors.toList());
60+
int[] toArr = list.stream().mapToInt(Integer::intValue).toArray();
61+
```
62+
63+
```ad-warning
64+
`list.remove(5)` removes the element **at index 5**. `list.remove(Integer.valueOf(5))` removes the value **5**. This is a classic LeetCode footgun with `int` lists.
65+
```
66+
67+
## HashMap / HashSet
68+
69+
```java
70+
Map<String, Integer> map = new HashMap<>();
71+
map.put("a", 1);
72+
map.get("a"); // null if absent
73+
map.getOrDefault("a", 0);
74+
map.containsKey("a");
75+
map.remove("a");
76+
map.put("a", map.getOrDefault("a", 0) + 1); // classic counting bump
77+
map.merge("a", 1, Integer::sum); // same, one line
78+
map.computeIfAbsent(key, k -> new ArrayList<>()).add(val); // group-by / adjacency list build
79+
80+
for (Map.Entry<String, Integer> e : map.entrySet()) { e.getKey(); e.getValue(); }
81+
for (String k : map.keySet()) { }
82+
for (int v : map.values()) { }
83+
84+
Set<Integer> set = new HashSet<>();
85+
set.add(1);
86+
set.contains(1);
87+
set.remove(1);
88+
89+
Set<Integer> set = new HashSet<>(list); // dedupe a list in one line
90+
```
91+
92+
```ad-info
93+
`LinkedHashMap` / `LinkedHashSet` preserve insertion order — use when iteration order matters (e.g. building an LRU cache). `TreeMap` / `TreeSet` keep keys sorted, backed by a red-black tree, O(log n) ops — use when you need order + range queries instead of a heap.
94+
```
95+
96+
## Deque (stack, queue, and monotonic deque)
97+
98+
`ArrayDeque` is the go-to — faster than `Stack`/`LinkedList` and not synchronized.
99+
100+
```java
101+
Deque<Integer> stack = new ArrayDeque<>();
102+
stack.push(1); // add to head
103+
stack.pop(); // remove from head, throws if empty
104+
stack.peek(); // read head, null if empty
105+
106+
Deque<Integer> queue = new ArrayDeque<>();
107+
queue.offer(1); // add to tail
108+
queue.poll(); // remove from head, null if empty
109+
queue.peek(); // read head, null if empty
110+
111+
// Monotonic deque (sliding window max, etc.) — needs both ends
112+
deque.offerFirst(x); deque.offerLast(x);
113+
deque.pollFirst(); deque.pollLast();
114+
deque.peekFirst(); deque.peekLast();
115+
```
116+
117+
```ad-warning
118+
`pop()`/`push()` on `ArrayDeque` operate on the **head** — so `ArrayDeque` as a stack pushes/pops from the same end you'd `poll()` from as a queue. Don't mix stack and queue method names on the same instance; pick `offer`/`poll` (queue) or `push`/`pop` (stack) and stay consistent.
119+
```
120+
121+
## PriorityQueue (heap)
122+
123+
```java
124+
PriorityQueue<Integer> minHeap = new PriorityQueue<>(); // min-heap by default
125+
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
126+
PriorityQueue<int[]> byFirst = new PriorityQueue<>((a, b) -> a[0] - b[0]);
127+
128+
heap.offer(5); // add
129+
heap.poll(); // remove + return min/max, null if empty
130+
heap.peek(); // read min/max, null if empty
131+
heap.size();
132+
133+
// Heapify an existing collection in O(n) instead of n offers (O(n log n))
134+
PriorityQueue<Integer> heap = new PriorityQueue<>(list);
135+
```
136+
137+
```ad-warning
138+
`(a, b) -> a[0] - b[0]` overflows if values approach `Integer.MIN_VALUE`/`MAX_VALUE`. Use `Integer.compare(a[0], b[0])` when magnitudes are unbounded.
139+
```
140+
141+
## StringBuilder
142+
143+
```java
144+
StringBuilder sb = new StringBuilder();
145+
sb.append("x").append(5); // chainable, mixed types
146+
sb.insert(0, "y"); // prepend
147+
sb.deleteCharAt(sb.length() - 1);
148+
sb.reverse();
149+
sb.charAt(i);
150+
sb.setCharAt(i, 'z');
151+
sb.toString();
152+
sb.length();
153+
```
154+
155+
```ad-info
156+
Strings are immutable in Java — `str += c` in a loop is O(n) per append, O(n²) overall. Always use `StringBuilder` when building a string incrementally.
157+
```
158+
159+
## String
160+
161+
```java
162+
s.charAt(i);
163+
s.length();
164+
s.substring(from); // [from, end)
165+
s.substring(from, to); // [from, to)
166+
s.split(","); // regex-based — escape special chars: split("\\.")
167+
s.toCharArray();
168+
String.valueOf(charArray);
169+
s.equals(other); // NEVER use == for content comparison
170+
s.compareTo(other);
171+
s.indexOf('c'); // -1 if absent
172+
String.join(",", list);
173+
s.trim();
174+
s.toLowerCase(); s.toUpperCase();
175+
Character.isDigit(c); Character.isLetter(c); Character.isLetterOrDigit(c);
176+
Character.toLowerCase(c);
177+
```
178+
179+
```ad-warning
180+
`==` compares references for `String`/boxed types, not content. Two equal-looking strings from different sources can be `==` false. Always use `.equals()`. (Integer caching makes `Integer == Integer` "work" for -128..127 only — another reason to avoid `==` on boxed types entirely.)
181+
```
182+
183+
## Trees & Linked Lists (typical LeetCode node defs)
184+
185+
```java
186+
class TreeNode {
187+
int val;
188+
TreeNode left, right;
189+
TreeNode(int val) { this.val = val; }
190+
}
191+
192+
class ListNode {
193+
int val;
194+
ListNode next;
195+
ListNode(int val) { this.val = val; }
196+
}
197+
198+
// Dummy head pattern — avoids special-casing an empty result list
199+
ListNode dummy = new ListNode(0);
200+
ListNode curr = dummy;
201+
// ... curr.next = new ListNode(x); curr = curr.next;
202+
return dummy.next;
203+
```
204+
205+
## Trie
206+
207+
```java
208+
class TrieNode {
209+
TrieNode[] children = new TrieNode[26];
210+
boolean isWord;
211+
}
212+
// index children with c - 'a' for lowercase-letter problems
213+
```
214+
215+
## Union-Find (Disjoint Set Union)
216+
217+
```java
218+
int[] parent = new int[n];
219+
int[] rank = new int[n];
220+
for (int i = 0; i < n; i++) parent[i] = i;
221+
222+
int find(int x) {
223+
if (parent[x] != x) parent[x] = find(parent[x]); // path compression
224+
return parent[x];
225+
}
226+
227+
void union(int a, int b) {
228+
int ra = find(a), rb = find(b);
229+
if (ra == rb) return;
230+
if (rank[ra] < rank[rb]) { int t = ra; ra = rb; rb = t; }
231+
parent[rb] = ra;
232+
if (rank[ra] == rank[rb]) rank[ra]++;
233+
}
234+
```
235+
236+
## Sorting with Comparator (multi-key, common interval pattern)
237+
238+
```java
239+
// int[][] intervals, sort by start then end
240+
Arrays.sort(intervals, (a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
241+
242+
// List<T> with Comparator.comparing chains
243+
list.sort(Comparator.comparing((int[] a) -> a[0]).thenComparing(a -> a[1]));
244+
245+
// Custom object, descending
246+
people.sort((a, b) -> b.score - a.score);
247+
```
248+
249+
## Bit Manipulation
250+
251+
```java
252+
x & 1 // check odd/even
253+
x >> 1 // divide by 2
254+
x << 1 // multiply by 2
255+
x & (x - 1) // clear lowest set bit
256+
x & (-x) // isolate lowest set bit
257+
Integer.bitCount(x) // popcount
258+
Integer.toBinaryString(x)
259+
1 << k // bit mask for position k
260+
```
261+
262+
## Complexity Cheat Sheet
263+
264+
| Structure | Access | Search | Insert | Delete |
265+
|---------------------|--------|--------|--------|--------|
266+
| ArrayList | O(1) | O(n) | O(n)* | O(n) |
267+
| HashMap/HashSet | - | O(1) | O(1) | O(1) |
268+
| TreeMap/TreeSet | - | O(log n) | O(log n) | O(log n) |
269+
| ArrayDeque (as stack/queue) | O(1) ends | O(n) | O(1) ends | O(1) ends |
270+
| PriorityQueue | O(1) peek | O(n) | O(log n) | O(log n) |
271+
272+
*O(1) amortized for append at the end; O(n) for insert/remove at arbitrary index.
273+
274+
---
275+
276+
## References
277+
278+
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/package-summary.html
279+
- [[java_concurrency_data_structures]]

0 commit comments

Comments
 (0)