Penawaran di London dalam satu hari: bagaimana cara mendapatkannya dan apa yang harus dilakukan setelah pindah

Halo, Habr!

Kami memiliki rencana besar untuk tahun 2020. Kami bermaksud untuk secara aktif mengembangkan Badoo dan Bumble, jadi kami serius mengembangkan tim teknis. Dan hari ini kami mengumumkan perekrutan besar-besaran pengembang PHP di kantor kami di London. 

Pada 2017, kami mencoba format pencarian baru - acara perekrutan: kami membawa pengembang keren ke Moskow, melakukan wawancara dalam satu hari dan segera melakukan penawaran ke kandidat yang cocok. Semua biaya untuk perjalanan ke ibukota, tentu saja, dikeluarkan.

Format telah bekerja dengan baik, dan kami memiliki banyak posisi terbuka lagi, jadi kami mengumumkan Peristiwa Perekrutan PHP baru. 

Aturannya sama: menunjukkan hasil tes tinggi sebelum 1 Maret, berhasil lulus wawancara pada 21 atau 22 Maret di Moskow - dan pada hari yang sama menerima tawaran ke kantor Badoo London. 

UPD: tes selesai, terima kasih untuk semua peserta! Kami telah memberi tahu para finalis dan memperingatkan bahwa tanggal wawancara ditunda tanpa batas waktu untuk kenyamanan dan keamanan para kandidat.



Di bawah potongan, saya akan memberi tahu Anda:

  • lebih banyak tentang tes;
  • proyek apa yang kami lakukan: pengoptimalan foto, streaming video, pembelajaran mesin untuk surat, transisi ke versi baru PHP dan banyak lagi.

Jika Anda seorang PHP shnik dan ingin pindah ke London, selamat datang di kat!


Cara lulus ujian


Tes terdiri dari lima tugas. Tepat 90 menit dialokasikan untuk keputusan: itu tidak akan berfungsi untuk menunda atau menghentikan proses. Sebelum Anda mulai, pastikan Anda memiliki cukup waktu. 

Dalam tiga tugas, Anda perlu menulis kueri kode / SQL, dan dalam dua tugas lainnya kami berharap dapat melihat jawaban terperinci untuk pertanyaan. Tes dipublikasikan di HackerRank. Kami merekomendasikan untuk berlatih pada tugas-tugas pengujian platform agar merasa nyaman dengan antarmuka. 

Keputusan dibuat hingga 2020-03-01 23:59:59 UTC. Berdasarkan hasil tes, kami akan memilih sekitar 60 kandidat yang akan kami undang ke Moskow untuk wawancara. 

Perusahaan menanggung semua biaya untuk perjalanan ke Moskow, serta biaya yang terkait dengan pindah ke London. Kami membantu mendapatkan visa kerja kepada anggota keluarga dari kolega baru kami, membayar penerbangan, menyewa rumah selama pencarian, membayar bonus tunai untuk pemindahan dan membantu meningkatkan bahasa Inggris. Anda bisa berkenalan dengan tim yang sudah di tahap wawancara: pengembang sendiri melakukan wawancara di acara perekrutan.

Apa yang dilakukan tim pengembangan server 


Kami bertanggung jawab atas backend dari layanan kencan Badoo dan Bumble. Selain menggesek ke kiri dan ke kanan untuk menemukan mitra, aplikasi memiliki streaming video, mengobrol dengan pesan audio, mencari orang-orang terdekat, integrasi dengan layanan pembayaran dan banyak lagi. Antarmuka yang relatif sederhana menyembunyikan banyak logika di PHP dan Go (dan semakin banyak). 

Tim kami memiliki lebih dari 40 orang. Pekerjaan itu dapat dibagi menjadi dua bagian besar:

  • fungsi baru dalam aplikasi,
  • proyek teknis - peningkatan alat, optimisasi, bekerja dengan utang teknis.

Saya akan berbicara tentang proyek paling menarik yang telah kami laksanakan selama dua tahun terakhir.

Cool chips dalam produk


Pasar untuk aplikasi kencan adalah dinamis dan kompetitif, oleh karena itu tujuan utama kami adalah pengembangan produk: itu harus tetap menarik dan aman bagi pengguna. 

Belajar menyembunyikan foto terlalu "pribadi"


Beberapa pengguna mengirim foto obrolan yang bersifat erotis, bahkan jika lawan bicara tidak meminta hadiah semacam itu. 

Tugas yang harus kami pecahkan adalah mengajarkan aplikasi untuk membedakan foto "pribadi" (18+) dari foto biasa dan menunjukkannya mengobrol di obrolan, memungkinkan penerima memutuskan sendiri apakah ia ingin melihatnya secara keseluruhan. 

Bersama dengan tim R&D, kami menciptakan layanan on Go dengan jaringan saraf yang dapat mengenali foto "pribadi". Jika kemungkinan bahwa foto itu erotis lebih tinggi dari ambang yang ditetapkan, bendera khusus dimasukkan ke dalam pesan dan klien menangani situasi ini sesuai: menunjukkan tulisan rintisan yang kabur menanyakan apakah penerima ingin melihat apa yang ada di dalamnya. 

Kami menjalankan semua tugas melalui tes A / B, dan juga dengan hati-hati membahas poin-poin utama dari fungsionalitas baru dengan statistik. Jadi, kami menemukan bahwa sekitar 200.000 dikirim per hari foto "pribadi". Dan juga - bahwa sering foto-foto ini masih dilihat dan tidak mengeluh tentang pengirim.  

Menambahkan pesan obrolan audio dan video


Selama dua tahun terakhir, kami telah menyusun fitur untuk messenger canggih dan memberi pengguna kesempatan untuk bertukar pesan multimedia. Implementasi opsi ini di sisi server cukup sederhana karena arsitektur fleksibel mobile API dan CDN-nya sendiri.

Saat merancang pesan multimedia dalam obrolan, kami mentransfer unggahan file dari API client-server utama ke layanan HTTP terpisah yang terletak di dalam CDN. Kami menggunakan repositori tunggal, jadi dari sudut pandang dukungan kode, solusi ini tidak menimbulkan masalah. Tetapi memungkinkan untuk menggunakan alat yang dioptimalkan untuk sifat beban:

  • API seluler (protokol biner) dipertajam dengan pertukaran perintah pendek dan pada puncaknya melewati dirinya sendiri lebih dari 100.000 permintaan per detik;
  • CDN disetel untuk bekerja dengan multimedia dan mampu memberikan 200.000 foto per detik (kami berbicara tentang pengoptimalan CDN secara rinci di konferensi Uptime Day).

Dari sudut pandang CDN, jenis file yang diunduh tidak terlalu penting, dan kami sudah memiliki konversi video. Kami hanya dapat memproses dengan benar tipe baru (audio dan video) dalam protokol API seluler.

Belajar bagaimana membangun model-ML tanpa R&D


Pada tahun 2018, kami menciptakan kerangka kerja kami sendiri untuk mengotomatisasi pelatihan model pada data kami. Sekarang setiap pengembang backend dapat secara mandiri membangun model yang disesuaikan untuk aplikasinya, tanpa menarik kolega dari R&D. 

Kerangka kerja ini mampu mengumpulkan ratusan metrik, baik universal (jenis kelamin, usia, aktivitas dalam aplikasi), dan spesifik, signifikan untuk setiap model spesifik. Algoritma untuk membangun model-ML dikonfigurasikan secara fleksibel, dan grafik hasil tersedia untuk analisis β€œout of the box”. Pada output, framework menyediakan model kerja yang merespon cukup cepat (dalam 10-100 ms) sehingga dapat dipanggil dari PHP secara langsung dalam permintaan pengguna tanpa mengorbankan UX.

Tahun lalu, kami mengintegrasikan kerangka kerja ke dalam berbagai bagian aplikasi kami: sistem anti-spam, memberi peringkat aplikasi dan beberapa lainnya. Mail ML adalah salah satu aplikasi yang paling sukses: model memprediksi probabilitas klik pada tautan dalam email untuk pengguna tertentu. Model belajar dari data pengguna lain, mirip dengan penerima email dengan atribut "penting", dan "kepentingan" dihitung secara otomatis oleh kerangka kerja.

Setelah mengevaluasi hasil, kami berhenti mengirim email dengan kemungkinan paling kecil mengklik tautan. Karena kita ini: 

  • peningkatan loyalitas pengguna, yang menghasilkan peningkatan metrik aktivitas dalam layanan: orang tidak suka surat "putus asa";
  • peningkatan tingkat kotak masuk di mailer utama: layanan email seperti pengirim dengan RKT tinggi.

Meluncurkan streaming video


Kami selalu mencari peluang baru untuk pengembangan. Ketika streaming video mulai mendapatkan momentum, kami memutuskan untuk mengintegrasikannya ke dalam aplikasi kami. Memprediksi keberhasilan proyek itu tidak mudah, jadi untuk mengurangi biaya, kami tidak terjun langsung ke pengembangan solusi kami, tetapi menemukan perusahaan yang menyediakan platform dan SDK dengan fungsi yang kami butuhkan.

Kami diharuskan membuat logika fitur, interaksi klien-server, menerapkan opsi untuk mengirim dan membayar hadiah, menyediakan konten yang moderat (baik aliran video dan komentar) dan mencakup semuanya dengan metrik. Kami telah membentuk tim lintas fungsi dari berbagai departemen dan divisi: pengembangan klien, pengembangan server, penagihan, platform, back office, analitik BI, desain dan manajemen produk. Semua duduk dalam satu ruang kantor - dan pekerjaan mulai mendidih.

Kami menentukan fungsionalitas versi pertama (MVP) - dan sebulan kemudian kami meluncurkan fitur di satu negara setelah satu negara. Selama beberapa minggu kami meluncurkannya di berbagai negara, dan hari ini streaming video tersedia di mana-mana. 

Menyiarkan pesan pengguna di Arbat


Itu promosi yang sangat tidak biasa: semua Oktober, pengguna Badoo mengirim pesan ke papan video besar yang terletak di Novy Arbat di Moskow. Dalam sebulan, 23.000 pesan dikirimkan kepada kami, 12.000 di antaranya berhasil dimoderasi dan menyentuh layar.

Papan iklan adalah TV pintar dengan browser dan klien JavaScript kami di dalamnya. Iklan lima menit ditampilkan di layar, di mana masing-masing tiga menit diberikan kepada kami. 



Tentu saja, semua pengguna ingin melihat pesan yang dikirim di layar dengan mata kepala sendiri. Untuk memungkinkan ini, kami harus menjawab pertanyaan ketika setiap pesan muncul di sana.

Kami harus memberi tahu pengguna tentang waktu tampil setelah moderasi. Secara teknis, pada titik ini, pesan masuk ke dalam jadwal internal kami dengan waktu dan durasi mulai yang jelas, yang dihitung secara dinamis: dari 30 detik hingga lima menit (tergantung pada jumlah pengirim). 

Kesulitannya adalah bahwa penyedia, untuk bagiannya, tidak menyediakan kemampuan untuk mengontrol dan melacak waktu komersial, sehingga perlu untuk secara cerdik menyinkronkan jadwal kami dengan jadwal penyedia, terus memantau dan menyesuaikan jika perlu. Ini membantu kami yang kami perhatikan (logging adalah segalanya bagi kami!) Bahwa beberapa puluh detik sebelum video berikutnya ditampilkan, smart TV memuat ulang halaman. Mustahil untuk fokus pada waktu ini, tetapi di situ orang bisa melihat perubahan dalam jadwal, yang kadang-kadang mencapai 15-30 detik. Kami mengatur pemantauan shift di pihak kami dan pada saat-saat operasi kami mulai meminta waktu pertunjukan terdekat dari penyedia. 

Dalam proses pengaturan sistem ini, insinyur kami, yang bekerja dari sebuah kafe di seberang papan iklan, makan croissant dalam jumlah yang mengesankan dan minum banyak cangkir kopi, tetapi berkat dia, siaran pesan pengguna berjalan dengan lancar dan tidak ada insiden serius. 

Proyek teknis


Meskipun volume besar pekerjaan bahan makanan, kami mencurahkan banyak waktu untuk proyek-proyek teknis. Kebanyakan dari mereka berhubungan dengan kinerja aplikasi kami, serta pengembangan dan peningkatan alat internal.

Proyek Sumber Terbuka Liveprof


Kami telah lama memiliki kesempatan untuk mengaktifkan XHProf pada produksi untuk permintaan tertentu, tetapi ini tidak selalu cukup. Permintaan berbeda, tetapi untuk pekerjaan sistematis tentang kinerja, saya ingin melihat gambaran besar untuk semua permintaan. Oleh karena itu, lahirlah gagasan semacam itu: luncurkan XHProf secara otomatis pada sebagian kecil kueri, dan agregat hasilnya. Ini adalah bagaimana proyek Liveprof muncul , yang kami akses terbuka.

Dalam proses pemrosesan permintaan, ada logika bahwa, berdasarkan probabilitas dan metode API, memutuskan apakah akan memulai XHProf. Hasil profil ditulis ke disk, dan kemudian dikirim ke server terpisah, di mana mereka ditempatkan dalam bentuk mentah di MySQL. 

Sekali sehari, sebuah skrip dijalankan yang mengagregasi hasil untuk setiap merek, platform, dan metode API. Dengan demikian, kita dapat melihat hasil pembuatan profil untuk permintaan khusus dari Badoo iOS (baik dalam bentuk pohon dan dalam bentuk grafik nyala), kita dapat melihat berapa persentase cluster yang diperlukan untuk memanggil fungsi individual (misalnya, berapa biaya untuk mengumpulkan URL untuk foto), dan baru-baru ini menambahkan output informasi ini langsung ke PhpStorm.

Bermigrasi ke PHP 7.4


Versi baru PHP senang dengan peningkatan kinerja. Selama dua transisi terakhir (dari 7,0 ke 7,2 dan dari 7,2 ke 7,4), departemen kami bertanggung jawab.

Transisi dimulai jauh sebelum rilis resmi. Pertama, kami menjalankan tes secara manual dengan versi baru dan ... kami menghadapi banyak masalah. Beberapa di antaranya mudah diselesaikan, sementara yang lain membutuhkan waktu. 

Ketika sebagian besar masalah telah diselesaikan, kami beralih ke versi baru di lingkungan pengembang, untuk beberapa waktu kami memantau log kesalahan dan mengumpulkan umpan balik dari pengembang dan insinyur QA. Pada saat rilis resmi versi stabil, kami siap untuk menguji produksi: pertama-tama kami menjalankannya di satu mesin dan secara bertahap meletakkannya di yang lain.

Tetapi setelah versi baru didistribusikan di semua server, transisi tidak berakhir: kami terus memeriksa sintaks dengan kedua versi PHP (baru dan sebelumnya). Dengan demikian, kami yakin bahwa pengembang tidak mulai menggunakan sintaks baru dan bahwa kami dapat beralih ke versi lama kapan saja jika muncul masalah yang tidak terduga di yang baru. Misalnya, sebelum liburan Tahun Baru, kami menemukan masalah kecil dengan kebocoran memori di PHP 7.4, memutuskan untuk tidak mengambil risiko dan kembali ke versi sebelumnya sebelum liburan. Setelah liburan, setelah menyelesaikan masalah, kami kembali meluncurkan versi 7.4 dan masih menggunakannya. 

Pergilah agregasi permintaan


Dengan pembaruan PHP, perjuangan kami untuk kinerja tidak berakhir di sana. Kami memiliki kerangka kerja yang kuat yang melakukan banyak pekerjaan di awal: dari inisialisasi ke berbagai pemeriksaan yang diperlukan untuk setiap permintaan. 

Kami memutuskan untuk melakukan percobaan sederhana. Kami memilih bagian dari perintah yang respons servernya tidak kritis (misalnya, mengirim statistik dari klien atau memilih opsi "Tidak" di game swipe), dan menulis layanan on Go yang menerima permintaan tersebut, menyimpannya, dan kemudian mengirimkannya ke server dalam satu paket ( untuk setiap pengguna). Dengan demikian, kita dapat dengan mudah menghemat menginisialisasi aplikasi tanpa menulis ulang kode utama.

Eksperimen ini ternyata berhasil: menurut perkiraan kami, kami dapat menghemat beberapa persen dari CPU (yang dalam kasus kami lebih dari sepuluh server) tanpa menulis ulang kode utama, tetapi dengan biaya mempersulit operasi dan logika kerja. Untuk melengkapi gambar, kami memutuskan untuk menunggu hasil percobaan dengan PHP 7.4 preload dan RoadRunner untuk memilih solusi yang optimal sesuai dengan rasio kemenangan dan kompleksitas implementasi. 

Pengoptimalan foto


Aktivitas pengguna secara langsung tergantung pada beberapa proyek teknis. Misalnya, semakin cepat kami menampilkan foto, semakin banyak orang menggesek, semakin banyak kecocokan terjadi, semakin banyak pasangan baru terbentuk dan sebagainya. 

Pada Oktober 2018, salah satu merek kami, Bumble, memutuskan untuk memasuki pasar India. Karena kami tidak tahu apa-apa tentang kecepatan Internet lokal, kami memutuskan untuk melakukan serangkaian percobaan dengan kualitas dan ukuran foto.

Kami meluncurkan semua percobaan teknis di bawah uji A / B. Ini memungkinkan Anda untuk melihat tidak hanya perbedaan dalam perilaku dan aktivitas kelompok yang berbeda, tetapi juga statistik tentang operasi aplikasi pada klien, yang dirinci berdasarkan opsi. Kami tertarik pada waktu untuk mengunduh gambar dan waktu untuk decoding dan tampilan. 

Infrastruktur, selain server penyimpanan, kami mengalokasikan sekelompok cache foto - ini adalah server yang menyimpan gambar yang paling umum digunakan. Karena ada sejumlah besar smartphone dengan layar berbeda di dunia, kami menyimpan foto dalam beberapa ukuran dasar dan mengonversinya dengan cepat menjadi ukuran dan format yang diminta oleh klien. 

Tugas yang ingin kami selesaikan adalah memilih format optimal (JPEG, WebP, PJPEG), ukuran dan kualitas gambar. Secara teori, format WebP harus menjadi yang terbaik, tetapi ini adalah yang paling mahal dalam hal konversi dengan cepat: alih-alih menghemat lalu lintas, Anda perlu membeli lebih banyak server cache foto. Bersamaan dengan ini, kami memutuskan untuk menguji bagaimana CDN di wilayah ini akan membantu meningkatkan UX.

Beberapa teknisi kami dikirim ke sana untuk meluncurkan proyek di India. Jadi kami tidak hanya memiliki nomor kering, tetapi juga orang-orang yang dapat menguji aplikasi pada operator yang berbeda di tempat, membandingkan pekerjaannya dengan pekerjaan aplikasi lain, dan sebagainya.

Hasil percobaan memungkinkan kami untuk memilih opsi terbaik untuk kualitas dan ukuran foto. Sebagai contoh, kami melihat bahwa logika preloading foto pada klien memainkan peran besar dalam aktivitas pengguna. Dan terlepas dari kenyataan bahwa foto di WebP lebih cepat diunduh, efek positifnya hanya terlihat di peramban seluler. Kisah yang sama dengan CDN: kami menguji tiga layanan CDN eksternal dan, meskipun percepatan pengiriman konten, tidak melihat perubahan positif dalam aktivitas. Akibatnya, kami mengaktifkan WebP untuk browser seluler dan menghemat daya, meninggalkan semua klien lain dalam format JPEG.

Streaming video sendiri


Seperti yang saya sebutkan di atas, versi pertama streaming video diluncurkan menggunakan layanan eksternal. Percobaan dianggap berhasil - dan kami mulai menyiapkan perangkat lunak dan infrastruktur untuk peluncuran di pusat data kami. 

Dengan bantuan transcoder siap pakai (untuk memeras aliran video dari pengguna) dan Edge-server (untuk mendistribusikan aliran ke pengguna) kami harus membangun sistem yang mirip dengan solusi kotak eksternal. Dan, tentu saja, banyak yang harus diselesaikan dengan "file" saat bepergian.

Sebagai contoh, awalnya setiap server Edge terhubung ke setiap server transcoder, yang rumit penskalaan dan peningkatan lalu lintas internal. Kami menulis penyeimbangan klien sedemikian rupa sehingga klien dari satu aliran pergi ke server Edge paling sedikit, dengan mempertimbangkan popularitas setiap aliran tertentu. 

Contoh lain, ketika kami harus cerdas, adalah logika mengubah kualitas aliran di WebRTC: karena kami menggunakan dua opsi kualitas, algoritma standar dihancurkan dan hanya berfungsi untuk mengurangi bitrate. Saya harus masuk lebih dalam dan mengedit algoritma yang digunakan di dalam perpustakaan WebRTC.

Selain itu, pensinyalan WebRTC, secara default, memberikan terlalu banyak informasi tentang host di jaringan ke klien. Solusinya adalah server proxy on Go, yang memberi klien hanya apa yang perlu dia ketahui, dan selain itu mengumpulkan banyak informasi berguna tentang klien yang terhubung. 

Dari awal penelitian hingga implementasi penuh, proyek ini membutuhkan waktu lebih dari enam bulan, tetapi sebagai hasilnya, kami dapat mengurangi biaya secara signifikan dengan meninggalkan layanan eksternal. 

Optimalisasi kinerja


Ini bukan proyek satu kali untuk tim kami - ini adalah bidang penting yang kami juga memperhatikan. Cluster utama kami yang melayani permintaan dari aplikasi terdiri dari ratusan server, dan oleh karena itu menguntungkan bagi kami untuk menginvestasikan waktu dalam pengoptimalan aplikasi: setiap persentase yang dimenangkan akan membuat kami memerlukan beberapa server fisik. 

Kami terus memantau total beban pada cluster kami dan beban untuk setiap panggilan API tertentu. Jika ambang tertentu terlampaui, kami mulai mencari dan mengoptimalkan kemacetan. Semakin besar kelebihannya, semakin banyak orang terlibat. Pendekatan ini sepenuhnya dibenarkan: dalam dua tahun terakhir, tingkat pertumbuhan cluster telah setengah tingkat pertumbuhan audiens layanan kami. 

Kami secara aktif berbagi pengetahuan yang diperoleh selama pekerjaan optimisasi di konferensi dan rapat. Rincian lebih lanjut tentang proyek dan studi kami dapat ditemukan di artikel dan laporan oleh Pasha Murzakov: 


Kontrol atas kode lama dan tidak terpakai


Kami memiliki pengembangan yang cukup intensif, dan laju peluncuran tugas dan eksperimen produk juga meningkat seiring pertumbuhan perusahaan. Dalam kondisi seperti itu, basis kode menjadi lebih kompleks dan kurang terkontrol. Situasi ini diperburuk oleh beberapa platform dan pengguna dengan versi aplikasi dan sistem operasi yang lebih lama. 

Kami mencoba untuk menjaga basis kode kami "bersih" untuk mempertahankan kecepatan kerja yang tinggi:

  • secara otomatis membuat tugas untuk menghapus kode setelah selesainya percobaan produk;
  • pelacakan otomatis versi lama aplikasi dan sistem operasi dan cabang kode yang digunakan di dalamnya;
  • Alat yang diperkenalkan untuk secara otomatis mencari kode yang tidak digunakan.

Anda dapat mempelajari lebih lanjut tentang hasil kami di Pertemuan PHP Badoo , yang akan diadakan pada hari Sabtu, 15 Februari. 

Tentu saja, ini bukan semua proyek yang ingin saya bicarakan. Selama dua tahun terakhir, kami telah berjuang dengan spammer dan kakap, menggergaji plugin kami untuk PhpStorm, menguji berbagai repositori KV (dan memilih Aerospike), banyak bereksperimen, berbagi pengetahuan dalam artikel, di konferensi dan tidak hanya.

Tetapi jika Anda memutuskan bahwa kami hanya bekerja, maka ini tidak benar. Setiap tim memiliki anggaran pembangunan tim sendiri. Rekan-rekan kami mengunjungi Amsterdam, Edinburgh, Praha dan kota-kota lain. Dan tahun lalu kami menyelenggarakan pertemuan umum departemen di Kroasia:


Dan kami juga tahu cara photoshop.

Saat pindah ke London dan kantor di Soho kami sudah memberi tahu, oleh karena itu kami tidak akan memikirkan detail dalam artikel ini - hanya menunjukkan beberapa foto.



Foto besar










Acara perekrutan adalah cara termudah dan tercepat untuk bergabung dengan tim kami. Kami menerima jawaban untuk tes hingga 1 Maret inklusif. Kemudian kita akan membutuhkan waktu seminggu untuk menganalisis hasil dan memanggil mereka yang mengatasi tugas. 
 
Jika Anda ingin bekerja untuk kami di London, tetapi tidak ingin mengikuti tes, ada opsi lain: cukup tanggapi lowongan di situs web kami , peluang ini selalu tersedia.

Jika Anda memiliki pertanyaan, jangan ragu untuk bertanya di komentar atau mengirim saya pesan pribadi. 

Semoga berhasil

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


All Articles