💡 Key Takeaways
- The First 30 Seconds: What the PR Description Tells Me
- The Logic Layer: Does This Actually Solve the Problem?
- The Data Layer: Following the Information Flow
- The Security Lens: Thinking Like an Attacker
Tiga tahun yang lalu, saya menyetujui permintaan tarik yang menyebabkan perusahaan saya kehilangan pendapatan sebesar $47.000 hanya dalam satu akhir pekan. Kode tersebut terlihat baik. Uji coba berhasil. Logikanya tepat. Namun saya melewatkan sesuatu yang halus dalam cara kami menangani konversi zona waktu untuk pelanggan Eropa kami, dan ketika waktu musim panas mulai berlaku, sistem pemrosesan pembayaran kami mulai gagal diam-diam untuk 18% dari basis pengguna kami.
💡 Poin Penting
- 30 Detik Pertama: Apa yang Diberitahukan Deskripsi PR kepada Saya
- Lapisan Logika: Apakah Ini Benar-benar Menyelesaikan Masalah?
- Lapisan Data: Mengikuti Aliran Informasi
- Lensa Keamanan: Berpikir Seperti Penyerang
Insiden itu mengubah cara saya meninjau kode selamanya. Saya Sarah Chen, dan saya telah menjadi manajer teknik senior di tiga perusahaan SaaS berbeda selama dekade terakhir, meninjau rata-rata 15-20 permintaan tarik per minggu. Itu sekitar 8.000 PR dalam karir saya, mulai dari perbaikan hotfix satu baris hingga refactor arsitektural besar yang melibatkan lebih dari 50 file. Saya telah melihat kode brilian yang mengirimkan bug, dan kode berantakan yang berjalan tanpa cacat di produksi selama bertahun-tahun.
Yang saya pelajari adalah bahwa tinjauan kode sebenarnya bukan hanya tentang menemukan bug—meskipun itu penting. Ini tentang membangun sistem yang bertahan ketika berhadapan dengan kenyataan. Ini tentang menciptakan kode yang dapat dipahami dan dimodifikasi oleh pengembang berikutnya (seringkali diri Anda sendiri enam bulan kemudian) tanpa rasa takut. Dan ini tentang menangkap masalah tak terlihat yang hanya terungkap ketika aplikasi Anda berkembang, ketika kasus pinggir muncul, atau ketika satu pelanggan di Australia melakukan sesuatu yang tidak pernah Anda duga.
Ini adalah daftar periksa saya. Bukan yang teoretis dari buku teks, tetapi yang telah teruji dalam pertempuran yang telah saya perbaiki melalui berbagai insiden produksi, sesi debugging hingga larut malam, dan perasaan tertekan saat Anda menyadari bahwa bug yang Anda setujui sekarang mempengaruhi pengguna nyata.
30 Detik Pertama: Apa yang Diberitahukan Deskripsi PR kepada Saya
Sebelum saya melihat satu baris kode pun, saya menghabiskan 30 detik membaca deskripsi PR. Ini mungkin terlihat sepele, tetapi deskripsi yang ditulis dengan buruk sering kali menjadi tanda merah pertama bahwa kode itu sendiri mungkin memiliki masalah. Dari pengalaman saya, pengembang yang tidak dapat mengartikulasikan dengan jelas apa yang dilakukan kode mereka sering kali belum sepenuhnya memikirkan implementasinya.
Saya mencari tiga hal spesifik: masalah yang diselesaikan, pendekatan yang diambil, dan kompromi yang dibuat. Deskripsi PR yang baik terbaca seperti dokumen desain mini. "Memperbaiki bug dalam autentikasi pengguna" tidak memberi tahu saya apa-apa. "Memperbaiki kondisi balapan dalam penyegaran token JWT yang menyebabkan 0,3% pengguna ter-log out secara tak terduga selama periode lalu lintas tinggi dengan menerapkan kunci terdistribusi menggunakan Redis" memberi tahu saya bahwa pengembang memahami masalah tersebut dengan mendalam.
Saya juga memeriksa apakah PR tersebut memiliki ukuran yang tepat. Aturan praktis saya: jika suatu PR menyentuh lebih dari 400 baris kode (tidak termasuk tes dan file yang dihasilkan), kemungkinan besar terlalu besar untuk ditinjau secara efektif. Penelitian dari praktik teknik Google menunjukkan bahwa efektivitas tinjauan menurun drastis setelah 200-400 baris. Saya menemukan ini akurat—setelah meninjau sekitar 300 baris, perhatian saya mulai terganggu, dan saya mulai melewatkan masalah-masalah halus.
Ketika saya menghadapi PR besar, saya meminta pengembang untuk membaginya menjadi bagian yang lebih kecil dan logis. Ya, ini membutuhkan waktu lebih banyak di awal, tetapi ini mencegah skenario di mana saya menyetujui PR 2.000 baris karena saya kewalahan dan hanya ingin cepat menyelesaikannya. Saya telah menyetujui terlalu banyak PR bermasalah dengan cara ini di awal karir saya.
Deskripsi juga harus menghubungkan konteks yang relevan: tiket atau masalah yang sedang ditangani, dokumen desain, dan PR terkait. Jika saya harus mencari melalui Jira atau Slack untuk memahami mengapa perubahan ini dibuat, itu adalah gesekan yang memperlambat seluruh proses tinjauan. Di perusahaan saya saat ini, kami membuat kebijakan bahwa PR tanpa konteks yang tepat tidak akan ditinjau sampai deskripsi diperbarui. Aturan sederhana ini telah meningkatkan kualitas tinjauan kami secara signifikan.
Lapisan Logika: Apakah Ini Benar-benar Menyelesaikan Masalah?
Setelah saya memahami apa yang seharusnya dilakukan PR tersebut, saya memverifikasi bahwa itu benar-benar melakukannya. Ini terdengar jelas, tetapi Anda akan terkejut betapa seringnya kode melewati tes tetapi tidak sepenuhnya menangani masalah yang mendasarinya. Saya telah melihat pengembang memperbaiki gejala sementara meninggalkan penyebab utama tanpa tersentuh, menciptakan bom waktu yang akan meledak kemudian.
"Tinjauan kode sebenarnya bukan hanya tentang menemukan bug—ini tentang membangun sistem yang bertahan ketika berhadapan dengan kenyataan dan menciptakan kode yang dapat dipahami oleh pengembang berikutnya tanpa rasa takut."
Saya mulai dengan berjalan secara mental melalui jalur bahagia. Jika ini adalah fitur baru untuk memproses pengembalian dana, saya membayangkan seorang pelanggan meminta pengembalian dana dan melacak jalur kode dari titik akhir API melalui logika bisnis hingga pembaruan basis data. Apakah setiap langkah masuk akal? Apakah kita menangani data dengan benar? Apakah kita mengupdate semua catatan yang diperlukan?
Tetapi jalur bahagia itu mudah. Apa yang memisahkan kode yang baik dari kode yang siap produksi adalah bagaimana ia menangani jalur yang tidak bahagia. Apa yang terjadi jika gerbang pembayaran tidak berfungsi? Apa yang terjadi jika jumlah pengembalian dana negatif? Apa yang terjadi jika pengguna meminta pengembalian dana untuk pesanan yang sudah dikembalikan? Saya telah belajar untuk hampir paranoid tentang kasus tepi karena lingkungan produksi adalah mesin kekacauan yang akan menemukan setiap kasus tepi yang belum Anda pertimbangkan.
Saya mencari pola pemrograman defensif: pemeriksaan nol, validasi input, penanganan kondisi batas. Tetapi saya juga mencari kelebihan rekayasa. Tidak setiap fungsi perlu menangani setiap kemungkinan kasus tepi. Jika metode privat hanya dipanggil dari satu tempat dengan input yang divalidasi, menambahkan validasi redundan hanya akan menjadi kebisingan. Kuncinya adalah memahami kontrak setiap fungsi dan memastikan itu dipenuhi di batasnya.
Satu pola yang sering menyebabkan masalah adalah "pembaruan optimis." Seorang pengembang mengasumsikan operasi akan berhasil dan memperbarui UI atau status basis data sebelum mengonfirmasi keberhasilan. Ini berfungsi 99% dari waktu, tetapi 1% membuat bug yang sangat membingungkan di mana status sistem menjadi tidak konsisten. Saya selalu menandai pola ini dan bertanya: apa yang terjadi jika operasi ini gagal di pertengahan jalan?
Lapisan Data: Mengikuti Aliran Informasi
Bug data adalah jenis bug terburuk karena sering kali diam dan kumulatif. Kesalahan logika mungkin langsung menghentikan aplikasi Anda, tetapi kesalahan data mungkin secara perlahan merusak basis data Anda selama berminggu-minggu, dan begitu Anda menyadarinya, Anda memiliki ribuan catatan buruk dan tidak ada cara bersih untuk memperbaikinya.
| Fokus Tinjauan | Reviewer Junior | Reviewer Senior | Dampak pada Produksi |
|---|---|---|---|
| Sintaks & Gaya | Fokus utama | Perhatian otomatis/minimal | Rendah |
| Kasus Pinggir | Hanya skenario yang jelas | Masalah zona waktu, lokal, dan skala | Tinggi |
| Penutupan Uji | Uji ada dan berhasil | Uji mencakup mode kegagalan | Kritis |
| Kinerja | Kode bekerja dengan benar | Perilaku di bawah beban/skala | Tinggi |
| Dokumentasi | Komentar ada | Alasan keputusan dibuat | Sedang |
Ketika meninjau kode yang menyentuh data, saya melacak seluruh siklus hidup data tersebut. Dari mana asalnya? Bagaimana validasinya? Bagaimana transformasinya? Di mana disimpan? Siapa yang dapat mengaksesnya? Ini sangat penting untuk konten yang dihasilkan pengguna atau data keuangan di mana kesalahan memiliki konsekuensi nyata.
Saya memperhatikan khusus pada konversi tipe data. Saya pernah menyetujui kode yang mengonversi harga dari float ke integer untuk perhitungan, lalu kembali lagi ke float. Terlihat tidak berbahaya. Tetapi karena masalah presisi floating-point, harga seperti $10,99 kadang-kadang berubah menjadi $10,98 atau $11,00 setelah perjalanan pulang. Kami tidak menangkapnya sampai pelanggan mulai mengeluh tentang pembayaran yang salah. Sekarang saya memeriksa setiap konversi tipe, terutama yang melibatkan uang atau ukuran.
Migrasi basis data adalah area lain di mana saya ekstra berhati-hati. Saya mencari beberapa hal: Apakah migrasi dapat dibalik? Apa yang terjadi jika gagal di pertengahan jalan? Berapa lama waktu yang dibutuhkan di basis data produksi kami? Saya telah melihat migrasi yang berjalan baik di basis data pengembangan dengan 1.000 catatan tetapi mengunci tabel selama 20 menit di basis data produksi dengan 50 juta catatan, menonaktifkan seluruh aplikasi.
Untuk setiap kode yang mengubah data yang ada, saya bertanya: apakah ada rencana cadangan? Dapatkah kita membalikkan ini jika ada yang salah? Di perusahaan saya sebelumnya, kami memiliki kebijakan bahwa setiap migrasi data yang mempengaruhi lebih dari 10.000 catatan membutuhkan pengujian awal pada snapshot produksi dan prosedur pemulihan yang jelas didokumentasikan dalam PR. Ini telah menyelamatkan kami berkali-kali.
Saya juga melihat pola akses data. Apakah kode ini melakukan N+1 kueri? Apakah ia memuat seluruh koleksi ke memori ketika hanya membutuhkan beberapa field? Masalah kinerja ini mungkin tidak terlihat jelas di pengembangan tetapi menjadi kritis saat skala. Saya pernah meninjau kode yang tampaknya baik tetapi akan menyebabkan CPU basis data kami melonjak sampai 100% jika dikirim ke produksi, hanya karena itu adalah