Belajar untuk menyelidiki bug [ditutup]

11

Saya bahkan tidak yakin bagaimana mendefinisikan kesulitan ini. Itu mengingatkan saya pada tes yang dilakukan beberapa calon karyawan pada saya sebelum saya mendapat pekerjaan. Mereka akan memilih objek di ruangan dan kemudian saya akan diizinkan untuk mengajukan pertanyaan untuk membantu saya menentukan apa objek itu (seperti 20 pertanyaan). Saya sangat mahir dalam hal ini (tidak, saya tidak pernah mendapat poin tinggi untuk kerendahan hati), jadi saya berasumsi bahwa saya akan sangat baik dalam mengatasi masalah bug ...

Tapi ada satu hal yang saya ketahui baru-baru ini. Saya sangat baik dalam situasi itu karena sangat mudah untuk melihat semua yang ada di ruangan, jadi saya dapat mendekati masalah saya dengan beberapa konsep bagian komponennya. Intinya saya "tahu apa yang saya tidak tahu". Tetapi dengan pemrograman saya mengalami banyak situasi di mana masalahnya tidak diketahui oleh saya. Saya tahu itu rusak, tetapi saya tidak punya konsep bagaimana itu bisa rusak. Saya sudah mengikuti semua instruksi, saya tahu teknologinya cukup baik ...

Jika saya jujur, saya merasa seperti mengalami kesulitan membayangkan hal-hal yang bisa salah sehingga saya dapat mengujinya dan, semoga, menemukan solusinya.

Bagaimana cara mengembangkan keterampilan itu? Apa yang harus saya lakukan untuk membantu imajinasi saya yang tampaknya terbatas dengan cara-cara yang mungkin dapat merusak proyek saya? Apakah ada latihan (puzzle mungkin?) Yang bisa membuat saya lebih baik dalam hal ini? Saya sadar bahwa mungkin penyembuhan terbesar hanyalah pengalaman ... tapi saya berharap dapat membantu mempercepat proses jika saya bisa. Menatap layar komputer saya dengan kosong selama beberapa jam sekaligus bahkan tidak menyenangkan ...

Jay Carr
sumber
3
bayangkan bagaimana Anda berpikir itu mungkin bekerja, dan bekerja mundur dari output ke input untuk menemukan jalur untuk menyelidiki
Steven A. Lowe
1
Saya akan melemparkan tautan di luar sana - Bagaimana menjadi seorang Programmer - keterampilan pertama yang terdaftar adalah "Learn to Debug".
1
Saya ingin membuang sesuatu mengenai pemikiran "out of the box". Berkenaan dengan bug, saya sering berpikir bahwa hal pertama yang harus dilakukan adalah hanya daftar semua sistem yang berinteraksi, kemudian menganggap setiap bagian dari itu bisa salah sampai dibuktikan sebaliknya. Maka pekerjaan Anda menjadi lebih mudah: anggap komponen itu gagal, dan temukan cara itu bisa walaupun awalnya tampak tidak masuk akal ("output rusak", dll.). Kemudian buktikan komponen Anda tidak gagal, dimulai dengan interaksi paling cepat. Setelah fakta itu bisa tampak seperti imajinasi tetapi seringkali itu hanya dimulai dengan pandangan pesimistis.
J Trana
Tuliskan printfatau printlnatau apa pun yang Anda gunakan di bawah setiap baris kode untuk 100% yakin semuanya bekerja sesuai keinginan Anda, haha. Kemudian jalankan aplikasi konsol Anda dengan App > out.txtkemudian datang bagian yang sulit melihat file besar .. kadang-kadang file log saya lebih dari beberapa juta baris dan mungkin butuh waktu haha. Tentu saja cara yang benar adalah dengan menggunakan debugger dan breakpoints tetapi kadang-kadang itu tidak mungkin dilakukan.
SSpoke
1
Baca Pirsig's Zen Dan Seni Perawatan Sepeda Motor amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0060589469
Jeffrey Kemp

Jawaban:

11

Setiap cacat pada perangkat lunak pada akhirnya disebabkan oleh perbedaan antara asumsi dan kenyataan. Bug berbahaya hanyalah perbedaan antara asumsi yang sangat mendalam dan kenyataan. Kemampuan untuk mendiagnosis bug tergantung pada kemampuan Anda untuk mempertanyakan asumsi Anda sendiri, dan yang memang membutuhkan kesadaran bahwa Anda tidak tahu hal-hal tertentu, Anda hanya mengasumsikannya dan dulu benar sampai sekarang.

Jelas alat perdagangan, file log, debuggers, dll. Sangat membantu dalam mengungkap asumsi seperti itu dan menyelaraskan kembali model dunia Anda dengan sistem yang sebenarnya. Tetapi sampai Anda siap mempertanyakan asumsi krusial, misalnya "Itu bukan input yang buruk karena kami memiliki pemeriksaan input yang komprehensif", Anda akan menghabiskan seluruh waktu Anda memeriksa bagian-bagian sistem yang salah, atau tidak tahu di mana lagi mencari. di tempat pertama.

Kilian Foth
sumber
3
Aku benci mengatakannya Killian, tapi kupikir kau sudah memukul kepalanya. Saya sangat bangga dengan "pengetahuan" saya tentang sistem yang saya peroleh selama saya di sini dan saya pikir saya secara mental menolak ide salah. Seperti yang telah saya sebutkan, saya tidak pernah mendapat nilai tinggi dalam kerendahan hati. Mengikuti saran Anda untuk menantang asumsi saya sendiri sebenarnya memungkinkan saya untuk membuat kemajuan yang kuat pada beberapa masalah yang saya hadapi dalam kode saya sendiri. Jadi, terima kasih, saya akan mengingat hal ini ke depan.
Jay Carr
2
@JayCarr: " secara mental menentang gagasan kesalahan " - Bagaimana jika Anda mencoba melihat kesalahan sebagai sumber belajar daripada kesalahan? Tidak ada yang salah dengan kesalahan, selama Anda tidak berhenti di situ.
JensG
14

Apa yang harus saya lakukan untuk membantu imajinasi saya yang tampaknya terbatas dengan cara-cara yang mungkin dapat merusak proyek saya?

Dalam kebanyakan kasus, saya tidak akan mengatakan apa-apa. Anda seharusnya tidak mencoba untuk memimpikan hal-hal yang mungkin menyebabkan program rusak. Anda harus secara sistematis menentukan apa yang menyebabkannya rusak.

Anda harus masuk ke proses debugging dengan informasi berikut:

  • langkah-langkah yang diambil dan nilai-nilai yang dimasukkan untuk menghasilkan bug;
  • apa yang harus dilakukan program ketika diberi langkah-langkah dan input tersebut;
  • apa yang sedang dilakukan program ketika diberi langkah-langkah dan input tersebut.

Jika ada pesan kesalahan, dapatkan semua informasi yang Anda dapat tentangnya. Jika pesan kesalahan itu sendiri tidak jelas, dan Anda tidak tahu apa artinya dalam praktiknya (beberapa pesan kesalahan tidak selalu berguna), maka gunakan Google, atau StackOverflow, atau sumber daya daring lainnya untuk mencari informasi tentangnya .

Jika tidak ada pesan kesalahan yang ditampilkan di ujung depan, periksa log apa pun yang ditulis aplikasi untuk pesan kesalahan selama periode waktu Anda mereproduksi bug. Kode mungkin telah dieksekusi sampai selesai, tetapi menemukan pengecualian yang sedang ditangani di sepanjang jalan yang membuang hasil akhir dan menghasilkan entri dalam log. Carilah itu, lakukan hal yang sama di atas dan mengidentifikasi dengan tepat apa artinya.

Jika ada stacktraces yang disediakan dengan pengecualian yang dilemparkan oleh kode Anda (dan harus ada), lihatlah baris kode yang disebutkan. Garis itu sendiri mungkin bukan yang benar-benar menghasilkan masalah. Jika Anda mendapatkan NullPointerException dalam sepotong kode Java, stacktrace akan memberi tahu Anda di mana Anda mencoba menggunakan sesuatu yang nol ketika Anda mengharapkannya. Itu tidak benar-benar mengarahkan Anda ke baris yang menyebabkan masalah, tetapi umumnya memang memberi tahu Anda variabel apa yang tidak memiliki nilai yang Anda harapkan, sehingga Anda dapat melihat referensi / tugas apa pun untuk variabel tersebut untuk menentukan bahwa nilainya tidak disetel atau nilainya diset dengan tidak benar.

Jika tidak ada yang membantu, jalankan debugger Anda. Jika Anda mempersempitnya ke bagian kode yang Anda tahu menyebabkan masalah - tetapi Anda tidak tahu persis baris mana - maka selesaikan itu. Jika tidak, ikuti saja semuanya. Di sinilah Anda perlu tahu persis apa yang harus dilakukan program dengan input yang diberikan, karena Anda perlu melihat setiap nilai setelah setiap baris dan menentukan dengan tepat di mana itu menyimpang dari apa yang Anda harapkan untuk dilakukan.

Masih belum tahu apa masalahnya? Minta bantuan seseorang . Rekan kerja, teman, komunitas online. Tunjukkan pada mereka semua pekerjaan yang baru saja Anda lakukan. Tunjukkan pada mereka pesan kesalahan, stacktraces, jelaskan apa yang dilakukan program secara umum (jika mereka belum tahu), apa yang seharusnya dilakukan dalam contoh khusus ini (mis. Mengembalikan nilai 4), apa yang sebenarnya dilakukan (mis. mengembalikan nilai 5). Jika Anda mempersempitnya ke beberapa baris kode di debugger, katakan "Saya tahu masalah ini disebabkan oleh baris-baris ini dalam kode, itu menetapkan nilai ke X ketika seharusnya Y, tapi saya tidak bisa melihat mengapa itu terjadi ".

Menghabiskan beberapa jam menatap kosong ke layar Anda pasti tidak menyenangkan, tetapi tidak ada alasan Anda harus melakukan itu. Jika ada masalah dengan kode Anda maka Anda harus membaca atau melangkah melalui kode.

Anthony Grist
sumber
Mungkin agak cepat menilai jawaban ini, agak frustrasi ketika saya membacanya. Saran suara. Komentar Killians hanya berbicara lebih ke jantung masalah saya, saya pikir. Itulah satu-satunya alasan mengapa ini bukan jawaban yang dipilih.
Jay Carr
4

Hingga taraf tertentu, ini seperti menginvestigasi kasus kriminal, atau teka-teki yang membingungkan.

Pertama, Anda mendapatkan korban. Setelah menggali beberapa saat ke dalam kasus ini, Anda mengidentifikasi beberapa tersangka dan Anda juga mengembangkan hipotesis kerja bagaimana tepatnya korban bisa terbunuh. Anda terus menyelidiki, mencari informasi yang lebih bermanfaat, membuat Anda semakin dekat dan semakin dekat ke sumber masalah sebenarnya.

Itu terjadi bahwa dari waktu ke waktu Anda berjalan ke jalan buntu (pun intended). Itu bagian dari itu, dan tidak ada yang salah dengan itu, selama Anda berhasil mengembalikan diri ke jalur secepat mungkin. Kuncinya adalah, untuk selalu berpikir tentang informasi apa yang Anda butuhkan selanjutnya, yang memasok hipotesis Anda (dan memberi Anda informasi lebih lanjut), atau membuktikannya salah. Kemudian temukan cara untuk mendapatkan informasi itu dengan cara yang efisien, buat kesimpulan Anda dan lanjutkan, sampai Anda akhirnya bisa menghukum yang bersalah.

Dan kadang-kadang Anda menyadari, bahwa semua fakta dan indikasi yang diperlukan untuk menemukan pelakunya sudah menunggu di depan Anda setengah jam yang lalu. Meskipun menjengkelkan, itu adalah bagian yang paling menarik, karena jika Anda melakukan tinjauan kritis atas tindakan dan kesalahan Anda, Anda mungkin bisa belajar dan menjadi lebih baik . Ajukan pertanyaan seperti:

  • Bagaimana saya bisa menghindari pemborosan waktu ini?
  • Apa yang saya abaikan sejak awal, dan mengapa?
  • Apa asumsi yang salah dan / atau salah yang saya andalkan?

Ini akan melatih kemampuan Anda. Ini juga akan mengembangkan insting Anda , sehingga seiring waktu Anda belajar untuk secara otomatis memperhatikan semua hal-hal kecil yang terlalu mudah diabaikan, membuat Anda lebih cepat mendapatkan jawaban yang tepat. Pada akhirnya, ini semua tentang latihan yang disengaja .

Yang tak kalah pentingnya adalah selalu ingat apa yang Sherlock Holmes ajarkan kepada kami: Ketika Anda telah menghilangkan yang mustahil, apa pun yang tersisa, betapapun mustahil, pastilah kebenaran.

JensG
sumber
3

Apa yang harus saya lakukan untuk membantu imajinasi saya yang tampaknya terbatas dengan cara-cara yang mungkin dapat merusak proyek saya?

Biarkan sejarah menjadi panduan Anda. Jika proyek Anda dikelola dengan baik maka Anda harus memiliki database setiap bug yang pernah diperbaiki dalam produk bersama dengan analisis tentang bagaimana bug itu ditemukan, bagaimana itu direproduksi, bagaimana itu dianalisis, dan bagaimana itu diperbaiki. Itu bukan basis data tulis saja. Baca database , dan taksonomi bug segera akan mulai terjadi pada Anda.

Itu akan memberi Anda gambaran yang baik tentang hal-hal yang salah dalam produk Anda. Jika Anda lebih tertarik pada apa yang salah dalam semua jenis perangkat lunak, terutama dengan penekanan pada kerusakan yang berdampak pada keamanan, saya sarankan Anda membaca daftar CWE: http://cwe.mitre.org/data/index.html

Eric Lippert
sumber
2

Jadi daripada mencoba mereproduksi dan memperbaiki cacat tertentu, saya percaya Anda bertanya tentang memikirkan tes baru yang dapat Anda gunakan untuk menyelidiki produk untuk melihat apakah produk tersebut bekerja dalam keadaan seperti misalnya: apa yang terjadi jika saya memasukkan karakter khusus ke dalam mendaftar kata sandi halaman yang diajukan, atau apa yang terjadi jika saya dengan paksa menutup program ketika sedang menulis ke database. Kasus-kasus ini memang sulit dipikirkan.

Pengembangan perangkat lunak selama 10 tahun terakhir (Agile / XP / TDD dll.) Telah mencapai nilai memenuhi persyaratan eksplisit saja dan kemudian mendeklarasikan fitur selesai, dan tidak menemukan setiap cara yang mungkin untuk memecahkan sesuatu (ada kemungkinan pengecualian, jika Anda bekerja untuk NASA atau melakukan pengamanan topi putih tetapi bahkan ada kasus yang harus dibuat untuk menyebut hal-hal seperti itu dalam kriteria penerimaan cerita pengguna).

Jadi, jika fitur Anda secara eksplisit mendaftar sebagai kriteria penerimaan apa yang perlu dilakukan sistem seperti bagaimana menangani input, karakteristik kinerjanya, tindakan alur kerja pengguna, dll. Maka Anda memiliki daftar lengkap tentang pengujian apa yang perlu diperiksa. Pengujian harus dilakukan untuk memvalidasi bahwa persyaratan telah dipenuhi, dan cara terbaik untuk melakukannya adalah dengan mendaftar secara eksplisit semua persyaratan Anda. Lihatlah Kuadrat Tes Agile .

Beberapa orang menganjurkan tes ini untuk menjadi pernyataan eksplisit persyaratan, yang perlu ditulis sebelum kode yaitu Uji Pertama (atau Test Driven Development).

Namun saya menghargai bahwa Anda tidak terdengar seperti sedang merenungkan proyek baru di mana Anda dapat mengatur praktik pengembangan terbaik Anda sendiri sebelum Anda mulai dan malah datang setelah perangkat lunak telah ditulis dan diminta untuk 'mengujinya'. Ini memang lebih menantang tetapi prinsip yang sama berlaku, Anda hanya dapat mengujinya begitu Anda tahu apa yang seharusnya dilakukan. Jika tidak ada daftar lengkap persyaratan yang dipenuhi oleh tim pengembangan untuk Anda bekerja maka mengajukan pertanyaan adalah cara terbaik ke depan. Tergantung pada tim Anda, ini mungkin perlu dilakukan dengan hati-hati karena orang-orang yang tidak secara eksplisit menyebutkan persyaratan mereka sebelum membangun sistem perangkat lunak tidak suka diingatkan tentang apa yang mereka lewatkan tetapi sangat penting untuk melakukan tugas ini dengan baik.

Setelah Anda menemukan persyaratan - itu harus kuat / harus aman, kemudian mencoba menggali lebih dalam dan mencari tahu seberapa aman itu harus, atau berapa banyak kegagalan yang dapat diterima, selalu ada batas, tidak banyak orang memiliki bukti NSA tingkat keamanan sebagai persyaratan untuk aplikasi mereka atau ingin membayar untuk itu. Semakin Anda menggali semakin jelas seharusnya jenis serangan keamanan apa yang Anda butuhkan untuk bertahan atau mudah digunakan yang Anda tuju. Beberapa pengetahuan domain kemudian berguna, dalam keamanan, dalam desain, dalam kinerja, dll. Di sinilah Anda mengajukan lebih banyak pertanyaan dari para ahli yang dapat Anda temukan di tim Anda, atau di sini di SE, atau google / buku.

Encaitar
sumber
Tidak cukup pertanyaan yang saya cari untuk dijawab, tetapi komentar yang sangat baik tidak kurang. Saya memilih Anda, ini komentar yang sangat berguna.
Jay Carr