About Me
Graduated Computer Science at the University of Waterloo in June 2025.
I use my website to document things I’ve been thinking about or have been doing.
[firstName][at][this fqdn] | |
| GitHub | sean01zhang |
Posts
- Go: Directional Channel Types
Golang’s concurrency features are super easy to understand and use. One of the key features is a channel, used to share data across different goroutines (think of this as a lightweight user-space pthread).
You have built a system on
gothat is super performant and web scale. One day, you push a change and now your service is crash-looping. You check the logs, and you realize that one of your goroutines sent on a closed channel, and your program panicked. - Initial Months Owning an OLED Display
Recently, I decided to buy a nice display for myself to treat my eyes, and I wanted to share some of my thoughts that I had using it for the first two months.
The monitor I bought is a LG 32-inch 4K OLED display that was on sale for $899.
Features
(Full product page with specifications is available on LG’s website)
The selling points of this monitor are:
- It is a widescreen (16:9 aspect) display.
- It is 32 inches wide diagonally.
- It has an OLED display panel.
- This allows your display to achieve true blacks. Each pixel in an OLED display emit their own light, so individual pixels can be turned off to get deep blacks. Most displays use LCD panels, which rely on a backlight that cannot be controlled to the pixel level to hit the same levels of blacks.
- It has a very high refresh rate, 240Hz.
- It has dual mode, where it can switch between 4K, 240 Hz and FHD, 480 Hz.
- Practically speaking, this gives you a button on the display which switches your monitor between the two resolutions to hit even higher refresh rates. If you play a lot of games that require low latency, this will come in handy.
- It has a stand that can be adjusted in every way fathomable - tilt, rotate, height, and swivel.
My Experience
I agree with reviews online, this is an excellent gaming monitor. It has super low latency in every aspect, it has a massive viewing angle, and its size and resolution will make any content you consume on here look great.
- Freeing alt keys in your terminal
In my terminal, I have
Option-Cbound to fzf’s fuzzy cd. However, when I press this, I getçtyped instead of triggering the keybind. I thought this was a system-wide issue with my US keyboard, but a more elegant solution lies inside of your terminal’s settings!Solution
Here is the fix for few terminal emulators that I know of.
Terminal.app
Go to
Settings > Profiles, and check the box, “Use Option as Meta key”. - Make a New Homebrew Tap
The documentation from the homebrew docs is sufficient to creating a new tap. I will add a bit of commentary in addition to the above to discuss the design choices I made when making my homebrew tap & cask for window-switcher.
First of all, I chose to create a repository on GitHub, since that is where my code is stored. Some bikeshedding - what should I name my tap?
Note: [GitHub Only] The brew.sh docs recommended adding a prefix to your homebrew tap repo with
homebrew-if you want users to take advantage of thebrew tapcomamnd. However, when others install or tap from your repo, they do not include the prefix. For example, the repogithub.com/sean01zhang/homebrew-formulaecan be accessed by executingbrew tap sean01zhang/formulae. - Why I Built Window Switcher
Since finishing my last internship, I’ve missed having massive monitors at work. No longer could I have two windows in split view without sacrificing content space.
This meant that I had many apps occupying one desktop at once. However, as a certified non-minimalist^TM, I have too many windows open. For example, I have multiple instances of Firefox open (one for each profile), multiple instances of Finder with different folders open, and if I wasn’t a
vimuser, I would have many different instances of my favourite GUI-based code editor open (one for each repository I was working on). - Feeding Sourdough Starter
This playbook documents how you should feed your starter. It assumes you have a starter already.
State
Note
Using a transparent container to store your starter makes it easier to know how active your starter is.
There is a gradient of which how hungry/active your starter is, and it can usually be gauged by the volume that your starter takes up.
Not fed in a while: Not bubbly, and may have a clear fluid on top (referred to as hooch). This fluid smells like alcohol and is a byproduct of fermentation. A build-up of this fluid usually indicates that your starter needs to be fed. Pour it out before the next feeding. This will be the smallest in volume it can be.
- 🍞🪵 :: 2024-12-30
Bread making log, Dec 30. I made 2 loaves, so this will be two parts.
Loaf 1
- Fed starter 1:1:1 at 10pm, left at RT
- 200g ea
- Used starter around 11:30am
- starter more than doubled, overfilled
- Mixed in water and dough first
- Then incorporated the starter
- Then added salt
- Poor mixture, it was quite lumpy
- did not pass windowpane test, dough was not airy
- Dough still sticky after last stretch and fold, shaped into a ball
- waited 10-15 mins
- Put into banneton
- Fridge overnight
- Preheat both dutch ovens no lid
- Put in oven 10:40am
- Did not take out to score until preheated
- did not shape, boule was firm and skin was dry
- A lot more expansion
- Expansion potentially caused crusting to not be as burned
- This could also be conflated with 19 mins lid off
- Scoring went too far along the sides, reduce length of cross. Depth was slightly deep too.
Loaf 2
- 1:1:1 on stbl starter
- 120g
- Used starter around 7pm, last fed 10pm but in fridge. Taken out around 2/3pm (5 hour warm up)
- Mixed all together, started with 250g (1.5 cup) water — added another 1/4 as needed
- did not pass windowpane test, was a bit dry
- Left in oven to proof on “proof” setting
- Stretch and fold focused on not ripping the dough
- Much more stretchy than earlier one after stretch and fold.
- Put in oven 10:40am
- Did not take out to score until preheated
- did not shape, boule was firm and skin was dry
- A lot more expansion
- Expansion potentially caused crusting to not be as burned
- This could also be conflated with 19 mins lid off
- Scoring went too far along the sides, reduce length of cross. Depth was slightly deep too.
- Fed starter 1:1:1 at 10pm, left at RT
- Added more buttons to my homepage!
Nice.
Widgets
88x31
A small pool of buttons (specifically 88px in width and 31px in height) that link to friends, in lexicographic order.
Tiger told me that https://eightyeightthirty.one/ crawls the entire web for buttons that link to other buttons. Really cool!
Web Rings
A circular linked-list of websites that share some interest in common. Below is the UWaterloo CS webring:


