initial commit

This commit is contained in:
Zhongheng Liu 2025-12-31 00:32:05 +00:00
commit 12113c2ee1
10 changed files with 313 additions and 0 deletions

6
docker-compose.yml Normal file
View file

@ -0,0 +1,6 @@
services:
blogsite:
image: custom/blogsite
build: ./src
networks:
- net

18
src/Dockerfile Normal file
View file

@ -0,0 +1,18 @@
FROM alpine:latest
WORKDIR /site
COPY ./in /site/in
RUN apk add git go lowdown busybox-extras
RUN mkdir -p /site/out /site/kew
RUN git clone https://stvnliu.me/git/steven/kew-custom.git /site/kew
RUN cd /site/kew && \
go build && \
cp ./kew /usr/local/bin/kew
RUN kew /site/in /site/out
EXPOSE 8080
CMD ["httpd", "-f", "-p", "8080", "-h", "/site/out"]

8
src/in/index.md Normal file
View file

@ -0,0 +1,8 @@
### Some things I've written on
- learning dutch
- using interesting technology
- reading some books
- other things in life in general
Copyright Zhongheng Liu 2026-2027

106
src/in/style.css Normal file
View file

@ -0,0 +1,106 @@
:root {
--bg: #646c7f;
--fg: #fffde0;
--fg-link: #fff18f;
}
/* global */
body {
margin: 0;
padding: 0;
background: var(--bg);
color: var(--fg);
font-family: serif;
font-size: 16px;
line-height: 1.2;
}
/* header */
header {
padding: 20px;
}
header h1 {
margin: 0;
font-size: 35px;
font-weight: normal;
font-style: italic;
}
header a {
color: var(--fg);
text-decoration: none;
}
main {
display: grid;
gap: 1.25rem;
align-items: start;
margin-right: 400px;
/* Desktop: article + sidebar */
grid-template-columns: 1fr 8fr; /* content flexible, nav fixed-ish */
grid-template-areas: "side content";
}
/* assign the semantic elements to grid areas */
article {
grid-area: content;
margin-left: 50px;
}
#side-bar {
grid-area: side;
margin-top: 10px;
width: max-content;
padding-left: 20px;
}
/* Mobile: stack them, keeping article first visually */
@media (max-width: 820px) {
main {
grid-template-columns: 1fr;
grid-template-areas:
"side"
"content";
margin-left: 10px;
margin-right: 10px;
}
}
.side-title {
font-size: 25px;
margin: 20px 0 8px 0;
color: var(--fg);
}
#side-bar ul {
margin: 0 0 0 20px;
padding: 0px;
list-style: none;
}
#side-bar li {
margin: 6px 0;
}
/* links */
a {
color: var(--fg-link);
text-decoration: none;
padding: 1px 2px;
}
a:hover {
background: var(--fg);
color: var(--bg);
}
h3 {
margin-top: 30px;
font-size: 25px;
color: var(--fg);
font-weight: normal;
}
/* footer */
footer {
padding-top: 80px;
font-style: italic;
font-size: 17px;
}

View file

@ -0,0 +1,13 @@
---
title: Learning Dutch (de eerste)
date: 2025-07-27 06:43:17
tags:
- dutch
- language
---
# Eerste tekst in het Nederlands
Hallo 👋, in deze maanden ben ik op een taalverwerving reis van de Nederlandse taal.
Nu kun ik niet wat sommige mensen praten begrijpen, maar sommige dingen in de televisie afleveringen kan ik nu begrijp, in particuliere sommige grappige van De Avondshow met Arjen Lubach. Hij is een heel leuk mens, met een even beter humor.
Misschien ik heb in dit tekst een paar fouten maken, maar dat is goed, want in de toekomst ga ik dit gezien, en daarna moet ik hoeveel beter mijn Nederlands worden over deze eerste maanden aan de verwering reis kennen.

View file

@ -0,0 +1,19 @@
# De tweede tekst in Nederlands
Hoi allemal, ik heb een beetje meer geleerd van de taal sinds de laatste update,
en we zijn nu bijna in het einde van het jaar 2025, nog een dag en komt het jaar 2026 (Dit tekst was op 30 dec 2025 geschreven).
Tijdens het jaar, er waren veel nieuwe dingen die ik heb geleerd. Sinds de tweede kwart van het studiejaar, ik heb in een officiele cursus bij de universiteit geweest.
Van deze cursus heb ik belangrijke woorden een grammatica geleerd, een daarom kan ik nu dit tekst schrijven. Ik weet het al dat ik zal fouten maken in dit tekst.
Volgend jaar, ik zal in deze cursus (maar natuurlijk op een hoger niveau) blijven, zodat ik kan meer van de taal leren.
Is Nederlands moeilijk? Ik denk niet zo. Voor mij, het was beetje makkelijker want ik ben al goed in Engels, en heb een paar Duitse woorden geweten. Dus ik heb al een goede basis om Nederlands te leren.
Maar ik weet niet zo veel van de cultuur. Nederlandse cultuur is veel interessante, want het normale van de samenleving is iets anders van dat in Griekenland, waar ik heb voor vier jaar gewoont.
Feestjes in Nederland zijn anders ook, met Sinterklaas (die is een feestje anders van Kerstmis). In Delft, er komt een markt elke week op donderdag en zaterdag, in het centrum.
Maar in het bijzonder, er was een grotere markt op Sinterklaas. Op de dag, ik heb een smakelijke portie kibbeling gegeten van een vishandel die was in het markt. Er was ook muziek, en lopend een paar Pietjes overal het markt.
In het einde, leven in Delft gaat nog goed in dit jaar. Ik heb alle cursusen van mijn eerste kwart geslaagd, en ik houd van alles in Nederland, behalve het weer. Ik hoop dat volgend jaar gaat nog beter!

View file

@ -0,0 +1,3 @@
# Mijn teksten in het Nederlands
Volgende lijst zijn teksten die ik heb gescheven in mijn studie van de Nederlandsche taal. Natuurlijk zal er fouten in de teksten zijn, maar dat is normaal tijdens taalstudie hé?

View file

@ -0,0 +1,86 @@
# Sorting with Comparables
Any class in Java that implements `Comparable<T>`can be compared to another object of class `T` via a public static method. This allows reference types to be compared to by a custom behaviour.
## Sorting collections with a `Comparable`
`Collection<T>.sort()` sorts the collection by calling the `T.compareTo(T other)` method, where `T implements Comparable`.
```java
public class Data implements Comparable<Data> {
private String name;
...
@Override
public int compareTo(Data other) {
return this.name.compareTo(other.name);
}
}
```
$$
\text{compareTo}: A \times A \rightarrow \mathbb{Z}
$$
The implementation of `compareTo` satisfies the following
$$
\text{compareTo}(x, y) =
\begin{cases}
a \in \mathbb{Z}^- & \text{if $x > y$}\\
0 & \text{if $x = y$}\\
b \in \mathbb{Z}^+ & \text{if $x > y$}\\
\end{cases}
$$
> [!important]
> To control (customize) the sorting mechanism, you need to have ownership of the class that implements the `Comparable` interface. This is not always possible. See `List<Integer>` sorting example.
## Custom sorting for arbitrary class `T` with a `Comparator<T>
`Collection<T>.sort(Comparator<T>)` sorts the `Collection` by passing value of type `T` into a `Comparator<T>`.
We can implement a custom `Comparator` by an anonymous class:
```java
Comparator<T> cmp = new Comparator<T>() {
@Override
public int compare(T x, T y) {
return x.compareTo(y);
}
}
```
>[!note] Lambda comparators
>A comparator can also be defined as a lambda function:
>```java
Comparator<T> cmp1 = (x, y) -> x.compareTo(y);
>```
`cmp1` has the same behaviour:
$$\verb|cmp(x, y)| \equiv \verb|cmp1(x, y)|$$
A use for this is inverting the condition of default behaviour in a class which implementation you cannot mutate.
Consider now the example of sorting a `List<Integer>`:
```java
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
```
We want to sort this list of integers from largest to smallest, whereas the default behaviour from `Integer implements Comparable` is from the smallest to largest.
Now we can apply a custom `Comparator<T>` such that the behaviour is inverted.
```java
list.sort(new Comparator<Integer>() {
@Override
public int compare(Integer x, Integer y) {
// We invert the comparison result of x.compareTo(y).
// swaps from smallest-to-largest to largest-to-smallest
return -x.compareTo(y);
}
});
System.out.println(list); // [4, 3, 2, 1]
```

View file

@ -0,0 +1,26 @@
# When is it modified, Nginx?
> RFC 2616 specifies the behaviour for a web server to respond according to an `if_modified_since` header, but it doesn't work correctly with Nginx. How and why is that so?
*TL;DR: The default Nginx behaviour is `if_modified_since exact;` rather than the more RFC-compliant `if_modified_since before;`, so only an exact date & time match would produce a `304`.*
One bright, sunshiny day I sat down in front of the computer and put in the following command:
```bash
curl --http1.1 -I --header 'If-Modified-Since: Mon, 01 Jan 1970 08:00:00 GMT' https://stvnliu.me/index.html
```
The expectation was that this would produce a `304 Not Modified` HTTP response, as it was specified in the relevant RFC standard. Instead, I was abhorred to discover the status code being a `200 OK` in the following response:
```
HTTP/1.1 200 OK
Server: nginx/1.29.1
Date: Wed, 17 Dec 2025 13:50:21 GMT
Content-Type: text/html
Content-Length: 1250
Last-Modified: Thu, 04 Dec 2025 22:59:21 GMT
Connection: keep-alive
ETag: "69321249-4e2"
Accept-Ranges: bytes
```
A quick dive down the Nginx tracker led to [this wontfix issue](https://trac.nginx.org/nginx/ticket/93), in which a developer responds to the question by stating that even though `if_modified_since before;` adheres more to the RFC standards, they deemed the `exact` behaviour to be much more reliable, i.e. the trade-off for unnecessarily re-fetched content in `200 OK` responses is sufficiently small compared to incorrect behaviour of serving stale content in false-positive `304` events.

28
src/in/template.html Normal file
View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{TITLE}}</title>
<link rel="stylesheet" href="/style.css" type="text/css">
</head>
<body>
<header>
<h1><a href="/index.html">~blog.stvnliu.me</a></h1>
</header>
<main id="content">
<nav id="side-bar">
{{NAV}}
</nav>
<article>
{{CONTENT}}
<footer>
<p>{{FOOTER}}</p>
</footer>
</article>
</main>
</body>
</html>