Perlukah kuliah untuk bisa memprogram? bagian 2

Saya ingin menambahkan point penting dari tulisan saya mengenai apakah perlu kuliah untuk bisa memprogram. Selain masalah ilmu yang dipelajar dalam kuliah, universitas juga menyediakan akses ke berbagai fasilitas.

Pertama adalah hardware, jika Anda belajar sendiri, mungkin Anda akan mendapatkan kesulitan mengakses berbagai jenis hardware (komputer multiprosessor, robot, router, dsb). Di universitas, berbagai hardware tersedia bagi mahasiswa untuk bisa terjun langsung mencoba.

Kedua adalah software. Mungkin sebagian besar software bisa dicari versi bajakannya di Internet, tapi ada beberapa software yang sulit dicari, atau sangat diproteksi (misalnya software yang terhubung ke Internet). Banyak perusahaan software memberikan lisensi gratis kepada universitas, atau kepada mahasiswa (selama masih menjadi mahasiswa).

Ketiga adalah informasi. Informasi ini bisa berupa akses ke jurnal (umumnya universitas berlangganan jurnal internasional). Beberapa buku tidak tersedia ebooknya, dan umumnya universtas memiliki buku-buku yang bermutu yang bisa dipinjam.

Selain ketiga hal tersebut, universitas juga memberikan akses pada para ahli (dosen dan peneliti) yang bisa diajak diskusi, dan bisa mengajar Anda untuk menghindarkan dari berbagai kesalahan umum, serta bisa mengkoreksi kesalahan Anda.

Dan yang terakhir adalah: universitas mengajari Anda untuk bekerja bersama dan bersosialisasi. Dengan berbagai tugas yang diberikan, Anda akan belajar untuk membagi tugas, merencanakan pekerjaan, dan sebagainya. Hal ini sulit didapat dari belajar sendiri ataupun dari kursus.

Berpikir Ketika Memprogram dan Menguji Program

Setelah membaca posting reddit ini, saya teringat kembali pada buku Programming Pearl, terutama bagian yang dibahas dalam posting itu yaitu mengenai binary search. Dalam buku programming pearl dinyatakan bahwa para programmer professional yang diberi waktu 2 jam untuk menulis binary search, 90% memiliki bug (terutama di *boundary* condition). Penulis blog memberi tantangan pada pembacanya untuk membuat binary search, boleh beberapa jam, tapi *tanpa testing* sama sekali.

Respon kebanyakan orang bisa dirangkum menjadi tiga kubu. Kubu pertama: ah di dunia nyata kan orang pasti testing, keahlian buat memprogram dengan benar tanpa testing itu tidak berguna. Kubu kedua menyatakan: kalau program sependek itu tidak bisa dibuat tanpa testing, bagaimana mungkin bisa membuat program besar yang rumit, apakah tiap baris program harus ditest?. Kubu terakhir menyatakan: buat apa sih membuat binary search, kan sudah ada di library/API?

Untuk kubu terakhir, jawabannya sederhana: ada kasus di mana hal tersebut masih diperlukan. Misalnya fungsi binary search di library kebanyakan tidak menyatakan elemen mana yang akan dikembalikan jika ada lebih dari 1 data yang cocok, dan tidak akan mengembalikan lokasi di mana data bisa disisipkan jika data belum ada. Contohnya di fungsi bsearch di C (POSIX):

The bsearch() function returns a pointer to a matching member of the array, or NULL if no match is found. If there are multiple elements that match the key, the element returned is unspecified.

Kadang diperlukan fungsi yang mengembalikan elemen pertama yang cocok, atau terakhir yang cocok, atau bahkan elemen random dari antara semua elemen yang cocok. Tentu saja salah satu solusinya adalah membungkus fungsi bsearch, lalu mencari ke depan atau belakang sampai tidak cocok lagi. Tapi dalam hal ini Anda juga tetap perlu memperhatikan batas index ketika mencari, jadi Anda tetap perlu menulis kode (yang perlu testing dan perlu dipikirkan).

Jika Anda mengimplementasikan fungsi binary search sendiri, Anda bisa membuat fungsi yang sekaligus mengembalikan posisi elemen di mana kita harus menyisipkan elemen tersebut jika elemen tidak ditemukan (ini bisa didapat dari lokasi perbandingan terakhir), dalam kasus ini kita tidak bisa membungkus fungsi bsearch, karena fungsi tersebut hanya mengembalikan NULL jika elemen tidak ditemukan.

Beberapa Pelajaran yang bisa dipetik dari posting dan diskusi adalah: testing itu perlu, bahkan untuk program kecil sekalipun. Pelajaran kedua adalah: kita tetap harus teliti dan berpikir ketika memprogram. Pelajaran ketiga adalah: meski isi library di berbagai bahasa sudah cukup lengkap, mengerti algoritma sederhana itu perlu, dan kadang kita perlu mengimplementasikan algoritma tersebut atau variannya.

Sebagian orang berpikir: ah tidak perlu terlalu teliti ketika memprogram, nanti akan ketauan salahnya ketika testing. Sebagian lagi berpikir: program ini sudah saya pikirkan, jadi gak perlu ditest. Sikap yang benar adalah: kedua hal tersebut berhubungan, kita harus teliti ketika memprogram, dan harus teliti juga dalam membuat testing. Mengapa tidak menggantungkan diri pada testing saja? ada beberapa masalah dengan testing, pertama testing itu sulit, untuk membuat test case yang baik perlu kasus yang sangat besar dan kedua testing tidak selalu bisa dilakukan.
Continue reading Berpikir Ketika Memprogram dan Menguji Program

Buktikan Anda hebat, bukalah source code Anda

Saya banyak mendengar orang yang merasa dirinya hebat dalam bidang programming, tapi tidak bisa membuktikan klaimnya. Jika ada yang bilang bahwa dirinya adalah penyanyi yang hebat, saya tinggal meminta dia menyanyi, jika dia adalah pelukis yang hebat, saya akan meminta dia melukis. Jika seseorang hanya memperlihatkan lukisan lalu bilang “saya melukis ini”, maka saya belum tentu percaya bahwa itu adalah benar lukisannya.

Dalam hal programming, kadang-kadang ada orang yang memperlihatkan program yang sudah jadi sebagai “bukti” mereka jago memprogram. Tapi sebuah program tidak cukup bercerita (apalagi hanya dari screenshotnya). Kita tidak bisa melihat apa isi dalamnya, yang mungkin penuh dengan komponen buatan orang lain. Mungkin ada yang bangga bisa membuat “MP3 Player”, tapi ternyata yang dibuat hanyalah user interface untuk komponen yang sudah ada. Tampilan bukanlah segalanya. Jika dibandingkan dengan seseorang yang membuat program command line yang memutar MP3 dengan membuat decodernya sendiri, saya akan menyatakan bahwa orang yang membuat decoder MP3 player tersebut jauh lebih hebat dibandingkan orang yang hanya membuat user interface saja.

Dengan tidak melihat source codenya, saya juga tidak yakin apakah gaya penulisan kode Anda bagus atau tidak. Bahkan ada kemungkinan ternyata source code Anda adalah hasil copy paste dari banyak tempat (yang bisa dicari dengan google code search). Saya sudah sering melihat banyak aplikasi yang seolah-olah hebat, tapi ternyata tidak sama sekali. Dengan sedikit reverse engineering, saya sudah melihat ada banyak aplikasi yang ternyata hanya memakai komponen yang sudah jadi (bahkan sebagian memakai komponen komersial dan tidak membayar, tapi diakali menggunakan crack).

Sebagian orang akan beralasan: wah saya tidak bisa memperlihatkan program saya atau source code saya, karena itu rahasia perusahaan. Jika Anda adalah programmer yang hebat, Anda tentunya akan membuat banyak program dalam hidup Anda (kecuali Anda sangat sibuk seperti Linus Torvalds yang hanya berkonsentrasi di Kernel Linux dan sedikit di Git). Program tersebut tidak perlu besar ataupun rumit. Banyak produk yang dibuat oleh programmer yang terdiri dari beberapa puluh, beberapa ratus, atau 1000-2000 baris kode saja dan sangat berguna bagi orang lain.

Kebanyakan plugin wordpress atau skrip GreaseMonkey hanya berkisar beberapa puluh sampai beberapa ratus baris kode. Bahkan Anda bisa membuat aplikasi serius tanpa harus menulis banyak kode. Jika Anda memang hebat. Misalnya salah satu produk web dari 37signals hanya terdiri atas 579 baris kode. Sebuah Window Manager untuk X11 dapat dibuat dalam 1000-2000 baris kode saja (contohnya xmonad dan dwm). Bahkan kernel sistem operasi Minix hanya sekitar 4000 baris kode saja (driver dsb dibuat di userspace, dan tidak termasuk dalam kode kernel).

Saya menggunakan metrik Lines of Code, karena ini yang paling mudah (meski tidak akurat), dan dengan aneka framework dan library yang ada saat ini Anda bisa menulis aplikasi lengkap dengan sangat cepat. Jadi saya tidak menantang Anda membuat program sangat kecil seperti dalam demoscene menggunakan assembly, tapi menantang Anda merilis program yang berguna, walaupun sederhana. Programnya juga sebaiknya memperlihatkan sesuatu yang baru atau menarik, bukan sekedar membuat another MP3 player dengan komponen buatan orang lain.

Saya belum merasa diri saya sudah hebat, tapi jika ada yang bertanya aplikasi apa saja yang sudah saya buat, saya bisa memperlihatkan halaman ini: http://yohan.es/applications/. Kalau ada orang lain yang mengaku hebat, tapi tidak bisa membuktikan kehebatannya, jangan-jangan dia hanya seperti djoko blue energy.

System programming

Banyak orang yang terkesima dengan orang yang memprogram di level kernel sistem operasi; banyak juga yang menganggap wilayah kompilasi atau interpretasi itu sesuatu yang rumit, dan sebaiknya diterima saja, tidak perlu dipelajari.

Sebagian orang bersifat tidak mau tahu. Misalnya ada yang bilang: mengapa belajar assembly atau C/C++, bahasanya nggak dipakai, mendingan belajar PHP, Ruby, Java atau .NET. Orang-orang tersebut tidak menyadari bahwa compiler dan atau runtime bahasa-bahasa tersebut dibuat dengan C dan C++. Sebagian besar library yang dipakai di berbagai bahasa juga diimplementasikan di C/C++.

Sebagian kemampuan prosessor juga tidak akan bisa dimanfaatkan secara maksimal oleh bahasa tingkat tinggi, tanpa bantuin assembly dan atau C/C++. Contoh terbaru adalah instruksi-instruksi STTNI (String & Text New Instructions) yang diperkernalkan di prosessor baru Intel dengan arsitektur Nehalem untuk mempercepat pemrosesan teks (dan parsing XML) tidak akan bisa dilakukan.

Bahkan jika Anda tidak memprogram dalam bahasa C sekalipun, pengetahuan tersebut bisa berguna, misalnya Anda bisa mengoptimasi penggunaan memori dan mengoptimasi kecepatan di PHP. Lihat juga posting saya mengenai Kritik PHP.

Sekarang pertanyaan berikutnya yang mungkin muncul adalah: bagaimana saya belajar pemrograman sistem?

Continue reading System programming

Kritik PHP

PHP merupakan bahasa yang kurang bagus, designnya tidak dipikirkan dengan matang. Banyak sekali keanehan PHP dibanding bahasa lain, dan meskipun PHP sudah mulai agak membaik di versi 5.3 (yang baru dirilis 3 minggu yang lalu), saya masih menunggu PHP6 untuk mencoba lagi.

Kebanyakan orang tidak menyadari bahwa mereka butuh sesuatu, atau bahwa sesuatu itu jelek, sampai mereka diberikan sesuatu yang lebih baik. Di artikel ini saya ingin mengkritik PHP, tapi sebelumnya akan saya contohkan apa yang saya maksud dengan melihat sejarah MySQL.

Awalnya MySQL tidak mendukung transaksi. Komentar pendukung MySQL waktu itu: transaksi itu tidak perlu, yang penting cepat (Bahkan pembuat mysql pun berpikir demikian, coba lihat http://www.genome.ou.edu/mysql_manual.html#Bugs, bagian ” Some things we don’t have any plans to do”). Tapi kemudian transaksi ditambahkan, dengan catatan: kalau mau cepat jangan pakai transaksi. Lalu berikutnya: transaksi adalah salah satu fitur yang kami banggakan.

Nah, saya cukup yakin, isi kritik saya ini kemungkinan akan banyak ditolak oleh orang yang cinta buta pada PHP, setidaknya saat ini. Tapi ketika PHP sudah berkembang, baru akan bisa diterima. Memang begitulah sifat penggemar sesuatu, jadi saya bisa memakluminya.

Saya sendiri pernah memprogram PHP dari sejak PHP3, lalu PHP4, dan sampai awal PHP5. Semakin lama saya mempelajari dan memakai PHP, saya semakin merasakan keterbatasannya. Saya tidak menyangkal bahwa PHP merupakan bahasa yang sangat populer. Namun tidak semua yang populer itu bagus (ingat DBase? Ingat Visual Basic 6? dsb). Bagi pencinta PHP, Anda mungkin bisa berbangga PHP semakin membaik, meski caranya dengan “tambal sulam”, dan meski Anda harus sering menyesuaikan program agar berjalan di PHP terbaru. Mungkin saya akan mencoba lagi PHP di versinya yang keenam, tapi saat ini mari kita bahas satu persatu kelemahan PHP.

Continue reading Kritik PHP

DataStore di Google AppEngine (RDBMS bukan segalanya)

Google AppEngine adalah sebuah layanan Google, di mana kita bisa membuat aplikasi dalam Python atau Java (atau bahasa lain yang memakai virtual machine Java) di infrastruktur milik Google. Secara teori, Anda akan bisa melayani 5 juta pengunjung per bulan secara gratis. Anda bisa membayar ekstra jika ingin mendapatkan resource yang lebih banyak.

Saya akan menceritakan salah satu pengalaman development dengan google appengine, yaitu mengenai bagian pembuatan aplikasi yang scalable, dengan fokus pada DataStore. Menurut saya DataStore merupakan implementasi penyimpanan data yang menarik, yang berbeda dari database relasional yang umum dipakai saat ini.

Ilmu relational database dan SQL hampir tidak dipakai sama sekali di sini. Bahkan operasi Join yang sangat lazim di basis data tidak bisa dilakukan dengan DataStore. Lalu apa kelebihan DataStore? datastore memiliki aneka batasan yang memungkinan Google mendistribusikan data di berbagai server di seluruh dunia. DataStore diiimplementasikan di atas teknologi google yang sudah terbukti, yaitu BigTable.

Continue reading DataStore di Google AppEngine (RDBMS bukan segalanya)

Tutorial Membuat Interpreter/Compiler

Membuat sebuah interpreter/compiler masih merupakan misteri bagi sebagian besar orang. Setelah melihat-lihat aneka kurikulum, dan slide kuliah di berbagai tempat di Indonesia, saya mulai menyadari mengapa. Pertama: dasar teori untuk membuat sebuah compiler/interpreter kurang diajarkan dengan baik, dan yang kedua: mata kuliah kompilasi hanya berisi teori, padahal mempraktikkan pembuatan compiler/interpreter tidaklah sulit

Proses interpretasi/kompilasi dimulai dengan parsing source code. Masalah parsing seharusnya sudah diajarkan di mata kuliah otomata. Parsing akan membuat sebuah parse tree, dan kemudian dikonversi menjadi abstract syntax tree. Untuk menangani pembuatan parser, diperlukan struktur data tree. Pelajaran mengenai tree diajarkan di mata kuliah struktur data.

Continue reading Tutorial Membuat Interpreter/Compiler

Garbage Collection bukan Panasea

Para mahasiswa yang belajar C setelah belajar beberapa bahasa lain (seperti PHP dan Java) biasanya akan kesulitan, karena di C alokasi memori harus diperhatikan dengan sangat detail. Bahkan setiap string harus dialokasi manual. Anda juga harus tahu dengan tepat apakah suatu objek berada di heap atau stack (dalam C *objek* adalah suatu lokasi memori yang bernama).

Detail-detail alokasi memori dan dealokasi memori biasanya tidak dibutuhkan lagi dalam aneka bahasa modern (Java, semua bahasa berhasis .NET, python, php, dsb) karena adanya fitur garbage collection. Tapi Anda akan salah jika menanggap pengetahuan mengenai alokasi dan dealokasi memori tidak diperlukan lagi.
Jika Anda memiliki sebuah list, tree, atau struktur data lain di mana satu objek merefer ke objek lain, dan objek tersebut merefer ke objek lain lagi, maka Anda mulai harus berhati-hati. Jika ternyata masih ada objek yang memegang reference ke “ujung” struktur data (root tree, atau elemen pertama list), maka seluruh elemen yang berhubungan tidak akan dilepaskan.

Garbage collection juga memiliki kelemahan: sifatnya tidak deterministik, kita tidak tahu kapan garbage collection akan dilakukan (sangat tergantung pada komponen yang melakukan garbage collection). Efek pengumpulan sampah di saat yang tidak diinginkan adalah kinerja aplikasi akan terganggu.

Efek lain yang buruk adalah: ketika garbage collection dilakukan, biasanya semua thread harus dihentikan sementara. Ini berarti bahwa kinerja aplikasi bisa sangat terganggu di saat yang tidak diharapkan.

Jadi jika Anda masih mempertanyakan kenapa harus belajar alokasi memori, dan mengapa mahasiswa masih perlu diajari bahasa C, berarti Anda belum paham benar mengenai garbage collection.

Pendidikan Pemrograman Yang Tidak Baik

Seperti telah saya tuliskan sebelumnya, belajar pemrograman secara formal itu perlu, tapi sayangnya beberapa tempat tidak mengajarkan pemrograman dengan baik. Berikut ini beberapa ciri pengajaran pemrograman yang tidak baik:

  1. Terlalu berfokus pada tools tertentu yang trend saat ini. Mahasiswa wajib memakai tools X (misalnya IDE-nya harus Microsoft Visual Studio, atau harus memakai Visual Prolog). Tools akan cepat sekali berganti. Ketika Anda diajari tools X, ketika lulus, tools tersebut mungkin sudah tidak ada, atau tidak didukung lagi. Ingin contoh? DBase dan Visual Basic. Dulu keduanya sempat menjadi tools yang “standar”, tapi sekarang tools tersebut tidak disupport lagi.
  2. Tidak mengikuti perkembangan zaman. Ini ekstreem sebaliknya dari yang pertama, ada yang masih mengajarkan kuliah C dengan standar Pre ANSI-C, dan menggunakan compiler Turbo C++ 2.0, yang dirilis kira-kira 20 tahun yang lalu, dan sudah tidak didukung lagi.
  3. Kurang mengajarkan aspek algoritma. Pada sebagian besar bahasa, sudah tersedia library standar untuk sorting, searching, dsb, tapi tanpa memahami kemampuan dan batasan setiap algoritma, Anda akan menemukan hambatan ketika memproses data dalam jumlah yang besar.
  4. Hanya mengajarkan paradigma tertentu. Umumnya paradigma yang dipakai sekarang adalah object-oriented yang digabung dengan procedural, tapi itu bukan satu-satunya cara menyelesaikan masalah.

Jangan heran jika ternyata lulusan sebuah sekolah/perguruan tinggi komputer tidak bisa memprogram jika pengajarannya tidak benar. Jika Anda ingin menyaring antara orang yang punya dasar pemrograman dan yang tidak, cobalah test sederhana ini.

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

Programmer yang baik akan bisa menuliskan solusinya di atas kertas (tanpa bantuan komputer), dalam beberapa menit.

Representasi Bilangan Desimal di Komputer

Dalam dunia komputer, biasanya kita menggunakan representasi floating point untuk menyimpan bilangan desimal. Namun itu bukan satu-satunya representasi yang ada. Ada beberapa representasi lain yang berupa fixed point, misalnya BCD (binary coded decimal), Chen-Ho, dan DCD (Densely Coded Decimal). Jika diperlukan Anda pun bisa membuat representasi sendiri, sesuai yang Anda mau.

Metode penyimpanan yang ada tersebut dibuat dengan tujuan yang berbeda-beda, misalnya tujuan utama representasi floating point adalah dapat menampung angka dalam range yang besar, tapi dengan presisi yang berkurang/terbatas. Floating point juga biasanya basis 2, sehingga lebih cepat dieksekusi di komputer yang memakai binary logic (perlu dicatat, tidak semua komputer memakai binary logic).

Representasi desimal yang lain bertujuan agar dapat merepresentasikan bilangan secara eksak, namun rangenya terbatas. Variasi representasi dibuat untuk berbagai tujuan, misalnya DCD dibuat agar memori yang diperlukan lebih sedikit.
Continue reading Representasi Bilangan Desimal di Komputer