Penasaran Penasaran dari Dunia IT - 4

gambar

Situs web Daily WTF telah mengumpulkan cerita-cerita lucu, liar dan / atau sedih dari dunia TI selama 15 tahun. Saya menerjemahkan beberapa cerita yang sepertinya menarik bagi saya. Semua nama dan nama perusahaan telah diubah. Masalah sebelumnya dapat ditemukan di bawah label " penyimpangan penasaran ."

Kisah pertama. Akhir bulan


[Asli]

Jika Anda bertanya kepada seorang insinyur desain apakah aman berjalan melintasi jembatan, ia akan dengan senang hati memberi tahu Anda seberapa andal jembatan itu, bagaimana matematika bekerja di dalamnya, seberapa jauh kita telah mencapai masalah keamanan bangunan. Setelah berbicara dengannya, Anda akan mendapat kesan bahwa tidak ada satu jembatan pun di Bumi yang akan hancur berantakan. Tetapi jika Anda bertanya kepada insinyur pengembangan perangkat lunak tentang bank, maka kemungkinan besar Anda akan ngeri, dan dengan probabilitas 50/50 meyakinkan diri Anda untuk menginvestasikan semua uang dalam bitcoin. Bank terkenal karena keputusan buruk mereka ketika membuat perangkat lunak - bukan karena keputusan ini menjijikkan, tetapi karena kebanyakan orang menganggap bahwa bank lebih akurat dan berhati-hati tentang keamanan.

Kato bekerja di Inibank, di mana produk komersial bernama T24 digunakan sebagai inti dari sistem perbankan. Sistem T24 digunakan oleh ratusan bank di seluruh dunia. Dapat disesuaikan untuk berbagai solusi perbankan. Seperti kebanyakan paket khusus. Ada programmer yang berspesialisasi dalam penulisan kode untuk itu, dan konsultan yang membantu bank dengan pembaruan besar.

Staf Inibank sibuk, sehingga bank mengundang konsultan untuk berpartisipasi dalam proyek khusus. Pada akhir hari kerja, bank melakukan proses penyelesaian, yang diperlukan agar semua uang mengalir sesuai dengan yang diperintahkan, semua data output yang diperlukan dihitung ulang, dan semua laporan yang diperlukan dieksekusi. Di bank, proses ini juga mengubah tanggal sistem ke hari kerja berikutnya. Itulah sebabnya ketika Anda melakukan perbankan online pada hari Minggu, tidak satu transaksi pun mulai diproses hingga Senin pagi. Konsultan harus membuat laporan baru yang akan dieksekusi selama proses penyelesaian dan termasuk pemrosesan tambahan jika tanggalnya sesuai dengan akhir bulan.

Kato menunjukkan kepada konsultan baru bagaimana bank membuat laporan akhir hari. “Lihat, kami memiliki variabel global untuk hari kerja sebelumnya, untuk hari ini, dan untuk hari kerja berikutnya. Mereka memiliki format YYMMDD untuk membuatnya lebih mudah untuk dikerjakan. "

"Ya, ya, mengerti. Saya mengerti. Apa format mereka? "

"... Uhh ... Aku hanya bisa berasumsi bahwa ini adalah tahun, bulan, dan hari."

“Ya, ya, baiklah. Bagus Lalu saya mulai bekerja. "

Setelah percakapan ini, Kato punya firasat buruk tentang ini. tetapi dia berusaha menyingkirkannya. Konsultan mengatakan bahwa semuanya sudah diatur dan siap. Dia tahu persis apa yang dia lakukan, kan? Kato membuang ini keluar dari kepalanya dan berhenti khawatir sampai waktu untuk meninjau kode tiba dan dia menemukan mutiara seperti itu:

 TH.DATE = R.DATES(EB.DAT.NEXT.WORKING.DAY)[1,6]:"01" CALL CDT('ES00',TH.DATE,"-1C") WTODAY = OCONV(DATE(),"DY") : FMT(OCONV(DATE(),"DM"),'R%2') : FMT(OCONV(DATE(),"DD"),'R%2') IF TH.DATE EQ WTODAY THEN 

Jelaskan dengan singkat apa yang terjadi di sini:

  1. Ambil hari kerja berikutnya dan ubah hari menjadi 01 untuk mendapatkan hari pertama bulan itu.
  2. Kami mengubah tanggal ini dengan mengurangi 1 hari kalender pada kalender Spanyol.
  3. Kami mengambil tanggal dari server dan menerjemahkannya ke format YYYYMMDD, memanggil perintah Date tiga kali.
  4. Jika tanggal yang dihitung pada langkah 2 sama dengan tanggal yang dihitung pada langkah 3, mulailah prosesnya.

Sebenarnya ... itu berhasil. Sebagian besar. Kecuali untuk beberapa alasan, akhir hari tidak terjadi setelah tengah malam pada hari terakhir dari bulan - dan ini tidak begitu jarang. Dalam hal ini, kode tersebut akan secara keliru berpikir bahwa ini adalah hari terakhir bulan itu, dan akan mulai membuat laporan. Yang berjalan dengan baik dengan masalah lain: jika hal yang sama terjadi pada hari terakhir bulan itu, maka membuat laporan tidak akan dimulai dengan kesalahan. Dan bug terbaik: jika hari terakhir pada bulan itu ternyata adalah hari Minggu, maka kalender server tidak akan pernah diinstal di sana, karena itu melompati hari yang tidak bekerja.

Berbicara tentang hari-hari yang tidak bekerja: karena Inibank berlokasi di AS, tidak ada alasan untuk menggunakan kalender Spanyol. Ya, bulan dan minggu akan sama, tetapi dalam kalender perangkat lunak Spanyol Anda perlu menentukan hari libur bank di AS, jika tidak, program akan terus bekerja. Akhirnya, seolah-olah semua ini belum cukup, Triple Date call berarti bahwa mungkin ada perbedaan pendapat ketika mulai tepat di tengah malam: nilai bulan diminta sebelum tengah malam, dan hari setelahnya.

Kato menambahkan komentar, menyarankan cara untuk mengubah kode:

 IF R.DATES(EB.DAT.TODAY)[5,2] # R.DATES(EB.DAT.LAST.WORKING.DAY)[5,2] THEN 

Lima menit kemudian, konsultan pergi ke mejanya. "Apa maksud edit ini?"

Kato sedang tidak ingin berdebat pada saat itu. “Kode kamu rusak, teman. Semua ini tidak perlu. "

“Begitu, begitu. Ini sebenarnya hanya prosedur operasi standar untuk industri kami. Baiklah, oke. "

Kato sangat meragukan itu, tetapi hanya mengangkat bahu. “Maka industrinya salah. Saya menjelaskan semuanya dalam komentar. "

"Ya. Ya saya membacanya. Tetapi saya akan membacanya lagi. " Dan dia menghilang dengan tiba-tiba saat dia muncul.

Pengeditan dilakukan, Kato menyetujui kode itu, dan konsultan menghilang ke kabut.

Kadang-kadang, berbaring di tempat tidur pada malam hari, Kato bertanya-tanya: apakah konsultan itu benar-benar memahami kesalahannya, atau apakah dia hanya setuju untuk melihat, menerima ceknya dan terus menulis di suatu tempat kode yang mengerikan dengan harga dua kali gaji Kato? Di bank-bank di mana tidak ada karyawan yang dapat memverifikasi kode.

Tetapi jangan menginvestasikan semua uang dalam bitcoin. Bahkan lebih buruk di sana.

Kisah kedua. Bagaimana ini dilakukan


[Asli]

Orang suka makan hot dog sampai mereka tahu cara memasaknya. Kebanyakan tidak bertanya, karena mereka tidak mau tahu dan terus makan hot dog. Saat mengembangkan perangkat lunak, terkadang kita harus bertanya. Bukan hanya untuk memecahkan masalah, tetapi juga karena beberapa programmer takut bahwa perangkat lunak di mobil mereka, yang bepergian di sepanjang jalan raya dengan kecepatan 100 km / jam, dirakit dari pita dan tongkat. Seluruh industri kami melakukan tugasnya dengan buruk .

Brett bekerja sebagai analis sistem di MedStitute Medical Research Center. MedStitute menggunakan perangkat lunak berpemilik yang disebut MedTech untuk menyimpan dan menganalisis data. Dokter dan peneliti menyukai hasil MedTech, tetapi kolega Brett Tyree tahu bagaimana mereka diciptakan.

Perangkat lunak tidak memiliki akses ke backend, dan seluruh proses pengembangan terjadi di GUI "mouse yang dapat diprogram". Antarmuka ini terlihat seperti ditulis oleh orang yang mempelajari pemrograman oleh situs web copy-paste dari tahun 90-an, melihat sepuluh menit dari Jurassic Park dan mencari jawaban untuk StackOverflow sampai sesuatu dapat dikompilasi. "Bahasa pemrograman" juga menunjukkan tingkat perhatian yang serupa dalam filosofi desain. Masing-masing if pasti memiliki yang else . Beberapa modul menggunakan nilai Boolean, yang lain mengembalikan string kosong untuk menunjukkan nilai yang salah. Dari dokumentasi itu tidak jelas dalam situasi yang satu atau yang lain terjadi. Bahkan, setiap if berubah menjadi tiga pernyataan.

Brett perlu memulai studi baru. Itu didasarkan pada satu set statistik sederhana dan mengelompokkan pasien menggunakan variabel acak. Brett mencari dalam daftar untuk variabel yang dapat diacak, tetapi tidak merasa perlu. Dia menyarankan agar dia melakukan kesalahan dan kembali beberapa layar untuk memeriksa namanya dengan menyalin untuk pencarian. Brett kembali ke daftar variabel acak. Dia tidak ada di sana. Dia melihat lebih dekat pada daftar dan memperhatikan bahwa daftar variabel acak berisi data dari bidang pilihan ganda. Bidang yang dia perlu untuk acak didasarkan pada bidang yang dihitung.

Brett tahu bahwa Tyree sedang mengerjakan proyek lain yang diacak oleh bidang komputer, jadi dia menghubunginya di Slack. “Bagaimana Anda menyandikan variabel acak ini? Apakah Medtech mencegah hal ini terjadi? "

"Aku sedang berbicara tentang konferensi, aku akan meneleponmu lagi nanti," tulis Tyree.

Beberapa menit kemudian Tyree menelepon Brett.

“Anda harus mulai dengan dua bidang. Katakan saja. sebut saja mereka $variable_choice , yaitu, pertanyaan pilihan ganda, dan $variable_calced , yaitu, bidang terhitung Anda. Saat Anda ingin membuat variabel yang membuat pemilihan acak berdasarkan bidang terhitung, Anda memberi tahu Medtech bahwa variabel acak ini didasarkan pada $variable_choice . Kemudian Anda menghapus $variable_choice , dan mengganti nama $variable_calced menjadi $variable_choice

“Berhenti, sistem memungkinkan Anda untuk melakukan ini, tetapi tidak memungkinkan Anda untuk mengacak bidang terhitung dengan cara lain? Dan dia tidak memeriksanya? "

"Saya harap tidak ada perubahan, dan dia tidak mulai memverifikasi ini sampai proyek saya selesai," jawab Tyree.

“Studi ini harus dilakukan selama sepuluh tahun. Dan penyelesaiannya yang sukses tergantung pada apakah pengembang menganggap trik ini sebagai bug? ”

“Saya hanya berhasil menemukan solusi seperti itu. Beri tahu saya jika Anda menemukan sesuatu yang lebih baik. ”

Brett tidak puas dengan peretasan semacam itu, dan ia kembali mempelajari dokumentasinya. Ia menemukan solusi "lebih baik": Anda bisa membuat bidang pilihan ganda baca-saja dengan satu-satunya nilai default - nilai bidang terhitung. Sayangnya, pengguna secara tidak sengaja dapat mengubah daftar dengan menjawab pertanyaan pilihan ganda sebelum menghitung nilai bidang yang dihitung.

Pada akhirnya, satu-satunya yang tersisa bagi Brett adalah istirahat, pergi ke kafetaria dan membeli beberapa hot dog.

Cerita ketiga. Portabilitas dan perangkat keras


[Asli]


Beberapa bulan yang lalu, ketika PC memiliki kasus logam dan plastik yang berat, Matt dan rekannya diminta untuk mengevaluasi paket perangkat lunak untuk operasi departemen penjualan yang akan datang. Sayangnya, ia dan koleganya bekerja di kantor yang berbeda di kota yang sama. Di era itu, alat kolaborasi online yang efektif belum ada, jadi Matt secara teratur harus pergi ke kantor lain, membawa PC bersamanya. Ini berarti bahwa setiap kali perlu untuk melepaskan kabel periferal dari case 473, membawa komputer di sepanjang koridor dan menuruni tangga, naik bus untuk menuju ke kantor lain, di mana ia melakukan semua ini dalam urutan terbalik. Terkadang organisasi buruh yang salah memaksa pasangan ini untuk bekerja di akhir pekan, yang berarti mereka membawa mesin kerja ke rumah.

Dalam prosesnya, hard drive 20 MB di komputer Matt meluap. Dari kantornya, ia mengirim permintaan ke departemen TI. Untuk memenuhi aplikasi, teknisi Gary ditunjuk, yang setelah beberapa waktu muncul di kubus Matt, memegang hard disk baru dan obeng. Gary mengirim Matt minum kopi untuk fokus pada "pasiennya." Setelah sedikit operasi, PC Matt dinyalakan dan bekerja dengan hard drive yang besar.

Sehari sebelum batas waktu proyek, Matt hampir menyelesaikan bagiannya dari pekerjaan. Dia hanya perlu membuat beberapa tambahan pada laporannya, dan kemudian menyalinnya ke disket dan mengirimkannya ke departemen penjualan. Mengembalikan PC-nya ke kubus dan menghubungkan kabel-kabel, dia menyalakan power dan mendengar bunyi letupan. PC sudah mati dan tidak menunjukkan tanda-tanda kehidupan.

Setelah panik menelepon ke departemen TI, Gary kembali muncul di kantornya dengan obeng. Membuka kasing PC, ia langsung berteriak: “Tunggu sebentar! Apakah Anda menyeret komputer ke suatu tempat? "

Matt mengerutkan kening. "Ya, tentu saja. Apakah itu masalahnya? "

“Ya tentu saja! Anda seharusnya tidak melakukan itu! "Gary mulai mengutuk. "Hard drive mulai nongkrong dan mempersingkat semuanya di dalam!"

Matt membungkuk pada Gary untuk melihat sendiri bagian dalam komputer itu. Dia segera memperhatikan bahwa hard drive baru "diperbaiki" untuk ditempel.

"Berhenti! Bahwa kamu seharusnya tidak melakukan ini! " Matt menunjuk ke selotip scotch. "Haruskah aku menghubungi atasanmu untuk berjaga-jaga?"

Wajah Gary mengerutkan kening. "Mereka tidak memberi saya pengencang yang diperlukan!"

"Lalu temukan orang yang memilikinya!"

Mengingat tenggat waktu yang akan datang, dengan izin bos, Matt mentransfer permohonannya lebih tinggi lagi. Hampir seketika, pita perekat diganti dengan perangkat keras asli. Dia tidak pernah mengerti mengapa karyawan departemen TI tidak memiliki akses ke peralatan yang diperlukan; dia menyarankan bahwa itu adalah ide cemerlang seorang idiot untuk menghemat uang. Matt hanya bisa menebak apa improvisasi putus asa lainnya yang membuat infrastruktur TI mereka berfungsi, dan berapa lama mereka akan luput dari perhatian jika PC-nya tidak rusak.

Kisah keempat. Ini adalah bagaimana PL / SQL mempengaruhi otak Anda.


[Asli]

Juara abadi di antara keputusan-keputusan aneh dan paling tidak berhasil selamanya akan tetap menjadi Oracle . Hari ini kita melihat sedikit kode PL / SQL.

PL / SQL adalah bahasa yang aneh, campuran dari SQL dan P rocedural (prosedural) L bahasa (bahasa) dengan objek-berorientasi terpaku ke samping. Sintaksnya mampu menciptakan kesan bahwa itu dikembangkan pada tahun 1970-an, dan setiap fungsi baru atau perubahan bahasa melanjutkan tradisi ini.

Struktur setiap modul kode PL / SQL berbasis blok . Setiap blok adalah namespace independen. Singkatnya, anatominya terlihat seperti ini:

 DECLARE -- variable declarations go here BEGIN -- code goes here EXCEPTIONS -- exception handling code goes here, using WHEN clauses END; 

Jika Anda menulis prosedur tersimpan atau pengendali acara, maka ganti kata kunci DECLARE dengan CREATE [OR REPLACE] . Anda juga dapat membuat sarang di dalam blok lain, jadi cukup sering Anda dapat melihat kode terstruktur dengan cara ini:

 BEGIN DECLARE --stuff BEGIN --actions END; --more actions END; 

Ya, cukup cepat itu mulai membingungkan. Dan ya, jika Anda ingin memberikan setidaknya penanganan kesalahan yang terstruktur, Anda harus mulai saling memblok.

Bahasa dan database memiliki fitur menyenangkan lainnya. Sebelum versi 12c, mereka tidak memiliki tipe kolom IDENTITY . Dalam versi sebelumnya, Anda harus menggunakan objek SEQUENCE dan menulis prosedur atau penangan peristiwa yang melakukan penomoran otomatis secara paksa. Biasanya, operator SELECT INTO… digunakan untuk menetapkan nilai ke variabel. Bonus: Oracle SQL selalu membutuhkan tabel untuk ditentukan dalam pernyataan FROM , jadi Anda harus menggunakan tabel dual diciptakan, seperti ini:

 CREATE TRIGGER "SOME_TABLE_AUTONUMBER" BEFORE INSERT ON "SOME_TABLE" FOR EACH ROW BEGIN SELECT myseq.nextval INTO :new.id FROM dual; END; 

:new dalam konteks ini menunjukkan baris yang kami beri penomoran secara otomatis. Dalam versi Oracle yang lebih lama, ini adalah cara "biasa" untuk membuat kolom dengan penomoran otomatis. Benoit menemukan cara lain yang sedikit kurang umum untuk melakukan operasi yang sama:

 CREATE OR REPLACE TRIGGER "SCHEMA1"."TABLE1_TRIGGER" BEFORE INSERT ON "SCHEMA1"."TABLE1" FOR EACH ROW BEGIN DECLARE pl_error_id table1.error_id%TYPE; CURSOR get_seq IS SELECT table1_seq.nextval FROM dual; BEGIN OPEN get_seq; FETCH get_seq INTO pl_error_id; IF get_seq%NOTFOUND THEN raise_application_error(-20001, 'Sequence TABLE1_SEQ does not exist'); CLOSE get_seq; END IF; CLOSE get_seq; :new.error_id := pl_error_id; END; END table1_trigger; 

Banyak yang terjadi di sini. Pertama, perhatikan bahwa bagian DECLARE berisi pernyataan CURSOR . Kursor memungkinkan Anda untuk beralih melalui catatan. Mereka sangat mahal dan di dunia Oracle itu adalah sumber daya yang perlu dibebaskan.

Penangan kejadian ini (pemicu) menggunakan blok bersarang tanpa alasan. Itu juga menggunakan pl_error_id variabel tambahan, yang dapat ditiadakan.

Tetapi bagian yang sangat aneh adalah blok IF get_seq%NOTFOUND . Semuanya cukup sederhana: memeriksa kondisi bahwa kursor tidak mengembalikan string. Untuk kursor ini, ini tidak dapat terjadi bahkan secara teoritis , sehingga operasi di dalamnya tidak pernah dilakukan. Urutan selalu mengembalikan nilai. Dan ini bagus , mengingat kode yang melangkah lebih jauh.

raise_application_error adalah analog dari throw in Oracle. Pernyataan ini naik tumpukan blok yang dapat dieksekusi sampai menemukan bagian EXCEPTIONS untuk menangani kesalahan. Perhatikan bahwa kami menutup kursor setelah pernyataan ini - yaitu, faktanya, kami tidak pernah menutup kursor. Kursor, seperti yang disebutkan di atas, mahal, dan Oracle hanya memungkinkan sejumlah terbatas untuk digunakan.

Di sini kita melihat contoh aneh bagaimana pengembang mencoba membela diri terhadap kesalahan yang tidak dapat terjadi, dengan cara yang akan menyebabkan kesalahan baru seiring waktu.

Cerita kelima. Login Terenkripsi Ganda


[Asli]

Membuat otentikasi untuk API web adalah tugas yang sulit , tetapi memiliki banyak solusi yang mapan. Hal yang paling sulit sebenarnya adalah memilih salah satu dari berbagai opsi, setelah itu cukup dengan hanya menambahkan komponen.

Ketika diimplementasikan dengan benar, sistem tidak tergantung pada jenis klien. Saya dapat mengakses layanan melalui browser, di klien yang tebal atau melalui CURL. Jika diterapkan secara tidak benar, Anda mendapatkan apa yang terjadi pada Amira .

Dia memecahkan masalah menarik statistik yang dia butuhkan dari backend, tetapi tidak dapat menemukan metode otentikasi. Oleh karena itu, ia mempelajari kode front-end untuk memahami bagaimana melakukan otentikasi:

 crypt = new JSEncrypt(); crypt.setPublicKey('<removed>'); challenge = "<removed>"; function doChallengeResponse() { document.loginForm.password.value.replace(/&/g, '%26'); document.loginForm.password.value.replace(/\\+/g, '%2B'); document.loginForm.password.value = crypt.encrypt(document.loginForm.password.value); document.loginForm.response.value = document.loginForm.password.value; document.loginForm.password.value = ''; document.loginForm.submit(); } 

Di satu sisi, saya dapat mengasumsikan bahwa kode ini sangat tua, mengingat document.loginForm digunakan untuk interaksi dengan elemen DOM. Di sisi lain, JSEncrypt pertama kali dirilis pada 2013, yang memberi kami bilah usia maksimum.

Kami meneruskan parameter akses ke backend dengan mengirimkan formulir, yang menurut pengembang kode, pembersihan diperlukan - semua & + di kata sandi diganti, tetapi ... ini tidak perlu, karena formulir harus memenuhi permintaan POST dan, di samping itu, kami mengenkripsi data .

Inilah yang saya pikirkan. Kode ini sebenarnya cukup lama. Pengembang menyalinnya dari pos di StackOverflow sekitar tahun 2005, yang tidak menggunakan enkripsi dan POST formulir melalui POST . Tahun demi tahun, sedikit perubahan ditambahkan padanya. tetapi mekanisme yang mendasarinya tidak pernah berubah.

Amira memeriksa riwayat dan menemukan bahwa enkripsi tidak digunakan di versi sebelumnya. challenge , MD5, , , .

: , , , , cURL -. , SSL/TLS .

Source: https://habr.com/ru/post/id446714/


All Articles