About
I am a software engineer experienced in developing microservices and monolith-based applications from my past experiences and projects. Currently interested in media streaming protocols and video processing, and I am always open to any opportunities in this domain.
Skills
Featured Projects
Lox Interpreter
A CLI with four modes: tokenize, parse, evaluate, run
interpreter-go is a tree-walking interpreter for Lox, the toy language from Crafting Interpreters. main.go dispatches to whichever pipeline stage you ask for — scan-only, scan+parse, scan+parse+evaluate a single expression, or run a full program — plus a REPL that falls back from expression parsing to statement parsing when a line isn't a bare expression.
Hand-written lexer with precise error reporting
The scanner walks the raw source byte by byte, no regex or lexer-generator involved, emitting typed tokens while tracking line numbers for accurate error messages. It handles single- and double-character operators, string and number literals, comments, and keyword lookup, and keeps scanning after an error so it can report every bad character in one pass instead of stopping at the first one.
Recursive-descent parsing into a Lisp-style AST
The parser is a straightforward recursive-descent implementation that mirrors Lox's precedence hierarchy: equality falls through to comparison, then term, factor, unary, and primary. Each expression node knows how to print itself, so the 'parse' mode renders the tree as a fully-parenthesized Lisp expression — handy for confirming the parser grouped operators exactly as expected before wiring in evaluation.
Lexical scoping with a linked Environment chain
Variables live in an Environment that holds a map plus a pointer to its enclosing scope, so a block statement can create a child Environment, execute its statements against it, and let lookups fall through to outer scopes on a miss. Get and Assign both walk the chain the same way, which is what makes shadowing and reassignment inside nested blocks behave correctly without any extra bookkeeping in the interpreter itself.
Redis-go
Speaking the real RESP wire protocol
redis-go implements the REdis Serialization Protocol over raw TCP — simple strings, errors, integers, bulk strings, and arrays — so the actual redis-cli binary can connect to it without knowing it isn't talking to real Redis. Reading and writing are split into a Reader and Writer over a buffered connection, with each Value tracking its own encoded byte size so the server can maintain an accurate replication offset later.
One goroutine per connection, command dispatch by RESP array
Every accepted TCP connection gets its own goroutine that keeps reading RESP arrays off the wire and switches on the first bulk string to route PING, GET, SET, DEL, INFO, and the replication commands to their handlers. Writes like SET and DEL also kick off an async propagateMessage call so connected replicas receive the same command, which is the hook the replication layer builds on.
TTL-aware key expiry
SET supports an optional PX argument for millisecond expiry, stored per-entry as an absolute expireDate rather than a countdown. There's no background sweeper — expiry is checked lazily on Load, so a key that's technically expired but never read again costs nothing, while any GET against it correctly reports a miss the instant it's past its deadline.
Leader-follower replication over PSYNC
A replica connects to its master with --replicaof, runs the real handshake (PING, REPLCONF listening-port, REPLCONF capa, PSYNC), and receives an RDB snapshot before switching into a loop that applies every propagated command as if it arrived from a normal client. The master's WAIT command pushes REPLCONF GETACK to every replica and blocks on a channel until enough of them ACK the expected offset, which is the same mechanism real Redis uses to give WAIT a meaningful guarantee instead of a fixed sleep.
SQLite-go
Parsing the 100-byte file header and paging the file
A from-scratch reader for SQLite's on-disk file format. The Pager is the only piece that ever calls ReadAt on the file — it reads the page size straight out of byte offset 16 of the header, and every layer above it just asks for a page number. dbinfo decodes the full 100-byte header struct with encoding/binary and cross-references it against a schema-table scan to report table, index, and view counts.
Recursively walking interior and leaf B-Tree pages
Table data lives in a B-Tree, and scanTable walks it recursively: leaf pages (type 0x0D) hand back rows directly, while interior pages (type 0x05) read the 12-byte header, follow each child pointer plus the right-most pointer, and recurse until they bottom out at leaves. This is the traversal every SELECT is built on top of, whether it's a full scan or a COUNT(*).
Decoding varints and SQLite's tightly-packed record format
Every row is a varint-length header of serial-type codes followed by a body of raw column bytes — no delimiters, no padding. The decoder reads each serial type and knows exactly how many bytes to consume next, whether it's a NULL, one of six integer widths, an IEEE-754 float, or a text/blob column whose length is derived directly from the odd or even serial type number.
A hand-written SQL parser for SELECT ... FROM ... WHERE
sqlparser tokenizes and parses a focused subset of SQL — SELECT with column lists, *, COUNT(*), a single-table FROM, and a single-column '=' WHERE — into a small AST, entirely independent of the storage engine. main.go then resolves each requested column name against the table's CREATE TABLE statement, including the SQLite quirk where an INTEGER PRIMARY KEY column is a rowid alias that isn't actually stored in the row's record.
Other Projects
public-moq-demo
An open-source project of an adaptive video streaming application utilizing QUIC
MEDIS
A webinar marketplace for Doctors and medical staff in Indonesia
Http-go
Simple implementation of HTTP Server made from scratch using Go
Agroaid
An application for detecting diseases in plants
Work Experience
CIMB Niaga
Software Engineer
- Improved document discovery and accessibility by building a file exploration page with full-text and fuzzy search, plus an embedded PDF viewer using pdf.js.
- Ensured data consistency for RAG-based applications by building an automated BullMQ pipeline to ingest and reconcile daily master data updates from an external source.
- Increased transparency of internal AI usage by developing a report dashboard page to visualize internal chat AI application usage for stakeholders.
- Streamlined document ingestion in the internal RAG platform by integrating SharePoint and automating daily synchronization jobs to ensure data consistency.
AwanTunai
Backend Engineer
- Achieved a 60% and 50% reduction in memory and CPU consumption by upgrading multiple services from Java 8 to Java 21 and Spring Boot 2 to Spring Boot 3.
- Improved homepage load time by 50%, reducing p50 latency from 1.4s to 0.7s by rewriting slow MongoDB queries and utilizing asynchronous processing.
- Automated invoice validation and fraud detection by developing a feature to allow users to upload invoices, assess data accuracy, and flag suspicious submissions using machine learning.
- Increased loan applications by developing an automated location-based application feature, enabling users in assigned regions to submit loan applications without requiring sales assistance.
AwanTunai
Backend Engineer Intern
- Satisfied regulatory (OJK) compliance by developing a lender login and registration page and enhancing the risk and compliance verification feature using Spring Boot and MongoDB.
- Satisfied regulatory (OJK) compliance by developing a notification centre for the whole loan submission and disbursement flow using Firebase Cloud Messaging and RabbitMQ.
- Automated loan document signing for lenders by integrating the internal service with a digital identity and signature provider, Privy.
Faculty of Medicine
Software Developer Intern
- Enabled end-to-end medical webinar delivery by developing MEDIS using Spring Boot and integrating with the Zoom Meeting API for automated webinar creation, access, and live session management.
- Automated webinar ticket payments by integrating the platform with the Midtrans Payment Gateway to handle transactions, payment status updates, and purchase history.
- Improved security and usability for multiple user roles by implementing role-based access control workflows across webinar management features.
Bangkit Academy
Cloud Computing Cohort
- Built a plant disease detection application using Node.js, integrating machine learning models for real-time automated diagnosis.
- Deployed and managed containerized applications on Google Kubernetes Engine as part of the Google Cloud Engineer learning path.
- Managed Google Cloud Platform resources across computing, storage, networking, and machine learning, completing 900+ hours of coursework.
Education
University of Indonesia
Bachelor's Degree in Computer Science
- Relevant Coursework: Information System Development Project, Enterprise Applications & Architectures, Data Structures & Algorithm, Databases, Computer Network, Operating System.
Exam Certification Passed

Associate Cloud Engineer
Passed the Associate Cloud Engineer Exam from Google Cloud

Problem Solving (Intermediate)
Passed the Problem Solving Intermediate Exam from Hackerrank

Java (Basic)
Passed the Java Basic Exam from Hackerrank
Course Completed

Google Cloud Skills Boost
Completed courses and lab challenges about Google Cloud Platform, Kubernetes, and Terraform

Coursera
Completed courses about Computer Networking, System Administration, and Machine Learning

Dicoding
Completed courses about Back End Engineering, Cloud Engineering, and Programming Languages

Udemy
Completed a course about backend communication design patterns, protocols, execution and proxying

AWS Skill Builder
Completed courses and assessment about cloud essentials in AWS

Cisco Networking Academy
Completed a course about introduction to Cybersecurity