Kesulitan dalam pekerjaan seorang programmer



Hari ini saya ingin berspekulasi tentang kompleksitas di sekitar kita (orang) dan tentang kemampuan kita untuk bekerja dengannya. Bukan tentang kerumitan yang mereka tulis dalam status status perkawinan di jejaring sosial, seperti "semuanya rumit", tetapi tentang kompleksitas dalam sistem organisasi dan teknis (omong-omong, menurut saya, ternyata nama yang bagus untuk spesialisasi universitas). Saya tidak berpura-pura menjadi asli dan, terlebih lagi, saya tidak berpura-pura benar (terutama karena, setidaknya setengah, saya di sini akan merendahkan, mengotak-atik, dan bermain-main). Beberapa alasan ini telah saya buat di suatu tempat di komentar, tetapi bagi saya pertanyaan ini tidak ditutup. Oleh karena itu, hidup selalu memberikan saya berbagai contoh ilustrasi yang mendorong saya untuk berpikir lebih jauh. Meskipun Jumat, itu tidak dimaksudkan untuk menjadi bacaan yang menghibur, tidak akan ada gambar lucu, jika ada - saya memperingatkan Anda. Jika Anda hanya ingin membaca satu kalimat,dan pergi untuk membaca sisa artikel Jumat yang menyenangkan - ini dia: "Sederhanakan kompleksitas di mana hal itu dapat dilakukan, tangani kompleksitas di mana hal itu tidak dapat disederhanakan, dan dapatkan pengalaman dan kemampuan untuk membedakan kasus pertama dari kasus kedua." Cocok seperti roti panggang hari Jumat.



Beberapa kutipan dari yang hebat:



Memahami berarti menyederhanakan.



Menyederhanakan bukan berarti memahami.



Kesederhanaan membutuhkan desain dan selera yang baik.



Buatlah sesederhana mungkin, tetapi tidak sederhana.




Kompleksitas ada di mana-mana di sekitar kita. Kami menggunakan perangkat teknis yang canggih, kami menghormati kode kriminal yang kompleks, di dalam diri kami sistem kekebalan yang kompleks melawan virus corona, makhluk hidup bersel tunggal yang paling sederhana membawa organel yang sangat kompleks, hukum Newton yang paling sederhana ternyata merupakan penyederhanaan dari hukum yang jauh lebih kompleks pada kecepatan nonrelativistik, dan tentang kompleksitas Model Standar dan segala macam mekanika kuantum yang berbeda, saya biasanya diam.



Kompleksitas selalu merupakan tatanan tertentu, sistem tertentu dari elemen-elemen yang berinteraksi, dan sesuai dengan definisi konsep dasar ini, kompleksitas tumbuh ketika jumlah elemen bertambah dan ketika jumlah dan variasi hubungan antara elemen-elemen ini bertambah. Mungkin kompleksitas identik dengan keteraturan, antitesis dari kekacauan?

Kehidupan secara umum adalah peningkatan spontan dalam kompleksitas dalam diri kita karena penurunan kompleksitas di luar, sebagaimana seharusnya untuk sistem disipatif yang layak. Energi didistribusikan kembali sedemikian rupa sehingga untuk meningkatkan kompleksitas, sebagian perlu dihabiskan, tetapi organisasi yang dihasilkan, tatanan yang dihasilkan, memberikan "akses" ke sejumlah besar energi. Inilah, menurut saya, alasan evolusioner untuk peningkatan "spontan" dalam kompleksitas kehidupan.



Sistem kompleks di sekitar kita, kompleksitas organisasi materi dan energi di sekitar, yang ingin dihilangkan, mengarah pada peningkatan kompleksitas konsumen, dan selanjutnya di sepanjang rantai. Bunga di mana Anda bisa mendapatkan nektar hanya dengan bantuan batang panjang menyebabkan pemompaan bibir dengan komplikasi silikon , pemanjangan dan spesialisasi batang pada kupu-kupu yang memutuskan solusi desain seperti itu.



Kami adalah pemrogram, kami membuat sistem perangkat lunak yang, seperti belalai kupu-kupu itu, pasti rumit untuk mengotomatisasi solusi yang serupa dengan proses rumit yang rumit dalam kehidupan.



Kami adalah programmer, kami membuat komplekssistem perangkat lunak, dan apa pun yang mereka katakan, kami suka menciptakan kompleksitas ini, tetapi ada satu nuansa yang membedakan kami dari pencipta sistem teknis kompleks lainnya.



Pencipta bahan dan perangkat teknis yang kompleks dibatasi oleh kekuatan, gesekan, dan bahan lain yang sedikit meredam imajinasinya. Gaya gesekan programmer tidak peduli atau membatasi (kecuali dia adalah pengembang simulator rekah hidrolik terbaik di dunia ), kekuatan dan berat perangkat juga, dan dari sini, menurut saya, masalah utama muncul.



Dan itu terletak pada kenyataan bahwa terlalu mudah bagi kita para programmer untuk menciptakan kompleksitas. Ini terlalu mudah bagi kami. Ctrl + C dan Ctrl + V, fungsi baru, modul baru, perpustakaan baru, lapisan abstraksi baru, makro-shmakros, praprosesor-pascaprosesor, adaptor, konverter, dan fasad - semua ini akan berfungsi, Anda hanya perlu menambahkan lebih banyak frekuensi dan RAM, dan tidak diperlukan peredam gesekan. Di dunia fisik yang diciptakan, semuanya tidak sesederhana itu. Di mana dalam produksi industri analog tidak hanya pemrograman genetik, tetapi setidaknya bahkan makro Lisp sederhana?



Lagi. Terlalu mudah dalam pemrograman untuk menambah kompleksitas, dan terlalu sulit dalam pemrograman untuk mengurangi kompleksitas. Selain itu, tidak ada yang menyukai mereka yang mengurangi kerumitan dalam pemrograman, karena mereka selalu merusak segalanya selama refactoring.



Saya tidak mengatakan bahwa kode kompleks adalah hal yang buruk. Kode mengotomatiskan tugas kehidupan nyata, itu mencerminkannya dalam model datanya, kode tidak bisa lebih sederhana dari kehidupan. Kompleksitas kode tumbuh seiring dengan kompleksitas masalah, tetapi pengembang yang buta huruf menambahkan lebih banyak kerumitan pada kode daripada kerumitan masalah.



Pengembang yang kompeten menahan diri untuk tidak memasukkan kompleksitas ke dalam kode. Tidak heran para hebat mengatakan bahwa karena debugging lebih sulit daripada menulis kode, Anda tidak akan dapat men-debug kode yang Anda tulis pada batas kompleksitas yang tersedia untuk Anda. Tetapi saya juga akan mengatakan bahwa pengembang yang kompeten tidak menciptakan solusi yang lebih sulit daripada 84% dari kemampuan mereka untuk mengatasi kompleksitas.



Ketidakmampuan untuk merancang perubahan tak terduga di masa depan dalam persyaratan kehidupan mengarah pada fakta bahwa kode harus ditulis ulang dan dikerjakan ulang. Halo, saya Cap Anda. Tetapi Anda tidak dapat menulis ulang sistem perangkat lunak yang kompleks dari awal hanya karena Anda tidak menyukainya karena kerumitannya.



Kompleksitas dan kebingungan adalah dua hal yang berbeda. Karena saya selalu memberi tahu siswa yang membawa lab orang lain dan yakin bahwa mereka memahaminya (dua bingkai baru-baru ini bahkan mengatakan bahwa mereka pikir mereka harus belajar menjelaskan kode orang lain, dan tidak menulis sendiri - jelaskan, Karl, bahkan tidak mengedit dan mengembangkan ! ), tidak mungkin untuk memahami bahwa Anda tidak memahami sesuatu jika Anda tidak memahaminya. Di sisi ambang induktif ini, situasi "Saya pikir saya mengerti" tidak dapat dibedakan dari situasi "Saya benar-benar mengerti".



Jika seseorang datang kepada Anda dan berkata: "Terlalu sulit bagi Anda di sini, kami akan menulis dari awal" - Anda tidak boleh membiarkannya menulis, Anda harus terlebih dahulu menunjukkan bahwa ia dapat memperbaiki sistem lama. Jika Anda tidak dapat mengatasi kompleksitas yang sudah Anda miliki, dengan metode refactoring bertahap, maka ketika Anda mulai menulis sendiri, Anda akan memutar kompleksitas lebih buruk dan pada akhirnya Anda tidak akan menyelesaikan masalah. Dan mengapa? Karena tidak mungkin untuk memahami apa yang sebenarnya tidak Anda pahami dan remehkan, menurut definisi.



Melebih-lebihkan: bahkan menemukan sepeda yang tepat tidak akan berhasil untuk pertama kalinya. Sepeda pertama akan melengkung dan miring, dengan tiga roda gigi terhubung berpasangan, seperti pada gambar klasik desainer perempuan. Tapi itu akan membawa Anda ke tingkat kesulitan yang perlu Anda kerjakan saat membangunnya, dan sepeda kedua sudah akan keluar dengan masuk akal. Mereka menulis kelas string mereka sendiri bukan untuk mempelajari sintaks, tetapi untuk mendapatkan bagian kompleksitas yang memberi kehidupan.



Kompleksitas dari satu bagian kode yang sama, dari solusi yang sama, sangat tergantung pada seberapa kompleksnya kode tersebut dalam sistem, dan kompleksitas sistem bukanlah jumlah dari kompleksitas subsistem. Dan ini adalah bagian dari masalah ketika bekerja dengan pelanggan atau pengamat luar lainnya. Anda mungkin sering mendengar: "Ini mudah dilakukan, hanya {aksi X} {di dalam sistem Y}, di sana sudah ada {di dalam sistem Z}!". Ini adalah hasil dari meremehkan kompleksitas sistemik, ketika seseorang percaya bahwa jika sesuatu mudah dilakukan secara terpisah dari yang lainnya, maka mudah untuk melakukannya di dalam sistem besar yang sudah jadi. Jika program perlu mengimplementasikan A, B, C, D, E dan F, dan semuanya kurang lebih sama dalam kompleksitasnya, maka akan terlalu meremehkan untuk berpikir bahwa mereka akan dibangun dalam waktu yang sama.



Hal utama bagi seorang programmer berpengalaman adalah kemampuan untuk mengelola kompleksitas. Biasanya kami hanya menambahkan kompleksitas (Anda tidak bisa hanya refactor), tetapi celakalah seseorang yang tidak bisa refactoring (sebenarnya, penyederhanaan!). Kemudian, alih-alih mengatur dan menyederhanakan, pengembang semacam itu memutar kruk pada kruk dan tidak dapat berhenti, karena kruk lebih mudah untuk ditulis. Seiring waktu, menjadi semakin sulit untuk menulis kruk, tetapi triknya adalah bahwa setiap saat semakin sulit untuk menulis kruk lain, tetapi masih selalu lebih mudah daripada membersihkan istal dan membereskan semuanya. Dan selalu ada ilusi bahwa karena tenggat waktu, solusi optimal adalah menulis kruk. Sayangnya, ini adalah solusi optimal saat ini, tetapi sangat sub-optimal dalam jangka panjang. Pemrograman serakah.



Kemampuan untuk mengatasi kompleksitas, mengantisipasi konsekuensi dan melihat hubungan di luar objek yang bersangkutan dengan sendirinya merupakan nilai profesional yang hebat, begitulah cara programmer menjadi manajer dan bos. Dalam arti tertentu, memprediksi perilaku sistem yang kompleks, mengantisipasi konsekuensi dari koneksi sistem baru yang muncul, "debug mental" dan "pengujian untuk kasus-kasus ekstrem", "apa yang akan terjadi", sebagai keterampilan profesional programmer, mendorong mereka pertumbuhan menjadi manajer, bersama dengan keterampilan umum abstraksi, induksi dan deduksi. Benar, refleksi dan introspeksi, introversi, seperti sejumlah keterampilan profesional programmer lainnya, sebaliknya, membatasi mereka dalam pertumbuhan ini.



Bagaimana Anda belajar menghadapi kompleksitas? Saya tidak punya resep selain saran untuk belajar melihat apa yang berhasil untuk keterampilan ini dan apa yang bertentangan dengannya. Tapi bagaimanapun, saya pikir semuanya dimulai dengan pendidikan paling dasar. Studi. Pengulangan adalah ibu dari pembelajaran. Saya seorang guru, saya memiliki deformasi profesional: mengulangi hal yang sama dua kali. Saya seorang guru, saya memiliki deformasi profesional: mengulangi hal yang sama dua kali. Saya melatih jaringan saraf alami dangkal yang tidak mengalami overfitting , dan semua jaringan saraf perlu diambil sampelnya beberapa kali. Pengulangan juga merupakan cara untuk mengatasi kompleksitas, dengan pengulangan model mental realitas difaktorkan ulang, dan tidak ada yang lain.



Sering ada banyak keluhan tentang mengajar pada umumnya dan mengajar di sekolah dan universitas pada khususnya tentang fakta bahwa sesuatu yang tidak relevan sedang diajarkan, otak diisi dengan pengetahuan dan keterampilan yang tidak perlu. Putri saya memiliki kubus berongga dengan lubang geometri yang berbeda, dan hanya sosok yang lebih kecil dari bentuk yang sesuai yang jatuh di dalamnya. Apakah ada orang yang berpikir bahwa seorang anak yang diajari untuk memilih kunci dari bentuk geometris yang diinginkan akan membutuhkan keterampilan bugbear di masa dewasa?



Saya pikir bagian yang sangat serius dari pendidikan, dan sejak awal hingga mempertahankan disertasi pertama, adalah melatih otak untuk mengatasi kompleksitas. Ketika seorang anak di sekolah belajar mengalikan angka tiga digit dalam kolom di selembar kertas, tidak ada orang waras yang akan berpikir bahwa keterampilan ini akan berguna baginya dalam kehidupan. Mengalikan dua angka tiga digit dengan benar dalam sebuah kolom adalah latihan untuk melatih kemampuan otak, mengingat beberapa angka, dan tidak kehilangan konsentrasi untuk jangka waktu tertentu. Pertama tambahkan kolom, lalu kalikan, lalu bagi. Dengan meningkatkan kompleksitas. Kemampuan untuk mengejan, kemampuan untuk bekerja.



Apakah ini kualitas yang tepat? Itu tergantung pada siapa yang ingin Anda buat! Jika itu adalah "pengguna yang memenuhi syarat", maka itu tidak perlu. Jika "seorang pencipta", maka, saya pikir, diperlukan. Dalam hidup, kemampuan mengalikan dalam kolom tidak berguna, dalam hidup akan berguna untuk dapat mengalikan angka yang sama di telepon, jika Anda membutuhkan jawaban yang tepat - dan kemampuan untuk meninggalkan hanya 1 angka penting dari masing-masing nomor dalam pikiran Anda tanpa telepon dan memperkirakan kira-kira urutan nilai yang diperoleh. Dan ini, omong-omong, juga tidak lebih dari kemampuan untuk bekerja dengan kompleksitas: dengan cepat membuat keputusan pada data yang kompleks, menyederhanakan data input dan menggunakan perkiraan kasar. Tetapi jika seseorang percaya bahwa dalam pekerjaannya dia tidak perlu berkonsentrasi dan tanpa kesalahan melakukan beberapa operasi rutin serupa, maka kemungkinan besar dia tidak akan bekerja dengan kepalanya dalam kehidupan ini.



Menyimpulkan ini, tentu saja, aliran pemikiran yang tidak teratur, saya hanya ingin mengulangi sekali lagi seruan yang dibuat di paragraf pertama. Belajarlah untuk menyederhanakan kompleksitas di mana hal itu dapat dilakukan, belajarlah untuk menangani kompleksitas yang tidak dapat disederhanakan, dan kembangkan pengalaman dan kemampuan untuk membedakan yang pertama dari yang terakhir.



All Articles