Mülakat Projesi ve Proje hakkındaki görüşler

Merhabalar. Konuyu daha önce açmıştım fakat reddedilmem üzerine gelen umutsuzluk ve hayal kırıklığıyla biraz sitemli bir konu açtığımdan silmem gerekmişti. Şimdi sakin bir kafayla tekrar konuyu açma gereği duydum.

Birkaç hafta önce bir iş başvurusu yapmıştım. Başvuru sonucu bir görev gönderildi ve 1 hafta süre verildi. 1 hafta sonunda projeyi sunmamı istediler. Yaptığım proje görevde istenen her şeyi karşılıyordu, sunumda sorulan pek çok soruyu da cevaplayabildim fakat sanırım OOP eksiklikleri, genel olarak yazılım üzerine bilgi eksikliği vs. gibi nedenlerle kabul edilmedim. Neden kabul edilmediğim hakkında net bir bilgim yok ancak project structure’ın zor anlaşılması, kodun nerede ne yaptığını tam olarak anlayamamaları gibi sorunlar da mevcuttu, variable isimlendirmeleri gibi problemler vardı.

Verilen task şu şekildeydi:

Görev Konusu :
Bu görevde, Interpol tarafından yayınlanan arananlar verisi çekilir ve kuyruğa yazılır. Kuyruktan okunan bu bilgiler
veritabanına kayıt edilir ve bir web server üzerinden paylaşılır. Uygulama aşağıda belirtilen mimaride yapılmalıdır.
Tüm işlemler kullanıcıya görsel bir arayüz ile sunulmalı ve docker ortamına uygun şekilde hazırlanmalıdır.
Gerekli Maddeler:
Mimari 3 container'dan oluşmaktadır.

◦ Container A: Belirli bir periyot süre ile sürekli olarak “Interpol” tarafından yayınlanan kırmızı liste verisi
çekilir ve Container C'de bulunan kuyruk sistemine aktarılır.

◦ Container B: Python ile hazırlanmış bir web sunucu olmalıdır. Burada Container C de bulunan kuyruk
dinlenmelidir. Kuyruktan elde edilen bilgiler istenilen veritabanında kaydedilmelidir. Bu bilgiler web
sunucu ile basit bir html web sayfasında zaman bilgisi ile birlikte gösterilmelidir. Kuyruktan elde edilen
her bilgi web sunucunun paylaştığı arayüz sayfası güncellenmelidir. Önceden kayıt edilmiş bilgilerin
güncellenmesi durumu ise alarm olarak arayüzde gösterilmelidir.

◦ Container C: Bir mesaj kuyruğu sistemi olan “RabbitMQ” bulunmaktadır.

* Yapıda değişkenlerin enviroment-config üzerinden müdahele edilebilir olması gerekmektedir (koda
müdahale etmeden değişiklik yapılabilmeli),
* Yapının Nesne Tabanlı Programlama temellerine göre oluşturulması,
* İstenilen yazılım Docker ortamına uygun şekilde hazırlanmalıdır ve dockerize edilerek build ve deploy
işlemleri yapılmalıdır. Docker-compose kullanılmalıdır,
* Yazılım testleri, yazılımın çalışma gereksinimleri, yorumları ve detaylı açıklama dosyası gibi dokumantasyon
ve kurulum yönergeleri hazırlanmalıdır(requirements.txt, doc-test, readme.md, .dockerfile, vs.) .

Bilgilendirme:
* Görev süresince python programlama dili kullanılmalıdır.
* Her türlü açık kaynaktan yararlanılabilir.
* Sizden beklenilen, kullandığınız/yazdığınız kodları anlamanız ve açıklamanızdır.
* Gerekli maddelerin tamamının yapılamaması durumunda, yapılan maddelere göre değerlendirilme
yapılacaktır.
* Proje github yada gitlab ortamında geliştirilmelidir.

Başvurduğum pozisyon Junior Python Developer’dı.

Yaptığım projeyi aşağıdaki github linkinden inceleyebilirsiniz. Geliştirme sırasında bu repoyu kullanmamıştım o yüzden çok az commit ve birden fazla contributor görebilirsiniz. Bu sizi yanıltmasın.

Link:

Junior, Mid, Senior fark etmeden hatamı bulup, bana söyleyip fark etmemi sağlayan herkese şimdiden çok teşekkür ederim. Kendime katacağım her bilgi benim için değerli.

3 Beğeni

Bu detaydan bahsedildigine gore incelemeyi de detayli yapmak gerekecek.

Code review cok sikintil bir surec; karar mekanizmasini bilmeyen insanlar kodun her parcasini incik cincik inceliyorlar. Hepsine tek tek “cunku bu yuzden, sunku bu yuzden” diye cevap vermemek karakter isteyen bir sey. “Tamam”, hatta “tesekkurler” diye cevaplamayi ogrenmek zor. O yuzden lutfen en azindan insanlarin size yardim etmeye calistigini hatirlayin. (Bunu geri donup yazdim; asagida cok negatif sey olmadigi icin bu sefer gerek yok aslinda, ama bunlar code review’lar icin genel olarak soylenmesi gereken seyler.)

changes

changes according to reviews

Ilk gozume carpan commit mesajlari oldu. Biliyorum basvuruya giden commit’lerle ayni degiller, fakat gordugume gore yorumlamak zorundayim. Commit mesajlari mumkun oldugunca kisa, fakat yapilan isi veya en azindan nereye dokundugunu aciklayici olmali.

Kotuden iyiye:

  • x
  • changes
  • changes to Dockerfile
  • changes to Container B’s Dockerfile
  • Update Container B to use python as a base image instead of Ubuntu

Tek basina birini ise alip/almama kararini degistirecek bir husus degil (hatta herkes onem vermez), ama benim gibi titiz commit yapmayi seven insanlara burun kivirtacak bir sey.

When you execute “docker-compose up”, UI will be available after 20 seconds.

Bu buyuk bir arti! Bir junior developer’dan, full stack oldugunu soylese bile, tek komutla calistirilabilir bir setup gormeyi beklemem. (Gerci bu hususta eski kalmis olabilirim, Docker Compose baya populer bir tool su aralar.) / yerine \ kullanan bazi path’leri duzeltmem gerekti, fakat tek hamlede calismasi etkileyici.

web_1 | File “/usr/src/app/routers.py”, line 21, in get_criminals
web_1 | if int(request.cookies[“item_length”]) < len(data):
web_1 | KeyError: ‘item_length’

Arayuzu gormekte sikinti cektim. Kimi kisiler icin anlasma bozucu (“dealbreaker”) olabilir. Ben, adaya bug report olarak sunup duzeltme surecini de gorme firsatina cevirirdim. En olmadi iki satir patch’lerdim, ki bu sefer oyle yaptim.

This page contains Interpol Red Wanted List

Front-end teknolojileri hakkinda yorum yapamayacagim, alanim degil. Fakat bariz bir sorun goremiyorum.

Kuyruktan elde edilen her bilgi web sunucunun paylaştığı arayüz sayfası güncellenmelidir. Önceden kayıt edilmiş bilgilerin güncellenmesi durumu ise alarm olarak arayüzde gösterilmelidir.

Otomatik guncelleme (JS, push/refresh) istiyorlarsa o eksik. Otomatik guncelleme istiyorlarsa bunu daha iyi belirtmeleri lazim.

Bilgilerin guncelleme durumunu nasil test edeceklerini merak ettim. Her halukarda, web sayfasinda bir alarm mekanizmasi gozukmuyor. Dogrusu WebSocket acip yan bir kanaldan alarm event’lerini vermek fakat bunun senkronizasyonu senior icin bile zor? (Yoksa sayfa periyodik olarak mevcut bilgileri alip degisikligi kendi fark edip alarm mi uretecek? Bu cok daha kolay ama tamamen JS, junior python adayindan neden istenir ki?)

Anlamadim. Buradan puan kirmis olabilirler.

Bir mesaj kuyruğu sistemi olan “RabbitMQ” bulunmaktadır.

Queue mesajlari gayet guzel.

Belirli bir periyot süre ile sürekli olarak “Interpol” tarafından yayınlanan kırmızı liste verisi
çekilir

Biraz sessiz calistigi icin bozuldu zannetmis olabilirler mi? Zannetmemeleri lazim. Sessizlik sorunsa da cozumu 1-2 satir log cagrisi.

Yazılım testleri, yazılımın çalışma gereksinimleri, yorumları ve detaylı açıklama dosyası gibi dokumantasyon ve kurulum yönergeleri hazırlanmalıdır(requirements.txt, doc-test, readme.md, .dockerfile, vs.) .

Bunlar eksik. Yalniz proje icin odeme yapilmiyorsa tam olarak yerine getirilmesini beklemem. Ama buradan da puan kirmis olabilirler.

Scrapy’nin yapisi oldukca karisik. Lakin gorulebildigi uzere kimi isleri cok baside indirgeyebiliyor. Adayin bunu kullanabilmesinin iyi bir sey olarak gorulmesi lazimdi.

Kodun parcalara ayrilmasi guzel, ve import’larin sonunda iki bos satir olmasi gibi titizlikler var. Su durumda variable isimlerine takilmak abes. Whitespace bozukluklari var ama bu kadari otomatik linter’dan gecen projelerde bile oluyo…


Acikcasi projede buyuk bir sorun goremiyorum. Junior degil, daha ust seviyelerde ise alinan insanlarin daha kotu is cikarttiklarini gormuslugum var. Eger sirket tarafindan belirlenmis sartlara uymuyorsa, sartlar bir junior aday icin fazla yuksek.

Mulakat surecinin geriye kalanini bilmiyorum tabi, ama bu projeden memnun kalmamislarsa girmemen iyi olmus bile olabilir…

4 Beğeni

Üst Not: Repoyu incelemede olduğu haline geri getirdim. Readme vs. de içerisinde bulunuyor.

Merhaba. Öncelikle incelemeniz için çok teşekkür ederim. Aslında hiçkimse kodumu incelemedi diyebilirim. Herhangi bir code review almadım, genelde “şurayı neden böyle yaptınız, burayı neden şöyle yaptınız?” tarzında bir sohbet gerçekleşti. Scrapy’nin spider scriptinde neden return yerine yield kullandığımı sormuşlardı. O an aklıma sadece yield kullandığımızda methodunun devamının da çalıştırıldığı, return gibi tamamen bitirmediği geldi. Sanırım heyecandandı, o sorunun devamında yield ile generator oluşturuyoruz bilgisi geldi ama artık soru üzerinden 10 dakika geçtiği için söylemek istemedim. Bunun dışında neden MongoDB kullandığımı, daha önce kullanıp kullanmadığımı sormuşlardı. Ben de daha önce kullanmadığımı, bunun ilk olduğunu söylemiştim. “Evet, maalesef daha önce kullanmadığınız belli oluyor. Neden bilmediğiniz bir teknolojiyi kullanma gereği duydunuz?” sorusunu yönelttiler. Birden fazla tablo olmayacağından, doğal olarak tablolar arası ilişki kurmam da gerekmeyeceğinden NoSQL kullandığımı söyledim. MongoDB connection’ını yapma şeklimi, bağlantıyı kullanma şeklimi beğenmediler büyük ihtimalle.

aslında bu detaydan bahsedilmedi. Sunumda kodu anlatırken ben söyledim. “Variable isimlendirmelerim kötü olabilir, üzgünüm.” minvalinde bir şey söylemiştim. Onlar da sadece “Evet” dediler bu duruma.

aslında onları da anlayabiliyorum. Başkasına mı yaptırdım kendim mi yaptım, yazdığım kod ne işe yarıyor biliyor muyum gibi soruların cevaplarını arıyorlar ama evet, maalesef biraz fazla detay istediler.

Burada söylemek istediğinizi tam olarak anlayamadım kusura bakmayın. Sunumu yaptığım insanlar aslında gayet iyi insanlardı. Burası böyle olmalıydı şurası şöyle olmalıydı gibi şeyler söylemediler. Sadece neden öyle yaptığımı sordular ben de buna göre cevap vermek durumunda kaldım.

Ufak tefek şeyler olduğundan çok önemsememiştim ama artık dikkat ederim. Teşekkürler.

host’u, port’u ve endpointi açıklamaya yazmayı unutmuşum kusura bakmayın. http://localhost:8001/api üzerinden ulaşılabiliyor siteye. Siz zaten bulmuşsunuz sanırım. Bunun dışında burada benim bir hatam var. cookie setlemeden cookielerinizdeki item_length’i bulmaya çalışmışım. bunu fixledim.

maalesef benim de alanım değil. tailwindcss ile kurcalaya kurcalaya bir şeyler yapmaya çalıştım.

aslında böyle bir mekanizma var ama sizde o kısım hata vermiş. Bunu şu şekilde yaptım:
Kullanıcı siteyi ilk ziyaretinde cookie’lerine item_length key’i ile bir kayıt ekleniyor. Bu key’in değeri MongoDB de criminals collection’ının length’i oluyor. Sistemi ilk çalıştırdığınızda scraper henüz çalışmadığından MongoDB’de 0 kayıt bulunuyor. 3 dakika sonra scraper veriyi almaya başlıyor (.env içerisinde 3 dakika olarak tanımlandı). Bu sırada backend içerisindeki background_task.py içerisinde bir thread oluşturuluyor ve bu thread consumer.py içerisindeki to_mongo() methodunu çalıştırıyor. to_mongo methodu rabbitten datayı consume edip mongoya yazıyor. Mongo’da kayıt oluştuğunda tekrar http://localhost:8001/api url’ine gittiğimizde yeni kayıt eklendiği bilgisi

This page contains Interpol Red Wanted List

yazısının altında beliriyor. Bunu da sizin cookielerinizdeki item_length ile Mongo’dan gelen total item length’i karşılaştırarak yapıyor. Evet bu mantıklı olmayabilir fakat aklıma bundan daha kolay bir çözüm gelmedi.

Özetle: Elimden gelenin en iyisini yapmaya çalıştım fakat sunum sanırım onlar için olumsuz geçti. Bu konuda bir şey söyleyemiyorum ne yazık ki. Birkaç farklı şey de sormuşlardı isterseniz burada onları da paylaşabilirim.

1 Beğeni

Kodu olusturan atomlar olarak dusunulebilir. Kucuk ve guzel ozetli commit’lerin onemi buyuk ve/veya uzun sureli projelerde karsimiza cikiyor. Mesela daha dun karmasik bir projede kullanici ayarlarinin nasil alindigini bulmam gerekti. Eskiden webcam ile ilgili bir ayar aldigimizi hatirladim. git lga altinda “webcam” arayinca yarim dakikada buldum.

Gozden kacan bir bug’i history’de bulmak icin git-bisect yaparken, sonra onu olusturan commit’i git-revert ederken, veya calisan branch’e yapilan hotfix’leri feature branch’e git-cherry-pick ile alirken, hep commit’leri kullaniyoruz. Mesajlari da yanlarinda geliyor.

Genel olarak code review surecinin sikintilarindan bahsediyordum. Dunki uzun mesaimin sonunda, sonradan bir edit olarak yazdigim icin aceleye geldi, kusura bakmayin.

Gayet dogru bir cevap. Aklima su (hayali) diyalogu getiriyor:

— Gokyuzu neden mavi?
— Cunku hava mavi.
— Hayir, Rayleigh scattering yuzunden. Dusuk dalga boylu mavi isik vs vs…
— O havanin mavi olmasinin sebebi.

Yani insan konuya hakimse, terimleri araya sikistirabilme kabiliyeti ikinci planda kalmali. Kaldi ki, “generator” cevabini bilen ve bekleyen insanlarin cogunlugunun generator’larin subroutine olduklarini ve kodlarinin cooperative multitasking ornegi oldugunu bildiklerini zannetmiyorum mesela.

Ayni sey closure / lambda / anonymous function / inline function icin de gecerli mesela. Disaridan deger capture edilebildigini biliyor ve buna gore kod yazabiliyorsan, terimlerin arasindaki nuanslari bilmen o kadar onemli degil. (Ki ben mesela yazi yazarken her seferinde Wikipedia’ya filan bakip tanimlarini tazeliyorum kafamda. Veya son zamanlarda suraya.)

Arguman/parametre de keza. Fonksiyona parametre olarak 5 yolladigini mi soyluyorsun? Sorun degil; fonksiyonu parametrik yapmis olman daha onemli.

Bi ekstrem ornegi de call/pass by reference / by value. “Ileri seviye” bir bilgi oldugu icin fetişize edildigini goruyorum. Dilin semantik kurallarini resmi dokumentasyondan ezbere okumaktansa yazdigi kodun bu baglamda duzgun calistigina dikkat eden insanlari tercih ederim.


Dedigim gibi, mulakatin tamamini bilmeden burada soylediklerim atip tutmak olur—gordugum kadarini, kendime gore yorumlayabiliyorum sadece. (Ki ben kimim? O da ayri bir problem) Ama gordugum kadarindan memnun kaldim, ve tek basina yaptigina inandigim birini junior, hatta belki daha yuksek bir pozisyona tavsiye etmekten cekinmezdim.

OOP skill’lerini veya kod stilini begenmedilerse, belki daha guzel gostermeni saglayacak bir proje verebilirlerdi. Bunun cogunlugu container, DB/queue setup, vs.


Bu arada geri donup neyi begenmediklerini, neyi yetersiz bulduklarini sordun mu? Mutlaka sor.

(Belki de para bile almadan) bir haftani harcadiysan, onlar da bir zahmet on dakka–yarim saat ayirip gelecekte daha basarili olmana yardimci olabilirler.

Aynisini surada yazdim. Cogu “senior” diye gezinen insanin bile sahip olmadigi bir bilgelik parcasi bu.

Öncelikle değerli yorumlarınız için tekrar teşekkür ederim.

Evet sabah 8.30’da kalkar kalkmaz mailime baktığımda yetersiz bulunduğumdan olumsuz sonuçlandığı mailini gördüm. Daha sonra 11.30 gibi olumsuz sonuçlanmasına neden olan hataları, eksiklikleri eğer sorun değilse kısaca açıklayabilir misiniz minvalinde bir mail attım fakat yine aynı mailin farklı bir şeklini yolladılar. Olumsuz değerlendirdik, mühendis gibi düşünmeye çalışın gibi bir maildi (mühendis gibi düşünme kısmını aklıma kazıdım. bu cümle kesinlikle geçiyordu).

evet tek bir satırında başkasının eli yok tamamını kendim yaptım.
Sağlık olsun diyebiliyorum bundan sonra. Bazı yabancı forumlarda da projem hakkındaki görüşlerini sorduğumda pek çok insan “Tüm bunları gerçekten Junior Python Developer pozisyonu için mi yaptın?” gibi tepkiler aldım. Bazıları OOP konusundaki eksikliklerimi fark etmiş olacak ki OOP üzerine bazı tavsiyeler verdiler. Kısaca projeyi verdiğim işletme dışında herkes gayet yeterli buldu diyebilirim.

Başka bir bakış açısı da şu, belki de sunumumu beğenmemişlerdir. Toplantıya ilk katıldığımda açıkça “Sunum yapmakta pek iyi değilim, tecrübem de yok. Bazı notlar aldım fakat bazı noktalarda yönlendirmelerinize ihtiyacım olacak” gibi bir şey de söylemiştim. Yine de sağlık olsun diyebiliyorum. Umarım benim için -sizin de dediğiniz gibi- böyle olması daha iyidir, yani işi alamamak.

Ayrıca son bir dipnot: Angarya işlerden nefret ettiğimi ve zorunda olmadıkça yapmak istemediğimi söyledim. Angarya işleri genelde yeni başlayanlara verdiklerini ve bu özelliğimi törpülemem gerektiğini söylediler. Bence bu konuda haklılar çünkü insanın karşısına her zaman dikkatini çeken harika görevler gelmiyor.

Zaman icerisinde ogrenilen (ogrenilebilen?) becerilerden bir tanesi de angarya islerden haz veya en azindan fayda cikartabilmek.

Ben bu tur isleri codebase’in begenmedigim bir kismini refactor etmek, veya minik bir ozgur kutuphane/dış kutuphaneye patch cikartmak icin kullanabiliyorum.

(Bu arada takildiklari nokta bu olabilir. Bence bunu isi aldiktan sonra soylemeliydin. Veya “her programci gibi, tembel bir insanim ve angarya isleri sevmiyorum ve yazdigim koda yaptirmayi tercih ediyorum” gibi bir ara yol da olabilir.)

aslında yapabileceğimi sadece haz almadığımı, yaparken sıkıldığımı söyledim.

Elime yüzlerce satırlık Excel dosyası verilip “hadi bunları bizim database’imizdeki veriye mapple” gibi şeyleri gerçekten istemiyorum (şu anki işimde bunu bazen yapıyorum. otomatize etmek için rapidfuzz string matching kütüphanesini kullanarak db’deki verilerle excel’deki verileri eşliyorum ancak %100 doğru olmuyor, kontrol gerektiriyor). Yine de dediğiniz gibi bu tip olumsuz karşılanabilecek şeyleri işi aldıktan sonra söylesem daha iyi olabilirdi.

Tekrardan eleştiri ve övgüleriniz için teşekkür ederim hepsi benim için çok değerliler. Umarım karşıma daha iyi fırsatlar çıkar. Başta umudumu kaybetmiştim ama sizin ve diğer forumlardaki insanların yazdıklarını gördükten sonra cesaretimi yeniden kazandım.