Hello! I’m an inveterate tech-head who does freelance software development, performance engineering, and systems analysis. 30 years of wrangling with computer code has given me both breadth and depth in the field; some of my main areas of expertise are listed below. I can help you design software, build software, analyze difficult bugs, make slow software fast, or train your development team. General consulting and advisory jobs are also welcome. If you need a technical power hitter on your project, drop me a mail and let’s talk.
I’m good with...
Languages
C, Ruby, JavaScript, Lua, Lisp (Clojure, Scheme, Common Lisp), Java, SQL (Postgres, SQLite), Assembly (x86-64/RISC-V)(Have also written production code in: AWK, C#, C++, CoffeeScript, Groovy, Perl, PHP, Python)
Low-level/“System” Programming
I’ve done extensive research into CPU architectures, firmware standards like UEFI, operating system internals (especially the workings of the Linux kernel), filesystems, compiler/linker design, virtual machine/dynamic runtime design, binary formats, network protocols...Understanding the lower parts of the computing stack often helps me diagnose and fix obscure bugs which would otherwise be inscrutable. Examples:
- Fixing a bug in Ruby’s garbage collector. (Ruby Bug #7135) After tracing a crashing Ruby program in the GDB debugger and examining its memory, I realized this was a use-after-free bug. Further investigation showed that the only reference to a string was being kept in a CPU register, when Ruby’s garbage collector relies on scanning the program stack for pointers.
- Fixing a bug in PHP’s JIT compiler. (PHP PR #6392) I traced a crashing PHP program in GDB and by reading the disassembly of JIT-generated code, found that it was clearly wrong. The next step was digging through the source code for the JIT compiler to find which part was generating the incorrect machine code.
This in-depth understanding also helps me design fast systems, or analyze why a system is slow.
Algorithms and Data Structures
Strong grasp of the classic algorithms and data structures, plus some exotic ones. Example:immutable-ruby
library. I wrote 95% of this library, which provides a selection of immutable, persistent, thread-safe data structures for Ruby.
Web
In-depth knowledge of foundational web technologies: HTTP, HTML, CSS, JavaScript (including its standard library and the various browser JavaScript APIs). Some knowledge of browser internals. Have read parts of the source code for the V8 JavaScript engine.SQL Databases
My experience is most extensive with PostgreSQL, but have also coded SQL for MS SQL Server, MySQL, and SQLite. Have often been able to make SQL queries faster (even hundreds of times faster) by analyzing the query plan and adjusting the query or adding appropriate indexes.Math
I’m a math buff and have a good grasp of many undergraduate-level math topics: calculus, linear algebra, differential equations, probability, statistics, group theory, complex analysis. (Math questions I’ve asked publicly)Other technical strengths (click for details):
Alpine Linux | Ansible | Concurrency | Data Visualization | Debuggers | Fuzzing | Git | GraphQL | JPEG | Linux Containers | Networking | Parsing | Regular Expressions | Security | SIMD | TeX | Text Encoding | UnicodeI’m the maintainer of several Alpine Linux packages. I have contributed code to musl libc before, and have read some of the source code for OpenRC. (Both of these are key components of Alpine Linux.)
I use Ansible to automate server setup and other sysadmin tasks.
I once became very interested in concurrent/parallel programming and did a lot of research. One of the fruits was the ReadWriteLock
implementation which is still included in the popular concurrent-ruby
library.
Most of what I know about data visualization in the abstract was learned by reading Tamara Munzner’s Visualization Analysis and Design. I sometimes use D3.js to create interactive displays of information; you can see a few examples on my blog.
I frequently use GDB to analyze the behavior of programs. Have some limited experience in scripting GDB using Python.
(War story: This once helped me diagnose and fix an intermittent bug which we couldn’t reliably reproduce; I ran the buggy program in a loop, under GDB, with a script which would make GDB stop the program at key points, dump the registers and stack to a log, then continue execution. After waiting for the bug to reoccur, I was able to find the log entries for the “bad” run and discover what was actually happening.)
Around 2015, I started using homebrew “fuzzers” to test my code on huge numbers of random test cases. These fuzzers were not coverage-guided, but would just blindly generate random inputs. Still, they were effective enough at finding bugs to make the practice worthwhile. When I started working on PHP core, Nikita encouraged me to try using clang’s libFuzzer (a coverage-guided fuzzer). It was astonishly good at finding bugs, even wildly obscure bugs; my previous hand-rolled fuzzers were left in the dust. Ever since then, libFuzzer has been a key tool in my toolkit. (Description of how I normally use libFuzzer)
Longtime, advanced git user.
On a previous project, I needed to implement a GraphQL server. None of the available open-source implementations seemed suitable, so I studied the specification and wrote my own server from scratch. (Interesting technical point: Many GraphQL server implementations use a technique called the “dataloader pattern” to avoid issuing vast numbers of database queries, but in my humble opinion, the “dataloader pattern” is a poor idea and best avoided. Instead, my implementation analyzes GraphQL queries and translates them into SQL queries in a way which guarantees just one SQL query will be issued for each node in the GraphQL query tree.)
See: JPEG decoder which I wrote as an exercise. My article on the Discrete Cosine Transform, which plays a central role in JPEG encoding/decoding.
Have worked on a number of projects which were containerized. So far, most of my work with containers has been via the LXC userspace tools. I understand the kernel features which support containerization (namespaces, cgroups) and the system calls involved.
At one previous job, I was in charge of network installations and support for a facility with several hundred workers. This meant learning to configure network switches, routers, Wi-Fi access points, and so on. I also studied many network protocols in detail and learned to use WireShark to analyze packet dumps.
I’ve researched a lot of parsing algorithms and am experienced in using both traditional LALR(1) parser generators and the newer PEG parser generators.
Good understanding of how regular expression engines are implemented. Have implemented some of the key algorithms before, such as NFA-to-DFA conversion and DFA minimization. Understand how to use advanced features supported by some regex engines, such as lookahead and lookbehind.
I’m not a security researcher, but once I worked through almost all the OverTheWire hacking “wargames”, just to understand more about how security exploits work. In the process, I learned how to write shellcode and develop buffer overflow exploits, printf format string exploits, time-of-check-to-time-of-use exploits, and so on.
Fun story: While going through some of the harder “wargames”, I found it was very helpful to use return-oriented programming in my exploits... but it is such a pain to read through an entire disassembled binary to find snippets of assembly code for a ROP exploit! To save myself this pain, I developed a tool in Ruby which analyzes an ELF binary and automatically generates a list of addresses for a ROP exploit against that binary. (You tell the tool what CPU registers and fixed memory addresses you want the exploit to write specified values into. It only works for the x86 architecture, and only for the basic scalar registers, not for bigger registers used for SIMD. I have not made this tool publicly available.)
While working on the PHP interpreter, I learned to devise algorithms for applying SIMD instructions to speed up computation on large strings. I’ve only done this for x86-64 CPUs, though the skill should transfer to other CPU architectures. Examples: 1 | 2 | 3 | 4 | 5
I use LaTeX for writing documents with embedded math notation, and KaTeX for including math notation in web pages. Once I wrote a Ruby-based clone of TeX to understand it better; unfortunately, my clone doesn’t support the TeX commands for aligning table cells and probably never will.
I’m the maintainer of mbstring, a core PHP extension which allows PHP to handle all kinds of legacy text encodings. This has resulted in getting to know far more than I ever wanted about ISO-2022 text, EUC, Shift-JIS, GB18030, BIG-5, UHC, HZ, etc.
I am the maintainer of one of PHP’s core libraries for handling Unicode, and this has caused me to delve into the Unicode standard. I’ve contributed implementations of some important Unicode-processing algorithms like string canonicalization and grapheme segmentation to lua-utf8
.
I don’t know much about (but would love to learn)...
High-scale Distributed System Design
Sounds fascinating, but I’ve never done it before. I could still help to fix bugs or optimize for speed on individual nodes in your distributed system.NoSQL Databases
Have only done a small amount of work with MongoDB on one project.SPA Web Frameworks (React/Vue/Svelte/etc)
I have built SPA web applications using my own hand-rolled JavaScript before, but have never used any of the big frameworks.Mobile (iOS/Android) Client Development
Would love to learn, but haven’t had the opportunity yet.Machine Learning
Would love to learn one of these days. Hopefully, when that day comes, my background in linear algebra and statistics may help.Samples of Paid Work
GUI for updating data tables on microcontroller
Written mostly in Clojure, AOT-compiled to Java bytecode and packaged up to run on a single double-click. So the client wouldn’t have to keep calling me back, most of what is seen in the GUI can be changed by editing plain-text configuration files. I couldn’t find a good open-source library for rendering 3D graphs with license terms which were acceptable, so I rolled my own simple CPU-based renderer which does Z-sorting and Gouraud shading of polygons.Web site for event staffing company
The initial development of this web site was done in 2013; it includes a public-facing section as well as a backend system which handles most internal business operations. Since then, I have been called back periodically to update and enhance the site. The backend system has an interesting architecture which is designed to minimize latency for office users.Samples of Open-source Work
PHP
I’ve contributed over 500 commits tophp-src
. Much of this was on mbstring
(a core PHP extension which is used to process text which is encoded in various ways), but it also includes other bug fixes and enhancements. My first commit in PHP core is interesting; it tweaked the PHP lexer so that PHP can print much better error messages for certain kinds of syntax errors.
lua-utf8
lua-utf8
is a Lua and LuaJIT extension for processing UTF-8 text. I have added several new features: functions for Unicode normalization, grapheme segmentation, and for UTF-8 validity checking and scrubbing of invalid byte sequences.
bit-twiddle
A C-based Ruby extension which implements various bit-manipulation operations which are not supported by core Ruby. Authored by myself, to scratch an itch which I had on another project.musl libc
I added a script which automatically annotates x86 and x86-64 assembly source files with directives to generate the right debugging information, so that debuggers can show an accurate stack trace when stopped in that assembly code. Before this, a debugger would not show a stack trace at all when stopped in certain parts of musl libc.Bug fixes in Ruby core
Here are a few examples: 1 | 2 | 3Rubocop
Rubocop is a linter and formatter for Ruby code. I’ve contributed more than 400 commits, including lots of bug fixes as well as some big performance improvements.Finally, if it’s any help...
- I speak, read, and write (Mandarin) Chinese and Japanese fluently.
(Last updated in June 2024)