Menjelang Moscow Python Conf ++, kami berbicara dengan Nikita Sobolev, CTO perusahaan We Make Services, tentang masalah global dalam mengelola kompleksitas kode dalam konteks pengembangan bahasa pemrograman. Dan juga tentang mengapa di sini seiring waktu situasinya semakin memburuk. Ditambah lagi mereka bertanya mengapa dia perlu membuat linter sendiri.
- Ceritakan beberapa hal tentang diri Anda dan pekerjaan Anda.Saya adalah direktur teknis "Kami melakukan layanan." Berbicara nama perusahaan, saya biasanya mengajukan pertanyaan: "Apa yang Anda pikirkan, apa yang kita lakukan?". Bahkan, kami berspesialisasi dalam pengembangan web: frontend dan backend untuk klien korporat. Dan kami bekerja sesuai dengan metodologi kami sendiri, yang kami tingkatkan sejalan dengan pengembangan perusahaan - Proses Pengembangan Perangkat Lunak Berulang (RSDP).
- Di Moscow Python Conf ++ Anda akan berbicara, termasuk tentang film Anda sendiri. Bagaimana pekerjaan Anda terkait dengan audit dan manajemen kompleksitas kode?Secara umum, kami memiliki dua bidang utama: pengembangan itu sendiri dan segala sesuatu di sekitarnya: konsultasi, menyusun persyaratan dan, khususnya, audit, di mana saya melihat banyak kode orang lain. Kode ini benar-benar berbeda: kode yang sekarang dalam pengembangan, dan warisan, yang tidak akan pernah diperbaiki oleh siapa pun; dan kode yang ditulis oleh spesialis pelanggan, dan kode yang mereka pesan di samping. Dan di semua versi kode ada banyak masalah: sama dan berbeda.
- Anda akan berbicara dengan pengembang secara khusus dalam Python. Apakah Python memiliki fitur dalam hal mengelola kompleksitas kode?Tentu saja!
Pertama, semua bahasa dengan pengetikan dinamis menderita tingkat yang lebih besar dari kompleksitas yang tidak dapat dibenarkan, setidaknya karena kurangnya konteks tambahan saat membaca kode. Dan Anda diizinkan lebih banyak kotoran.
Kedua, Python aktif berkembang. Ini memiliki elemen sintaksis baru, konsep dan modul baru di perpustakaan standar yang memecah semua yang sebelumnya.
- Seberapa buruk segalanya dalam Python? Lagipula, ada bahasa berkembang aktif lainnya, misalnya, JavaScript, yang sering dikritik untuk ini. Apakah JavaScript lebih baik?Tidak. Saya bahkan akan mengatakan bahwa dalam hal kompleksitas, Python cukup bagus sehubungan dengan bahasa lain. JavaScript benar-benar buruk karena satu alasan sederhana: dalam kode proyek JS, beberapa entitas yang tidak terkait dengan bahasa itu sendiri dicampur sekaligus - plugin pihak ketiga dan perpustakaan yang digunakan untuk membangun proyek. Misalnya, jika Anda menggunakan Webpack, Anda dapat menulis fungsi `import ()`, yang memuat modul secara tidak sinkron. Ternyata sang kolektor memasukkan beberapa bagiannya ke dalam bahasa pemrograman Anda, dan pada akhirnya umumnya tidak jelas apa yang terjadi.
Mengelola kompleksitas sulit ketika bahasa berubah dari menginstal Babel atau plugin-nya. Dan untuk memahami cara kerjanya, Anda harus mengikuti standar bahasa, implementasi spesifik, dll.
Dalam Python, situasinya jauh lebih baik. Bahasa berkembang cukup sistematis, dan perkembangan ini memiliki tonggak yang dapat dimengerti. Di dalamnya, Anda tidak dapat secara radikal mengubah sintaksis dengan dua baris dalam konfigurasi. Dan ini masih merupakan backend, di mana kita terbiasa membuat tuntutan yang lebih tinggi daripada ke frontend. Namun, menurut pendapat saya, di Python ada beberapa perubahan baru yang melanggar apa yang sebelumnya, membawa manfaat yang meragukan.
- Artinya, dengan perkembangan bahasa, semuanya menjadi lebih buruk?Jika Anda ingat bahwa AsyncIO muncul - pada dasarnya bahasa kedua di dalam Python - tentu saja, kompleksitasnya telah berkembang sangat pesat. Bahkan, sekarang ada dua bahasa pemrograman yang sepenuhnya independen dengan sintaksis yang sama: Python dan Python + AsyncIO. Artinya, Python sebagai entitas telah menjadi lebih rumit dua kali lipat, karena memiliki dua keturunan terpisah yang bekerja sesuai dengan aturan yang berbeda.
Pendapat bahwa ini adalah bahasa pemrograman yang berbeda tidak populer. Namun, ketika Anda meminta lawan pendapat ini, misalnya, untuk menjalankan fungsi asinkron dari kode sinkron, mereka gagal. Perpustakaan juga sangat berbeda. Ingin menggunakan pustaka sinkron untuk bekerja dengan database - silakan. Dan Anda ingin tidak sinkron - tidak.
Tetapi dalam Python, yang ditulis lima tahun lalu, tidak ada yang benar-benar berubah, dan bahkan sebaliknya, alat muncul yang menyederhanakan kode, misalnya, penjelasan dan pengecekan jenis.
- Apakah pengelolaan kompleksitas memengaruhi fakta bahwa dalam pemrograman sekarang ada cukup banyak orang dengan basis teknis yang lemah?Tentu saja Untuk orang-orang seperti itu, mereka bahkan datang dengan bahasa pemrograman khusus. Itu disebut Go. Saya tidak bercanda. Memang, tujuan menciptakan bahasa Go adalah upaya untuk melibatkan siswa dan magang Google yang tidak dapat mempelajari C ++ dalam menulis kode. Python tidak cocok dengan mereka dalam kinerja, mereka membutuhkan sesuatu yang lain, dan Google datang dengan Go. Ternyata, banyak orang yang siap untuk menulisnya, karena sangat sederhana. Tetapi pada biaya apa kesederhanaan ini telah dicapai? Mereka memberi kita bukan bahasa pemrograman normal, tetapi versi yang sangat terpotong - praktis tidak ada konsep rumit dengan desain di dalamnya. Tidak ada obat generik, tidak ada pengecualian, dll. Dan ada banyak penggemar pendekatan ini.
Tetapi ada pengembang lain, dan bagi mereka masalahnya adalah bahwa ada bahasa di mana tidak ada keseimbangan: Anda dapat melakukan hal-hal sederhana, dan Anda tidak dapat melakukan hal-hal rumit sama sekali. Atau setidaknya melalui rasa sakit - Anda harus bertarung dengan alat untuk melakukan sesuatu. Di sini, menurut saya, adalah masalah mengelola kompleksitas.
- Apa masalah khas kode orang lain?Biasanya mereka dibagi menjadi dua bagian.
Yang pertama adalah masalah yang terkait dengan fakta bahwa orang tidak dapat menyetujui di mana harus menempatkan koma bersyarat. Anda membaca satu kode dan melihat koma di satu tempat, beralih ke file lain - dan melihat koma di tempat lain. Ini mempersulit persepsi, seolah-olah membaca buku yang dicetak tebal di satu tempat dan dicetak miring. Ini mengalihkan perhatian dari isi, karena otak harus mengenali bahwa itu adalah cara berbeda untuk menulis hal yang sama.
Ketika Anda mengoreksi sintaksis, Anda mulai memperhatikan semantik, karena orang menulis secara konseptual berbeda. Sayangnya, tidak ada cara untuk menyetujui tingkat ini - tidak mungkin untuk mencapai kesepakatan bahwa kita memecahkan masalah seperti itu dengan cara ini, tetapi ini adalah seperti itu. Awalnya tidak mungkin mencakup semua kasus. Proses ini terjadi selama peninjauan kode dari tugas segera: ketika pengembang dijelaskan mengapa keputusannya tidak dapat dibuat. Jika praktik tinjauan kode diterapkan dan pengulas baik, mereka memotong kurva solusi dan tidak ada masalah dalam kode. Tapi biasanya kami datang ke audit di mana proses seperti itu tidak dilakukan. Dan masalah semantik dan arsitektur jauh lebih sulit untuk dipecahkan, karena mereka kadang-kadang sulit untuk dirumuskan dan didefinisikan sendiri.
- Dan seperti apa bentuknya dalam praktik?Misalnya, orang dapat memecahkan masalah yang sama dalam templat, dalam tampilan, atau dalam model. Dan tidak ada pemahaman yang diterima secara umum di mana tepatnya tugas ini harus diselesaikan: tidak ada dokumentasi atau pola yang berlaku khusus untuk proyek ini (misalnya, di sini kami menggunakan model tebal dan memasukkan semua logika ke dalamnya, tetapi di sini kami menggunakan yang tipis; baik atau buruk, sekarang itu tidak masalah, tapi kami sepakat).
"Apa yang kamu lihat sebagai alasan utama bahwa masalah ini bahkan ada?"Semua orang tidak tahu cara menulis kode.
Tesis ini diuraikan sebagai berikut: masalahnya adalah kita adalah manusia. Dan secara umum sangat sulit bagi kita untuk menulis sesuatu yang terstruktur dan logis. Dan di sini kami juga memiliki dua jenis penerima yang berbeda. Pertama, ini adalah orang yang akan membaca kode ini, dan kedua, ini adalah mesin yang harus menjalankannya. Kode untuk mesin harus dibuat sesuai dengan kriteria kinerja, konsumsi memori dan waktu CPU, dan kode untuk orang tersebut harus berdasarkan pada prinsip keterbacaan, kejelasan, dll. Ini adalah dua tugas yang berlawanan. Dan seseorang yang, pada kenyataannya, tidak dapat sepenuhnya menyelesaikan salah satu dari mereka, dipaksa untuk menyelesaikan kedua tugas yang saling bertentangan pada saat yang sama.
"Tapi penggunaan pola pemrograman yang berbeda pada dasarnya adalah pencarian teknik?" Apakah ini benar-benar buruk?Tentu saja, riset teknik penting dan perlu. Tapi dia juga harus bisa dikendalikan. Sebelum setiap tugas seperti itu, perlu menetapkan kriteria dan batasan yang jelas: sesuai dengan waktu yang dihabiskan, untuk persyaratan bisnis, pada praktik dan alat teknik.
Saya jauh lebih mungkin mengamati pencarian kreatif. Tidak ada batasan seperti itu, validasi dari hasil yang diperoleh juga. Kualitas - seperti dalam seni kontemporer - tidak dapat diukur.
Hampir semua klien yang datang kepada kami untuk audit menderita dari situasi yang khas: seseorang melakukan sesuatu kepada mereka, mereka menyewa seorang pengembang untuk entah bagaimana mengembangkan solusi, tetapi dia datang dan mengulurkan tangannya: di sini untuk dilakukan, mari kita menulis ulang semuanya. " Apakah menyenangkan menulis ulang? Tidak akan. Ketika Anda memutuskan untuk menulis ulang, Anda menginjak rake yang sama persis: Anda mempercayakan tugas tersebut ke pengembang lain yang membuat kesalahan lain, tetapi pada akhirnya semuanya ternyata persis sama.
- Perlu pendekatan lain?Ya Selama audit, kami mencoba mencari penyebab masalah dengan kode: mengapa tidak ada orang yang mengambil dan menggembungkan modul ke titik yang sulit untuk digulirkan, dan mengapa keputusan yang salah dibuat pada awalnya. Dan kami mencoba untuk mengotomatisasi atau menyederhanakan sebanyak mungkin keputusan yang tepat dalam batas yang diberikan.
Saya akan memberikan bagian kecil ke dalam laporan. Setiap orang memiliki pemahaman bahwa kode terdiri dari baris - ini adalah entitas paling sederhana yang dapat terdiri dari. Setiap baris dapat ditulis sebagai
x = 1
atau mungkin suka
x = Math.median(forecast_data) if forecast_data else compute_probability(default_model)
.
Ada perbedaan yang sangat besar antara kedua garis ini, karena Anda mudah memahami yang pertama, dan banyak logika terkonsentrasi di yang kedua. Perlu untuk menjalankannya di kepala secara paralel dengan juru bahasa. Oleh karena itu, Anda harus mulai mengendalikan cara Anda menulis kode, dengan kontrol satu baris kode. Lebih jauh garis berubah menjadi konsep yang lebih kompleks - fungsi, kelas, modul, dll. Tetapi aturan yang Anda terima harus satu.
Sebagai hasilnya, kami tidak melarang banyak hal dilakukan. Karena manajemen adalah tentang larangan yang diberlakukan.
- Apakah Anda menemukan hal-hal lucu dalam kode orang lain?Tentu saja Saya bahkan punya
repositori tempat saya mengumpulkan contoh kode seperti itu.
Contoh paling menakutkan yang saya lihat menunjukkan kepada saya bahwa di dalam loop dari seratus iterasi, Anda dapat mendefinisikan suatu fungsi. Sejujurnya, ketika saya melihatnya, penerjemah saya rusak. Saya menduga, tetapi tidak tahu bahwa itu mungkin.
Ada suatu kasus ketika kami melihat banyak komentar lucu dalam kode. Seseorang mengeluh tentang kehidupan, tentang pekerjaan, ada yang menulis: "Saya mengerti bahwa saya menulis omong kosong, tetapi pelanggan memaksa saya untuk melakukannya." Namun, pelanggan biasanya tidak memaksa Anda untuk menulis kode yang buruk. Mereka meminta untuk memecahkan masalah mereka, dan kode apa yang Anda tulis di sana, mereka tidak peduli.
- Linter, review kode - jangan simpan?Saya punya dua jawaban. Ya, benar. Tidak, mereka tidak menyimpan. Ini membantu jika Anda benar-benar mengikuti aturan dan peraturan yang diberikan kepada Anda oleh lier lanters (mereka yang melakukan banyak pekerjaan kasar untuk Anda: periksa fungsi untuk kompleksitas, kode semantik, dll.). Item ini harus diblokir. Anda tidak bisa menjalankan linter sesekali untuk melihat hasilnya. Jika Anda gagal aturan ini, maka Anda tidak boleh merilis kode sama sekali dalam produksi.
Tetapi pada kenyataannya - mereka tidak menyimpan. Karena proyek-proyek yang menggunakannya jarang terjadi.
Kebetulan, mereka sering bertanya kepada saya: bagaimana cara memperkenalkan ini? Dan saya menjawab: ini sangat sederhana, Anda meletakkan garis di CI - periksa kode saya - dan jika crash, itu saja, Anda menerapkannya. Tetap hanya untuk memperbaiki segalanya. Untungnya, sekarang ada autoformatters dan kemampuan untuk memperbaiki file kode dengan file. Pertanyaan selanjutnya adalah tradisional: bagaimana menjelaskan kepada bisnis bahwa ini penting?
- Apakah ada jawaban umum untuk pertanyaan ini?Untuk setiap kasus, jawabannya berbeda, jadi dalam kasus umum sulit untuk dirumuskan (Anda perlu memikirkannya, tentang ini ...). Tetapi biasanya perusahaan yang menangani masalah ini berasal dari sisi teknis. Yaitu teknisi bertanya kepada kami, sebagai orang yang tahu bagaimana berbicara tentang bisnis, dan tentang teknologi memahami bagaimana menjelaskan ini kepada bisnis dalam kasus khusus mereka. Dengan pernyataan masalah seperti itu, ini sangat sederhana. Ketika Anda datang, semuanya sudah buruk, dan semua orang mengerti ini. Pembicaraan dengan bisnis dimulai seperti ini: "Anda mungkin berpikir bahwa programmer Anda sedang duduk dan tidak melakukan apa-apa?" Dan bisnis itu mengangguk. Dan Anda mengatakan itu bukan itu intinya. Programmer adalah orang-orang hebat yang mencoba menyelesaikan masalah Anda. Tetapi tanpa pendekatan terpadu untuk manajemen proyek, semuanya jatuh ke dalam kekacauan, dan ini normal.
Dan kami mengusulkan untuk membuat aturan untuk menghindari masalah tertentu. Kami mempertimbangkan biaya untuk memperkenalkan potongan-potongan yang berbeda, dan kemudian kami mengevaluasi kerugian nyata (selesai) dari kenyataan bahwa belum ada potongan tersebut. Misalnya, programmer telah memperbaiki bug selama sebulan yang tidak ada atau yang dapat ditemukan dalam 30 detik, jika Anda menggunakan pendekatan dan alat khusus. Angka-angka meyakinkan dengan baik.
- Pada akhirnya, apakah ini masalah administrasi?Tentu saja Saya yakin bahwa programmer ingin menulis kode yang baik. Namun ada berbagai kendala. Seseorang tidak tahu caranya karena kurang pengalaman. Seseorang kehilangan motivasi, karena semua orang tidak peduli. Seseorang tidak tahu apa sebenarnya kode yang baik untuk alasan itu, katakanlah, melempar kreatif. Mereka menekan seseorang - dia ingin dan bisa menulis, tetapi mereka mengatakan kepadanya bahwa itu harus besok. Dan alih-alih membangun kemitraan dengan bisnis dan menjelaskan mengapa ini tidak akan terjadi besok (atau jika itu terjadi, maka akan diperlukan untuk memerintah selama tiga hari lagi), tetapi dia melakukannya. Dan kemitraan semacam itu menarik bagi bisnis itu sendiri. Dia juga perlu membuatnya bekerja untuk waktu yang lama dan murah untuk dirawat.
Artinya, semua masalah diselesaikan di sini: tidak ada kontradiksi yang tak terpecahkan.
- Ada gaya kode - PEP 8. Tidak membantu untuk dengan cepat memahami apa yang baik?Dalam hal koma, itu membantu. Tapi apa gunanya jika Anda menempatkan koma yang benar dan yang lainnya buruk?
- Kehilangan beberapa hal tingkat tinggi yang terkenal?Secara teori, ada beberapa praktik rekayasa terbaik. Tapi mereka tidak diketahui atau diabaikan. Ketika Anda bertanya mengapa pengembang tidak mengikuti praktik ini, ia mengatakan bahwa ia mendengar bahwa ini adalah topik yang baik, tetapi kodenya berfungsi seperti itu. Ketika kode berhenti bekerja, Anda bertanya apakah dia mengerti dari mana praktik terbaik yang sesuai berasal dan mengapa mengikutinya? Tidak, saya tidak mengerti. Dia percaya bahwa dia keliru.
Cukup sulit untuk menjelaskan kepada seseorang bahwa melakukan kesalahan adalah hal biasa. Setiap orang salah, kita semua adalah manusia. Tetapi praktik rekayasa terbaik hanya diciptakan untuk menyelamatkan Anda dari kesalahan atau melindungi Anda dari konsekuensi. Yaitu itu adalah alat keamanan, seperti di perusahaan. Itu hanya ditulis tidak dengan darah, tetapi dengan membuang waktu dan uang.
Secara umum, tugas global kami yang tidak terjangkau adalah untuk mengotomatiskan tinjauan kode sehingga Python sendiri (jika kita berbicara tentang kasus kami) tahu cara menulisnya. Ini harus menjadi alat yang tidak hanya menyediakan peluang, tetapi juga batasan bagi pengembang.
- Mengapa Anda mengembangkan linter? Apakah mungkin menggunakan (atau mengembangkan) yang sudah ada?Faktanya, kami melakukannya. Linter kami sebenarnya adalah plugin untuk Flake8. Kami hanya memposisikannya sebagai alat lengkap, dan bukan hanya sebuah plug-in.
Mengapa Flake8 dan bukan Pylint? Pylint melakukan banyak hal yang tidak boleh dilakukan oleh si pemberi semangat. Sebagai contoh, ia mengimplementasikan sejumlah besar pemeriksaan tipe, meskipun pemeriksa tipe harus berurusan dengan tipe. Plus, itu menghasilkan sejumlah besar kesalahan, yang sebenarnya tidak. Dan saya tidak suka dokumentasinya, dan saya takut akan penerapan astnya sendiri. Sulit untuk dikonfigurasikan. Dengan mengaktifkan konfigurasi, Anda membiarkan orang membuat pilihan yang salah. Karena itu, tugas kita adalah membuat alat yang tidak dapat dikonfigurasi. Jadi Anda katakan - itu saja.
- Panduan apa yang membentuk dasar dari linter ini? Atau hanya pengalaman Anda sendiri di sini?Sekarang ini didasarkan pada aturan yang telah kami rumuskan untuk diri kami sendiri pada tinjauan kode selama bertahun-tahun. Beberapa aturan porting dari linter lain: ESLint, Pylint, SonarQube, Credo. Banyak yang telah diambil dari karya
CognitiveComplexity yang sangat baik. Selalu menatap Dompet Miller. Aturan terpisah - ini adalah visi saya, yang muncul setelah mengevaluasi sejumlah besar kode orang lain. Artinya, pada tahap ini adalah "gado-gado".
- Apa yang akan Anda bicarakan di Moscow Python Conf ++?Pertama-tama, tentang
manajemen kompleksitas . Topik ini dekat dan dapat dimengerti oleh semua pengembang. Kami akan melihat berbagai metrik, tentang cara mentransfer kompleksitas dari kode komponen paling sederhana - baris - ke modul paling kompleks. Dan kemudian kita akan berbicara tentang bagian holivary, di mana saya akan mempresentasikan visi saya tentang bagaimana sebaiknya atau tidak menulis dengan Python, dan meminta pengguna untuk memilih apa yang mereka suka dan apa yang tidak. Bagi banyak pengembang, pembatasan (melakukan A, tetapi tidak melakukan B) adalah upaya pada ruang kreatif mereka, sehingga mereka bereaksi sangat keras terhadap ini. Dan di sini Anda dapat memulai diskusi yang menarik.
- Siapa yang menjadi fokus laporan?Saya pikir ini masih pengembang mapan, karena programmer pemula belum membentuk pendapat yang jelas. Meskipun akan menarik bagi mereka untuk mendengarkan dan berbicara. Mereka pasti pengguna kami.
, ,
Moscow Python Conf++ . . ,
.