Menurut pendapat saya, ini adalah pertanyaan wawancara yang luar biasa - setidaknya dengan asumsi (1) kandidat diharapkan memiliki pengetahuan yang mendalam tentang threading, dan (2) pewawancara juga memiliki pengetahuan yang mendalam dan menggunakan pertanyaan untuk menyelidiki kandidat. Selalu mungkin pewawancara mencari jawaban spesifik dan sempit, tetapi pewawancara yang kompeten harus mencari yang berikut:
- Kemampuan untuk membedakan konsep abstrak dari implementasi konkret. Saya melemparkan yang satu ini terutama sebagai meta-komentar pada beberapa komentar. Tidak, tidak masuk akal untuk memproses satu daftar kata dengan cara ini. Namun, konsep abstrak dari pipeline operasi, yang dapat menjangkau beberapa mesin dengan kemampuan berbeda, adalah penting.
- Dalam pengalaman saya (hampir 30 tahun aplikasi terdistribusi, multi-proses, dan multi-berulir), mendistribusikan pekerjaan bukanlah bagian yang sulit. Mengumpulkan hasil dan mengoordinasikan proses independen adalah tempat sebagian besar bug threading terjadi (sekali lagi, menurut pengalaman saya). Dengan menyaring masalah ke rantai sederhana, pewawancara dapat melihat seberapa baik kandidat berpikir tentang koordinasi. Selain itu, pewawancara memiliki kesempatan untuk mengajukan segala macam pertanyaan lanjutan, seperti "OK, bagaimana jika setiap utas harus mengirimkan kata-katanya ke utas lain untuk rekonstruksi."
- Apakah kandidat berpikir tentang bagaimana model memori prosesor dapat memengaruhi implementasi? Jika hasil dari satu operasi tidak pernah dihapus dari cache L1, itu bug bahkan jika tidak ada konkurensi yang jelas.
- Apakah kandidat memisahkan threading dari logika aplikasi?
Poin terakhir ini, menurut saya, yang paling penting. Sekali lagi, berdasarkan pengalaman saya, secara eksponensial menjadi lebih sulit untuk men-debug kode berulir jika threading dicampur dengan logika aplikasi (lihat saja semua pertanyaan Swing di atas pada SO untuk contoh). Saya percaya bahwa kode multi-thread terbaik ditulis sebagai kode single-threaded mandiri, dengan handoff yang jelas.
Dengan mengingat hal ini, pendekatan saya adalah memberi masing-masing utas dua antrian: satu untuk input, satu untuk output. Thread memblokir saat membaca antrian input, mengambil kata pertama dari string, dan meneruskan sisa string ke antrian outputnya. Beberapa fitur dari pendekatan ini:
- Kode aplikasi bertanggung jawab untuk membaca antrian, melakukan sesuatu terhadap data, dan menulis antrian. Tidak peduli apakah multi-threaded atau tidak, atau apakah antrian adalah antrian di memori pada satu mesin atau antrian berbasis TCP antara mesin yang hidup di sisi berlawanan dari dunia.
- Karena kode aplikasi ditulis seolah-olah single-threaded, itu dapat diuji secara deterministik tanpa perlu banyak perancah.
- Selama fase eksekusi, kode aplikasi memiliki string yang sedang diproses. Tidak perlu peduli tentang sinkronisasi dengan utas yang menjalankan secara bersamaan.
Yang mengatakan, masih ada banyak daerah abu-abu yang dapat diselidiki oleh pewawancara yang kompeten:
- "OK, tapi kami ingin melihat pengetahuanmu tentang primitif konkurensi; bisakah kamu menerapkan antrian pemblokiran?" Jawaban pertama Anda, tentu saja, adalah bahwa Anda akan menggunakan antrian pemblokiran yang sudah dibangun sebelumnya dari platform pilihan Anda. Namun, jika Anda memahami utas, Anda dapat membuat implementasi antrian di bawah selusin baris kode, menggunakan sinkronisasi apa pun yang primitif dukung platform Anda.
- "Bagaimana jika satu langkah dalam proses itu membutuhkan waktu yang sangat lama?" Anda harus berpikir tentang apakah Anda ingin antrian output terbatas atau tidak terbatas, bagaimana Anda dapat menangani kesalahan, dan efek pada throughput keseluruhan jika Anda memiliki penundaan.
- Bagaimana cara efisien enqueue string sumber. Tidak perlu masalah jika Anda berurusan dengan antrian di memori, tetapi bisa menjadi masalah jika Anda berpindah antar mesin. Anda juga dapat menjelajahi pembungkus read-only di atas array byte yang mendasarinya.
Akhirnya, jika Anda memiliki pengalaman dalam pemrograman bersamaan, Anda mungkin berbicara tentang beberapa kerangka kerja (misalnya, Akka untuk Java / Scala) yang sudah mengikuti model ini.