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
- Reduced document retrieval time from up to 5 seconds to under 0.7 seconds by building a document exploration platform with full-text search, fuzzy search, and an embedded PDF viewer using pdf.js.
- Improved data consistency for internal RAG applications by designing and implementing an automated BullMQ pipeline to synchronize daily master data from external systems.
- Enabled stakeholders to monitor AI adoption by developing an analytics dashboard to visualize internal AI application usage and trends.
- Automated document ingestion for the internal RAG platform by integrating SharePoint and implementing scheduled synchronization jobs to maintain an up-to-date knowledge base.
AwanTunai
Backend Engineer
- Reduced memory consumption by 60% and CPU utilization by 50% by migrating multiple backend services from Java 8 to Java 21 and Spring Boot 2 to Spring Boot 3.
- Reduced homepage p50 latency from 1.4 seconds to 0.7 seconds by optimizing MongoDB queries and introducing asynchronous request processing.
- Automated invoice verification and flagged suspicious submissions by developing a machine-learning-assisted validation pipeline.
- Simplified customer onboarding by developing a location-aware loan application workflow that enabled eligible customers to apply without sales assistance.
AwanTunai
Backend Engineer Intern
- Supported OJK regulatory compliance by developing a lender onboarding platform and implementing risk and compliance verification workflows using Spring Boot and MongoDB.
- Automated lender document signing by integrating Privy digital signature services, reducing manual verification and document processing effort.
- Delivered real-time loan submission and disbursement notifications by building an event-driven notification service using RabbitMQ and Firebase Cloud Messaging.
Faculty of Medicine
Software Developer Intern
- Built MEDIS, an end-to-end medical webinar platform using Spring Boot and React with Zoom Meeting API integration for automated webinar creation, scheduling, and management.
- Automated webinar payment processing by integrating the Midtrans Payment Gateway with transaction status updates and purchase history management.
- Implemented role-based authorization to support administrators, speakers, and participants across the webinar platform.
Bangkit Academy
Cloud Computing Cohort
- Built a plant disease detection application using Node.js and machine learning models for real-time 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 while completing over 900 hours of cloud computing coursework.
Education
University of Indonesia
Bachelor's Degree in Computer Science
- Relevant Coursework: Information System Development Project, Enterprise Applications & Architectures, Data Structures & Algorithms, Databases, Computer Networks, Operating Systems.
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