66 poin oleh GN⁺ 2025-08-18 | 1 komentar | Bagikan ke WhatsApp
  • Merangkum jebakan yang tidak intuitif dan sering dialami developer, serta memperkenalkan penyebab bug yang mudah terjadi
  • Membahas masalah yang sering muncul di berbagai teknologi seperti HTML, CSS, Unicode/encoding teks, floating-point, waktu, dan lainnya
  • Menekankan bahwa perbedaan halus dalam sintaks dan perilaku di setiap bahasa dan framework dapat menimbulkan salah paham atau error
  • Menjelaskan dengan contoh jebakan di area inti backend seperti concurrency, networking, database yang dapat terjadi di lingkungan produksi nyata
  • Melalui beragam contoh dan tautan referensi, memandu situasi masalah, solusi, serta perbaikan terhadap perilaku tak terduga

HTML dan CSS

  • Nilai default min-width di Flexbox/Grid

    • min-width secara default adalah auto
    • min-width: auto ditentukan oleh ukuran konten, dan diterapkan lebih dulu daripada flex-shrink, overflow: hidden, width: 0, max-width: 100%
    • Rekomendasi: nyatakan min-width: 0
  • Perbedaan horizontal dan vertikal di CSS

    • width: auto berusaha mengisi ruang parent, sedangkan height: auto menyesuaikan konten
    • width: auto pada elemen inline, inline-block, dan float tidak melebar
    • margin: 0 auto memusatkan secara horizontal, margin: auto 0 tidak bisa memusatkan secara vertikal (namun pada flex-direction: column, pemusatan vertikal dimungkinkan)
    • Margin collapsing hanya terjadi secara vertikal
    • Jika arah layout berubah seperti writing-mode: vertical-rl, perilakunya juga terbalik
  • Block Formatting Context (BFC)

    • Buat BFC dengan display: flow-root (selain itu overflow: hidden/auto/scroll, display: table, dll. juga bisa, tetapi ada efek samping)
    • Margin sibling vertikal yang saling berdekatan bertumpuk, atau margin child yang bocor ke luar parent, dapat dicegah dengan BFC
    • Jika parent hanya berisi child float, tingginya akan kolaps menjadi 0 → bisa diperbaiki dengan BFC
    • Jika ada border atau padding, margin collapsing tidak terjadi
  • Stacking Context

    • Kondisi yang membuat stacking context baru
      • Properti rendering seperti transform, filter, perspective, mask, opacity
      • position: fixed atau sticky
      • z-index ditentukan + posisi absolute/relative
      • z-index ditentukan + elemen di dalam flexbox/grid
      • isolation: isolate
    • Karakteristik
      • z-index hanya berlaku di dalam stacking context tersebut
      • Koordinat position: absolute/fixed didasarkan pada ancestor terdekat yang positioned
      • sticky tidak bekerja melampaui stacking context
      • overflow: visible pun tetap terpotong oleh stacking context
      • background-attachment: fixed diposisikan berdasarkan stacking context
  • Satuan viewport

    • Di browser mobile, saat address bar/navigation bar hilang dari layar ketika discroll, nilai 100vh ikut berubah
    • Solusi terbaru: gunakan 100dvh
  • Acuan posisi Absolute

    • position: absolute tidak mengacu ke parent, melainkan ke ancestor relative/absolute atau stacking context terdekat
  • Perilaku Blur

    • backdrop-filter: blur tidak mempertimbangkan elemen di sekitarnya
  • Float dinonaktifkan

    • Jika parent adalah flex atau grid, float pada child tidak berpengaruh
  • Satuan persen untuk width/height

    • Tidak berfungsi jika ukuran parent belum ditentukan sebelumnya (untuk menghindari referensi siklik)
  • Karakteristik elemen inline

    • display: inline mengabaikan width, height, margin-top, margin-bottom
  • Penanganan whitespace

    • Secara default, line break di HTML diperlakukan sebagai spasi, dan spasi berurutan dipadatkan menjadi satu
    • `` mencegah pemadatan spasi, tetapi perilaku awal/akhirnya khas
    • Pada kebanyakan konten, spasi di awal/akhir diabaikan, tetapi `` adalah pengecualian
    • Spasi/line break di antara inline-block ditampilkan sebagai jarak nyata (tidak terjadi pada flex/grid)
  • text-align

    • Berlaku untuk perataan teks dan elemen inline, tetapi tidak untuk perataan elemen block
  • box-sizing

    • Nilai default adalah content-box → tidak termasuk padding/border
    • Saat width: 100% + padding ditetapkan, elemen bisa melampaui area parent
    • Solusi: box-sizing: border-box
  • Cumulative Layout Shift

    • Jika atribut width dan height tidak ditentukan pada ``, keterlambatan loading gambar dapat menyebabkan layout bergeser
    • Rekomendasi: tentukan atribut tersebut untuk mencegah CLS
  • Permintaan jaringan untuk download file di Chrome

    • Tidak ditampilkan di panel Network DevTools (diproses di tab lain)
    • Jika perlu analisis, gunakan chrome://net-export/
  • Masalah parsing JavaScript di dalam HTML

Unicode dan Encoding Teks

  • Code point dan grapheme cluster

    • Grapheme cluster adalah “unit karakter” pada GUI
    • Karakter ASCII yang terlihat terdiri dari 1 code point = 1 grapheme cluster
    • Emoji bisa menjadi satu grapheme cluster yang tersusun dari beberapa code point
    • Di UTF-8, code point berukuran 1~4 byte, dan jumlah byte tidak sama dengan jumlah code point
    • Di UTF-16, code point berukuran 2 byte atau 4 byte (surrogate pair)
    • Standar tidak membatasi jumlah code point dalam cluster, tetapi implementasi sering memberi batas demi performa
  • Perbedaan perilaku string antarbahasa

    • Rust: string internal menggunakan UTF-8, len() adalah jumlah byte, indexing langsung tidak bisa, chars().count() adalah jumlah code point, validitas UTF-8 diverifikasi ketat
    • Golang: string pada dasarnya adalah array byte, panjang dan indexing berbasis byte, umumnya menggunakan UTF-8
    • Java, C#, JS: berbasis UTF-16, panjang diukur per 2 byte, indexing juga per 2 byte, ada surrogate pair
    • Python: len() mengembalikan jumlah code point, indexing mengembalikan string yang berisi satu code point
    • C++: std::string tidak memiliki batasan encoding, berperilaku seperti vektor byte, panjang/indexing berbasis byte
    • Dari bahasa-bahasa yang disebutkan, tidak ada yang menghitung panjang/indexing berdasarkan grapheme cluster
  • BOM (Byte Order Mark)

    • Beberapa file teks memiliki BOM, misalnya EF BB BF → penanda encoding UTF-8
    • Umumnya digunakan di Windows, dan software non-Windows mungkin tidak dapat menangani BOM
  • Hal lain yang perlu diperhatikan

    • Saat data biner diubah menjadi string, bagian yang tidak valid akan diganti dengan � (U+FFFD)
    • Ada confusable characters (karakter yang terlihat mirip satu sama lain)
    • Normalisasi (Normalization): misalnya, é dapat direpresentasikan sebagai U+00E9 (satu code point) atau U+0065+U+0301 (dua code point)
    • Ada zero-width characters dan invisible characters
    • Perbedaan line break: Windows menggunakan CRLF \r\n, Linux/MacOS menggunakan LF \n
    • Han unification: karakter yang bentuknya sedikit berbeda di tiap bahasa memakai code point yang sama
      • Font merender dengan tepat dengan menyertakan variasi per bahasa
      • Dalam internasionalisasi, perlu memilih variasi font yang benar

Floating point

  • Karakteristik NaN

    • NaN tidak sama dengan nilai apa pun, termasuk dirinya sendiri (NaN == NaN selalu false)
    • NaN != NaN selalu true
    • Hasil operasi yang melibatkan NaN umumnya akan tetap menjadi NaN
  • Nilai khusus

    • Ada +Inf dan -Inf, berbeda dari NaN
    • -0.0 adalah nilai yang dibedakan dari +0.0
      • Dalam operasi perbandingan keduanya sama, tetapi pada beberapa perhitungan berperilaku berbeda
      • Contoh: 1.0 / +0.0 == +Inf, 1.0 / -0.0 == -Inf
  • Kompatibilitas dengan JSON

    • Standar JSON tidak mengizinkan NaN dan Inf
      • JS JSON.stringify mengubah NaN dan Inf menjadi null
      • Python json.dumps(...) mencetak NaN dan Infinity apa adanya (melanggar standar)
        • Jika opsi allow_nan=False digunakan, keberadaan NaN/Inf akan memunculkan ValueError
      • Golang json.Marshal mengembalikan error jika ada NaN/Inf
  • Masalah presisi

    • Perbandingan langsung floating point bisa gagal → bentuk abs(a - b) < ε disarankan
    • JS memperlakukan semua angka sebagai floating point
      • Rentang integer aman adalah -(2^53 - 1) ~ 2^53 - 1
      • Di luar rentang ini, representasi integer menjadi tidak akurat
      • Untuk integer besar, disarankan menggunakan BigInt
      • Jika JSON berisi integer di luar rentang aman, nilai hasil JSON.parse bisa tidak akurat
      • Timestamp dalam milidetik aman hingga 287.396 tahun, sedangkan dalam nanodetik akan menimbulkan masalah
  • Hukum operasi tidak selalu berlaku

    • Bergantung pada urutan operasi, kehilangan presisi dapat membuat hukum asosiatif dan distributif tidak berlaku secara ketat
    • Operasi paralel (perkalian matriks, penjumlahan, dll.) dapat menghasilkan hasil nondeterministik
  • Performa

    • Pembagian jauh lebih lambat daripada perkalian
    • Jika membagi berkali-kali dengan angka yang sama, bisa dioptimalkan dengan menghitung kebalikannya terlebih dahulu lalu mengalikan
  • Perbedaan menurut hardware

    • Dukungan FMA (Fused Multiply-Add): beberapa hardware melakukan perhitungan antara dengan presisi lebih tinggi
    • Penanganan subnormal range: hardware modern mendukungnya, tetapi beberapa hardware lama memperlakukannya sebagai 0
    • Perbedaan mode pembulatan
      • Ada RNTE (round to nearest ties to even), RTZ (round toward zero), dan lainnya
      • x86/ARM dapat mengaturnya sebagai status mutable thread-local
      • GPU memiliki mode pembulatan yang berbeda per instruksi
    • Perbedaan perilaku fungsi matematika seperti trigonometri dan logaritma
    • x86 memiliki FPU 80-bit legacy dan per-core rounding mode → tidak disarankan digunakan
    • Selain itu, berbagai faktor lain juga dapat membuat hasil floating point berbeda antar-hardware
  • Cara meningkatkan presisi

    • Susun graph perhitungan lebih dangkal (kurangi struktur perkalian berantai)
    • Hindari kasus ketika nilai antara menjadi sangat besar atau sangat kecil
    • Manfaatkan operasi hardware seperti FMA

Waktu (Time)

  • Leap second

    • Timestamp Unix mengabaikan leap second
    • Saat leap second terjadi, waktu di sekitar interval tersebut bisa memanjang atau memendek (leap smear)
  • Zona waktu (Time zone)

    • UTC dan timestamp Unix bersifat sama di seluruh dunia
    • Waktu yang dibaca manusia bergantung pada zona waktu tiap wilayah
    • Disarankan menyimpan timestamp di DB lalu mengonversinya di UI
  • Daylight saving time (DST)

    • Di beberapa wilayah, jam disesuaikan 1 jam selama musim panas
  • Sinkronisasi NTP

    • Selama proses sinkronisasi, waktu bisa berada dalam situasi "mundur"
  • Pengaturan zona waktu server

    • Server disarankan diatur ke UTC
    • Dalam sistem terdistribusi, perbedaan zona waktu antar-node dapat menimbulkan masalah
    • Setelah mengubah zona waktu sistem, DB perlu dikonfigurasi ulang atau direstart
  • Jam hardware vs jam sistem

    • Jam hardware tidak memiliki konsep zona waktu
    • Linux: memperlakukan jam hardware sebagai UTC
    • Windows: memperlakukan jam hardware sebagai waktu lokal

Java

  • == membandingkan referensi objek, untuk membandingkan isi objek perlu memakai .equals
  • Jika equals dan hashcode tidak dioverride, map/set akan menilai identitas objek berdasarkan referensi
  • Jika isi objek key pada map atau elemen objek pada set diubah, perilaku container akan rusak
  • Metode yang mengembalikan List dalam beberapa kasus dapat mengembalikan ArrayList yang mutable atau Collections.emptyList() yang immutable; jika yang kedua dimodifikasi akan muncul UnsupportedOperationException
  • Ada metode yang mengembalikan Optional tetapi justru me-return null (tidak disarankan)
  • Jika melakukan return di blok finally, exception yang terjadi di try atau catch akan diabaikan dan nilai return dari finally yang akan dipakai
  • Ada library yang mengabaikan interrupt, dan proses inisialisasi class termasuk I/O bisa rusak karena interrupt
  • Exception pada task yang dikirim ke thread pool dengan .submit() pada dasarnya tidak dicetak ke log dan hanya bisa diperiksa lewat future; jika future diabaikan, exception tidak bisa diketahui
    • Pekerjaan scheduleAtFixedRate akan berhenti diam-diam saat exception terjadi
  • Literal angka yang diawali 0 diperlakukan sebagai oktal (0123 → 83)
  • Debugger memanggil .toString() dari variabel lokal, dan pada beberapa class toString() memiliki efek samping sehingga perilaku kode bisa berubah saat debugging (dapat dinonaktifkan di IDE)

Golang

  • append() menggunakan kembali memori jika capacity masih tersedia; append pada subslice dapat menimpa memori induknya juga
  • defer dijalankan saat fungsi return, bukan saat scope blok berakhir
  • defer menangkap variabel mutable
  • Terkait nil
    • nil slice dan empty slice berbeda
    • string tidak bisa nil, hanya ada string kosong
    • nil map bisa dibaca tetapi tidak bisa ditulis
    • Ada perilaku khusus pada interface nil: jika data pointer null tetapi type info tidak null, nil tersebut tidak dianggap sama dengan nil
  • Dead wait: ada kasus bug konkurensi nyata di Go
  • Ada berbagai jenis timeout, dibahas lebih rinci di net/http

C/C++

  • Jika menyimpan pointer ke elemen std::vector lalu vector membesar, akan terjadi realokasi dan pointer menjadi tidak valid
  • std::string yang dibuat dari string literal bisa jadi merupakan objek sementara, sehingga memanggil c_str() berisiko
  • Jika container dimodifikasi saat iterasi, iterator bisa menjadi tidak valid
  • std::remove tidak benar-benar menghapus, melainkan hanya menyusun ulang elemen; untuk menghapus tetap perlu erase
  • Jika literal angka diawali 0, angka itu diperlakukan sebagai oktal (0123 → 83)
  • Undefined behavior (UB): selama proses optimisasi, UB bisa diubah secara bebas sehingga berbahaya jika dijadikan sandaran
    • Mengakses memori yang belum diinisialisasi adalah UB
    • Mengubah char* menjadi pointer struct lalu mengaksesnya sebelum masa hidup objek dimulai adalah UB; disarankan inisialisasi dengan memcpy
    • Akses memori yang tidak valid (seperti pointer null) adalah UB
    • Overflow/underflow integer adalah UB (untuk unsigned, underflow ke bawah 0 bisa terjadi)
    • Aliasing: jika pointer dari tipe berbeda mereferensikan memori yang sama, strict aliasing rule dapat menyebabkan UB
      • Pengecualian: 1) tipe dengan hubungan pewarisan 2) konversi char*, unsigned char*, std::byte* (konversi balik tidak berlaku)
      • Untuk konversi paksa, disarankan memakai memcpy atau std::bit_cast
    • Akses unaligned memory adalah UB
  • Alignment memori
    • Integer 64-bit harus berada pada alamat yang habis dibagi 8
    • Pada ARM, akses unaligned bisa menyebabkan crash
    • Jika byte buffer langsung ditafsirkan sebagai struct, masalah alignment bisa muncul
    • Alignment dapat menimbulkan struct padding sehingga memboroskan memori
    • Beberapa instruksi SIMD (seperti AVX) hanya bisa memproses data yang ter-align; biasanya memerlukan alignment 32-byte

Python

  • Argumen default fungsi tidak dibuat ulang setiap kali dipanggil, melainkan nilai awalnya tetap disimpan

SQL Databases

  • Penanganan Null

    • x = null tidak berfungsi; harus menggunakan x is null
    • Null tidak sama dengan dirinya sendiri (mirip NaN)
    • Unique index mengizinkan duplikasi Null (kecuali Microsoft SQL Server)
    • Cara select distinct menangani Null berbeda-beda tergantung DB
    • count(x) dan count(distinct x) mengabaikan baris yang nilai Null
  • Perilaku umum

    • Konversi implisit tanggal bisa bergantung pada timezone
    • Join kompleks + distinct bisa lebih lambat daripada query bersarang
    • Di MySQL(InnoDB), jika field string bukan utf8mb4, penyisipan karakter UTF-8 4-byte akan memicu error
    • MySQL(InnoDB) secara default tidak membedakan huruf besar/kecil
    • MySQL(InnoDB) mengizinkan konversi implisit: select '123abc' + 1; → 124
    • Gap lock di MySQL(InnoDB) dapat memicu deadlock
    • Di MySQL(InnoDB), jika kolom group by dan kolom select tidak cocok, hasil yang dikembalikan bisa non-deterministik
    • Di SQLite, jika bukan strict, tipe field pada dasarnya tidak terlalu bermakna
    • Foreign key dapat memicu lock implisit dan menyebabkan deadlock
    • Locking bisa merusak repeatable read isolation tergantung DB
    • Distributed SQL DB bisa saja tidak mendukung locking atau punya perilaku khusus (berbeda-beda per DB)
  • Performa/operasional

    • Masalah query N+1 tidak muncul di slow query log karena tiap query-nya cepat
    • Transaksi yang berjalan lama dapat memicu masalah lock dan lain-lain → disarankan transaksi diselesaikan secepat mungkin
    • Contoh kasus full table lock
      • Di MySQL 8.0+, penambahan unique index/foreign key umumnya bisa diproses secara konkuren
      • MySQL versi lama bisa memicu full table lock
      • Jika mysqldump tidak memakai opsi --single-transaction, akan terjadi full table read lock
      • Di PostgreSQL, create unique index atau alter table ... add foreign key memicu full table read lock
        • Cara menghindari: gunakan create unique index concurrently
        • Untuk foreign key, gunakan pendekatan ... not valid lalu validate constraint
  • Query range

    • Range yang tidak tumpang tindih:
      • Kondisi sederhana p >= start and p file 2>&1 → stdout+stderr keduanya ke file, cmd 2>&1 > file → hanya stdout ke file, stderr tetap seperti semula
  • Nama file membedakan huruf besar-kecil (berbeda dengan Windows)

  • File executable memiliki sistem capability (getcap untuk memeriksanya)

  • Bahaya variabel unset: jika DIR unset maka rm -rf $DIR/ berisiko menjalankan rm -rf / → bisa dicegah dengan set -u

  • Penerapan environment: untuk menerapkan skrip ke shell saat ini gunakan source script.sh → untuk penerapan permanen tambahkan ke ~/.bashrc

  • Bash melakukan caching perintah: jika file di dalam $PATH dipindahkan bisa muncul ENOENT → segarkan cache dengan hash -r

  • Jika variabel digunakan tanpa tanda kutip, baris baru akan diperlakukan sebagai spasi

  • set -e: langsung keluar saat skrip error, tetapi tidak bekerja di dalam kondisi (||, &&, if)

  • Konflik antara livenessProbe K8s dan debugger: debugger berbasis breakpoint menghentikan seluruh aplikasi sehingga health check gagal mendapat respons → Pod bisa dihentikan

React

  • Memodifikasi state secara langsung di kode rendering
  • Menggunakan Hook di dalam if/loop → melanggar aturan
  • Ada nilai yang diperlukan tetapi terlewat dari dependency array useEffect
  • Tidak ada kode clean up di useEffect
  • Jebakan closure: bug terjadi karena menangkap state lama
  • Mengubah data di tempat yang salah → komponen tidak murni
  • Tidak menggunakan useCallback → menyebabkan rerender yang tidak perlu
  • Saat nilai yang tidak dimemoisasi dikirim ke komponen yang dimemoisasi, optimasi memo menjadi tidak efektif

Git

  • Rebase adalah penulisan ulang histori

    • Setelah rebase, push biasa akan bentrok → harus force push
    • Jika histori branch remote berubah, gunakan juga --rebase saat pull
    • --force-with-lease dalam beberapa kasus dapat mencegah commit developer lain tertimpa, tetapi jika hanya fetch dan tidak pull perlindungan ini tidak berlaku
  • Masalah revert merge

    • Revert merge efeknya tidak sempurna → saat branch yang sama di-merge lagi tidak ada perubahan apa pun
    • Solusi: lakukan revert atas revert tersebut, atau gunakan cara yang lebih bersih (backup → reset → cherry-pick → force push)
  • Hal yang perlu diperhatikan terkait GitHub

    • Walau secret seperti API key ditimpa dengan force push setelah sempat di-commit, rekamannya tetap tersimpan di GitHub
    • Jika B adalah fork private dari repo private A, lalu A menjadi public, isi B juga akan ikut terbuka (tetap bisa diakses bahkan setelah dihapus)
  • git stash pop: jika terjadi conflict, stash tidak akan di-drop

  • .DS_Store dibuat otomatis oleh macOS → disarankan menambahkan **/.DS_Store ke .gitignore

Networking

  • Beberapa router dan firewall memutus koneksi TCP idle secara diam-diam → connection pool pada klien HTTP atau DB bisa menjadi tidak valid → solusi: atur TCP keepalive
  • Hasil traceroute kurang andal → dalam beberapa kasus tcptraceroute lebih berguna
  • TCP slow start bisa menyebabkan latensi meningkat → dapat diatasi dengan menonaktifkan tcp_slow_start_after_idle
  • Masalah TCP sticky packet: algoritma Nagle menunda pengiriman paket → bisa diatasi dengan mengaktifkan TCP_NODELAY
  • Saat menaruh backend di belakang Nginx, perlu mengatur reuse koneksi → jika tidak, pada beban tinggi koneksi bisa gagal karena kekurangan port internal
  • Nginx secara default melakukan buffering paket → menyebabkan keterlambatan pada SSE(EventSource)
  • Standar HTTP tidak melarang body pada request GET dan DELETE → sebagian memang menggunakannya, tetapi banyak library dan server tidak mendukung
  • Satu IP dapat meng-host beberapa website → pembedanya adalah header HTTP Host dan SNI pada TLS → ada situs yang tidak bisa diakses hanya dengan IP langsung
  • CORS: saat meminta resource dari origin lain, browser memblokir akses ke respons → server perlu mengatur header Access-Control-Allow-Origin
    • Jika termasuk pengiriman cookie, perlu pengaturan tambahan
    • Jika frontend dan backend memakai domain dan port yang sama, tidak ada masalah CORS

Other

  • Hal yang perlu diperhatikan pada YAML

    • YAML sensitif terhadap spasikey:value salah, key: value yang benar
    • Kode negara NO jika ditulis tanpa tanda kutip bisa ditafsirkan sebagai false
    • Git commit hash tanpa tanda kutip bisa dikonversi menjadi angka
  • Masalah CSV di Excel

    • Saat membuka CSV, Excel melakukan konversi otomatis
      • Konversi tanggal: 1/2, 1-22-Jan
      • Konversi tidak akurat untuk angka besar: 1234567890123456789012345678901234500000
    • Penyebabnya, Excel secara internal memproses angka sebagai floating point
    • Ada kasus nama gen SEPT1 berubah secara keliru akibat masalah ini

1 komentar

 
GN⁺ 2025-08-18
Komentar Hacker News
  • Beberapa router dan firewall kadang memutus koneksi TCP yang idle secara diam-diam tanpa memberi sinyal apa pun ke aplikasi; kode yang mempertahankan pool koneksi TCP seperti library klien HTTP atau klien database bisa mengalami masalah koneksi menjadi tidak valid tanpa peringatan. Untuk mengatasinya, Anda bisa mengatur TCP keepalive di sistem, atau jika HTTP, menggunakan header Connection: keep-alive, Keep-Alive: timeout=30, max=1000. Setelah koneksi TCP tersambung, router di tengah tidak menyimpan state; masalahnya ada pada timeout sesi firewall atau NAT. Dalam kasus ini, paket RST pun tidak datang. Di lingkungan K8s, pernah mengalami masalah karena pengaturan modul conntrack terlalu rendah. Meskipun memakai HTTP Keep-Alive, itu hanya efektif untuk penggunaan ulang koneksi dan tidak menjaga koneksi di jaringan tetap hidup (tautan penjelasan). HTTP Keep-Alive sebenarnya tidak menghasilkan paket, hanya menunda penutupan. Sebaliknya, TCP Keep-Alive secara berkala menghasilkan paket untuk mereset timer

    • TCP Keep-Alive bisa tidak bekerja baik di perangkat mobile. OS mobile biasanya hanya bisa melacak atau mengelola paket keep-alive yang muncul di level aplikasi secara terpisah. Namun TCP Keep-Alive bekerja di bawah level aplikasi, jadi dalam kondisi tertentu bisa dinonaktifkan, sementara aplikasi masih tetap bisa diakses
  • Metode yang mengembalikan Optional<T> bisa saja mengembalikan null, dan praktik seperti ini sangat membingungkan. Kalau sedang cukup sabar secara emosional, rasanya ingin mengajukan JEP yang memperkenalkan anotasi seperti @java.lang.NonNullReference. Jika tipe dideklarasikan dengan anotasi ini, saya ingin compiler memperlakukan assignment null sebagai error. Misalnya, Alpha boleh diberi null, tetapi Beta menghasilkan error. Sepertinya perlu melihat spesifikasi untuk memahami bagaimana dead code elimination benar-benar bekerja di javac; misalnya pada if (true), bagian b = null sebenarnya dielide, dan secara legal mungkin tetap merupakan kode yang diizinkan

    • Di Kotlin, kasus seperti ini sudah menjadi compile error, jadi tidak perlu anotasi khusus

    • Masih dipertanyakan apakah di bahasa yang punya null, benar-benar perlu memakai Optional<T>. Seperti di Python, nilai balik fungsi ditulis saja sebagai T | None, bukan objek Optional tersendiri. Jika tetap harus dicek, pembeda framework-nya jadi terasa kurang jelas. Kecuali memakai gaya monad tertentu, pada akhirnya pengecekannya tetap sama

  • Ada yang bilang Java, C#, dan JS mengenkode string in-memory dalam bentuk sejenis UTF-16, tetapi untuk Java itu tidak tepat; untuk C# dan JS mungkin juga begitu. Selama tipe string sebuah bahasa cukup opak, bentuk representasi in-memory adalah detail implementasi. Di Java, itu menjadi jelas sejak versi 9 (tautan JEP terkait). Adanya FFI juga menjadi alasan mengapa mengubah detail implementasi tidak selalu mudah. Selain itu, tentang angka di JS, disebutkan bahwa max accurate integer adalah 2^53−1, padahal bilangan bulat yang jauh lebih besar seperti 2^100 juga bisa direpresentasikan secara akurat. Arti 2^53−1 adalah bahwa n-1, n, dan n+1 semuanya dapat direpresentasikan secara akurat dalam IEEE double; karena itu n == n-1 dan n == n+1 keduanya akan bernilai false

    • C# punya representasi in-memory yang sangat tetap. Karena kasus seperti ReadOnlySpan<char> atau raw char* yang mengakses buffer secara langsung cukup umum, char adalah tipe code point UTF-16. Untuk JS mungkin entah bagaimana masih bisa dihindari

    • Saya lebih ingin memakai istilah max safe integer daripada max accurate integer

    • (Terkait encoding base64) Soal string in-memory Java, C#, dan JS yang bukan sejenis UTF-16, mungkin secara teknis benar, tetapi jika string yang telah di-base64-encode di bahasa berbasis UTF-8 didekode di Java, ada kasus di mana representasi UTF-16 Java menimbulkan masalah

  • Rasanya tip atau informasi berbentuk manual lebih cepat dipahami hanya jika memang sudah tahu atau hampir tahu sebelumnya. Kebanyakan manual lebih efektif untuk merapikan dan mengulas kembali daripada untuk proses belajar itu sendiri, sehingga kurang efisien untuk mengajari orang yang benar-benar belum tahu

    • Pada dasarnya manual ada agar kita meninggalkan catatan dan tidak hanya bergantung pada ingatan. Kebanyakan manual Unix memang berbentuk seperti ini. Kita biasanya mencari manual saat sudah tahu sebuah software melakukan apa, tetapi lupa detail cara pakainya. Sebaliknya, pemula total butuh tutorial atau panduan untuk memahami konsep. Manual lebih berperan sebagai persiapan agar bisa mengajukan pertanyaan dengan lebih baik
  • Saya sangat tertarik membaca tulisan “Traceroute Isn’t Real”; selama ini saya merasa data traceroute sering sangat tidak akurat atau tampak tidak bermakna, dan tulisan itu membantu saya memahami alasannya (tautan asli). Kalau ada informasi terbaru, akan menarik juga untuk mendengarnya

  • Tulisan ini sebenarnya lebih mirip daftar tip kecil yang dipelajari penulis dari pengalaman daripada jebakan atau trap yang sesungguhnya. Banyak isinya hanya berlaku dalam konteks sempit tertentu, tetapi konteksnya tidak dijelaskan dengan jelas, dan beberapa bahkan tampak seperti informasi yang keliru. Jadi keseluruhan tulisan ini tidak perlu diterima mentah-mentah; lebih baik dilihat sebagai alur pemikiran atau catatan semata

  • Soal nilai argumen default di Python bukan nilai baru yang dibuat tiap pemanggilan, melainkan nilai yang disimpan, ini poin yang wajib diketahui saat memakai variabel datetime

    • Saya bukan developer yang selalu memakai Python, tetapi minggu ini saya benar-benar kerepotan karena nilai argumen default disimpan. Saya ingin menetapkan set kosong jika argumen set tidak diberikan, tetapi set itu malah dipakai ulang dan menimbulkan bug. Butuh waktu lama sampai akhirnya paham penyebabnya
  • Pada “trap” pertama di halaman, dikatakan bahwa min-width: auto menentukan lebar minimum berdasarkan konten, tetapi ini sebenarnya tidak benar jika bukan dalam konteks flex/grid. Menurut MDN, pada block, inline, table, dan sebagainya, auto dikoreksi menjadi 0 (tautan dokumentasi resmi)

    • Jebakan pertama yang sebenarnya adalah bahwa “tidak ada properti CSS yang bisa dibaca secara terisolasi”. Sesuai namanya, cascading, hasil dari nilai default dan berbagai aturan akan bergabung di suatu tempat, jadi konteks seluruh dokumen itu penting

    • Cascade pada properti teks CSS masih lumayan bisa dipahami. Tetapi layout CSS terlalu sulit dipahami, baik dari sudut pandang desainer halaman, implementator, maupun pengguna. Sulit bersimpati ini sebenarnya didesain untuk siapa

  • Secara keseluruhan ini daftar yang lumayan bagus, meski ada beberapa pendapat.

    • Soal Han unification di Unicode, bahwa karakter dengan makna sama memakai code point yang sama di berbagai bahasa lalu ditampilkan berbeda tergantung font, itu bukan trap. Hanzi/Kanji seperti contoh yang diberikan dipakai hampir sama di Tiongkok dan Jepang, dan pengguna kedua bahasa tetap mengenali varian lain sebagai karakter dengan konsep yang sama. Penulis seolah berkata huruf ‘A’ harus didefinisikan berbeda untuk bahasa Inggris dan Prancis, padahal tidak begitu. Lihat entri Han unification
    • -0.0 dan +0.0 (nol negatif dan nol positif) diperlakukan sama dalam perbandingan floating point, tetapi ada cara membedakannya, misalnya lewat bit pattern masing-masing, atau dari hasil 1.0/-0.0 = -tak hingga dan 1.0/0.0 = +tak hingga
    • Saya sangat setuju dengan saran untuk menetapkan timezone server ke UTC. Gunakan UTC di server, log, penyimpanan foto, dan semua tempat yang punya nilai arsip atau membutuhkan timestamp yang akurat; waktu lokal sebaiknya hanya dipakai untuk percakapan
    • Disebutkan bahwa pada integer, (low + high) / 2 berisiko overflow sehingga sebaiknya memakai low + (high - low) / 2, tetapi jika low atau high bisa bernilai negatif, itu mungkin hanya memindahkan rentang overflow. Ini isu penting dalam binary search umum
    • Menggunakan tipe dan operasi integer dengan benar di C/C++ juga jebakan besar, lihat tautan panduan terkait
    • Disebutkan bahwa rebase bisa mengubah history, padahal rebase itu sendiri memang command untuk me-rewrite history
    • Meskipun secara konseptual pengguna dua bahasa mengenali karakter yang sama, ini tidak bisa sekadar dianggap “variasi font”. Memiliki code point Unicode yang sama tidak berarti penggantian karakter aman dilakukan; bagi pengguna Jepang, penggantian seperti ini bahkan bisa menjadi alasan menolak memakai suatu produk

    • Memang huruf A dalam bahasa Inggris dan Prancis tidak dibedakan, tetapi ada juga kasus seperti А (huruf Kiril) dan A (huruf Latin) yang terlihat sama namun sebenarnya memiliki code point berbeda. Han unification juga sering menyatukan karakter yang bentuk visualnya cukup berbeda, sehingga pembelajar bahasa Jepang atau Mandarin bisa benar-benar bingung. Misalnya karakter '喝' (drink) bisa tampil sangat berbeda tergantung konteks seperti pada tautan ini, dan bahkan saat disalin bentuknya bisa langsung berubah, sehingga cara penanganannya cukup rumit. Han unification secara praktis memang topik yang sangat merepotkan

  • Disebutkan ada perbedaan halus antara numpy dan pytorch, tetapi tanpa penjelasan kasus yang konkret, ini tidak terlalu berguna dan informasinya terasa kurang, jadi tidak tampak sebagai jebakan yang realistis