Vay be, teknik mülakatlar! Sanki bir zaman makinesine binip geleceğe ışınlanmak gibi değil mi? O kadar hazırlık yaparsın, kodlarına hakim olursun, ama o ilk soru geldiğinde sanki beynindeki tüm hard diskin formatlanmış gibi hissedebilirsin. Bana da oldu, hem de defalarca. Hani o çok güvendiğin algoritmayı bir anda unutursun ya, işte tam o an… Neyse efendim, bu yazıda size hem kendi yaşadıklarımdan hem de genel geçer bilgilerden yola çıkarak bu mülakat denen canavara nasıl daha hazırlıklı girebileceğimizi anlatacağım. Bu arada, tam da bu konuyla ilgili geçen gün bir arkadaşım anlattı, iş başvurusu yapmış ve mülakatta onu bir algoritma sorusuyla terletmişler. Sonrası malum, hüsran. Ama olsun, ders çıkarırız.
Teknik mülakatlar dediğimiz şey aslında sadece kod yazma yeteneğini ölçmekten çok daha fazlası. Bir nevi problem çözme becerini, düşünce yapını, hatta takım içinde nasıl uyum sağlayabileceğini anlamaya çalışıyorlar. Yani sadece ‘Aha, bu sorunun cevabı C#’ diye düşünmek yetmiyor. Diyorlar ki, ‘Bu problemi nasıl ele alırsın? Nereden başlarsın? Hangi veri yapılarını kullanırsın? Zaman ve alan karmaşıklığı ne olur?’ İşte bütün bu soruların cevabı aslında senin o anki panik seviyenle doğru orantılı olarak değişebiliyor galiba. 🙂 Ama korkmayın, bu soruların hepsinin bir mantığı var.
Öncelikle en temelden başlayalım. Veri yapıları ve algoritmalar. Bu ikisi olmadan teknik mülakat olmaz, sanki çorbasız tarhana gibi bir şey. Diziler, bağlı listeler, yığınlar, kuyruklar, ağaçlar, graflar… Bunların ne işe yaradığını, ne zaman hangisini kullanman gerektiğini bilmen lazım. Hani bazen bir soruyu çözmek için bir sürü yol vardır ya, işte o yolların en verimli olanını seçebilmek için bu veri yapılarını iyi tanıyacaksın. Mesela bir arama işlemi yapacaksın diyelim. Eğer verilerin sıralıysa ikili arama (binary search) inanılmaz hızlıdır. Ama değilse? O zaman başka bir yöntem düşünmek lazım. Bu arada, algoritma denince akla hemen sıralama algoritmaları gelir. QuickSort, MergeSort, BubbleSort… BubbleSort’u biliyorsunuz, en basit ama genellikle en yavaş olanı. Hani kendi programım sınıfta kaldı dediğim o Proxy programında da böyle basit bir sıralama mantığı kullanmıştım ama filtreyi aşamadı tabii :)) Neyse, konumuza dönelim.
Algoritmalara gelince, sadece bilmek yetmez. Bir de bunların karmaşıklığını anlayacaksın. Büyük O gösterimi, yani Big O notation dedikleri olay var ya, işte o senin için bir pusula gibi olmalı. Bir algoritmanın ne kadar hızlı çalıştığını, veri miktarı arttıkça performansının nasıl değiştiğini anlamana yardımcı olur. Hani bazen bir kod yazarsın, kendi bilgisayarında süper çalışır ama milyonlarca kullanıcıya ulaştığında çöküverir ya, işte orada Big O devreye giriyor. Zaman karmaşıklığı (Time Complexity) ve alan karmaşıklığı (Space Complexity) bu işin temel taşları.
Şimdi gelelim kodlama kısmına. Genelde mülakatlarda sana bir problem verilir ve bunu belirli bir dilde çözmen istenir. Hangi dil olursa olsun, temel prensipler aynı. Okunabilir, bakımı yapılabilir ve en önemlisi doğru çalışan kod yazmak. Ben genelde C#/.NET ile REST API’ler geliştiriyorum ve Dapper kullanıyorum, o yüzden size bu taraftan bir örnek göstereceğim ama mantık diğer diller için de geçerli. Bazen bir API endpoint’ine veri göndermen gerekir. Örneğin, bir kullanıcı bilgisi kaydı yapacaksın.
Mesela şöyle bir durum düşünelim: Vue.js ile bir frontend’den C# REST API’sine veri göndermek istiyorsun. İlk başta basit bir POST isteğiyle yapmaya çalıştın ama bir türlü çalışmadı. Hata mesajları da pek aydınlatıcı değildi. ‘Request body is empty’ diyor ama sen veri gönderiyorsun, ne alaka? İşte tam burada Dapper’ın veya genel olarak ORM’lerin nasıl çalıştığını bilmek devreye giriyor. Belki de veriyi doğru şekilde parse edemiyordur. Ya da servisin beklediği parametreler tam uyuşmuyordur.
İşte o zaman önce bir Vue.js tarafında gönderdiğin veriyi kontrol edersin. JSON formatı doğru mu? Alan isimleri birebir aynı mı? Sonra backend’e gelirsin. Controller’daki action metodu doğru request body’yi alıyor mu? Dapper kullanıyorsan, SQL sorgun doğru mu? Parametreler doğru eşleşiyor mu? Bu arada, bazen kendi yazdığım kodlar sınıfta kalır, hani o dediğim proxy programı gibi. Geçenlerde de bir API entegrasyonunda böyle bir durum yaşadım. Veri gönderiyorum ama karşı taraf boş dönüyor. Meğersem bir parametreyi eksik göndermişim, o kadar basit bir hataydı ki sinirden tepinmiştim :))
Neyse, gelelim o kod örneğine. Diyelim ki Vue.js’ten bir kullanıcı adı ve şifre gönderiyorsun. İlk denemen şöyle olabilir:
// YANLIŞ DENEME: Sadece parametre yollamak yeterli olmayabilir. [HttpPost] public async Task<IActionResult> CreateUser(string username, string password) { // Burada veriyi alıp veritabanına kaydedeceksin // ... return Ok("Kullanıcı oluşturuldu."); }
Bu şekilde direkt string parametre olarak almak bazen işe yaramaz, özellikle karmaşık objeler gönderdiğinde. Karşı taraf veriyi doğru alamayabilir. İşte o zaman dediğim gibi JSON parse hatası alırsın. Peki doğrusu ne olmalı? Genellikle bir DTO (Data Transfer Object) oluşturup, gelen JSON’u o DTO’ya mapletmek en sağlıklısı. Böylece hem kodun daha okunabilir olur hem de hataları daha kolay bulursun.
Doğru yaklaşım şöyle olmalı:
// DOĞRU YAKLAŞIM: DTO kullanarak veriyi almak. public class UserRegistrationDto { public string Username { get; set; } public string Password { get; set; } }[HttpPost] public async Task<IActionResult> CreateUser([FromBody] UserRegistrationDto userDto) { if (userDto == null) { return BadRequest("Geçersiz kullanıcı bilgileri."); }
// Burada userDto.Username ve userDto.Password'ü kullanarak // Dapper ile veritabanına kaydedebilirsin. // Örnek: await _connection.ExecuteAsync("INSERT INTO Users (Username, PasswordHash) VALUES (@Username, @PasswordHash)", new { Username = userDto.Username, PasswordHash = HashPassword(userDto.Password) }); return Ok("Kullanıcı oluşturuldu."); }
// Not: Gerçek uygulamada şifre hashlenerek saklanmalıdır. // HashPassword metodu burada örnek olarak verilmemiştir.
Gördüğünüz gibi, ilkinde sadece string parametreler alırken, ikincisinde bir DTO kullanıyoruz. Bu, gelen JSON’un direkt olarak `UserRegistrationDto` nesnesine bağlanmasını sağlıyor. Bu sayede hem backend kodun daha temiz oluyor hem de frontend’den gelen verinin yapısı daha net anlaşılıyor. Bu arada, bu tür entegrasyonlar için genelde Google’da bolca örnek bulabilirsin. Hani ben de ilk öğrendiğim zamanlar çok arardım. Hatta bazen YouTube’da kısa videolar izleyerek de anlardım mantığını.
Bu arada, teknik mülakatlarda sadece kod yazmakla kalmazlar. Bazen sana ‘şu durumu nasıl yönetirsin?’, ‘şöyle bir sorun olsa ne yaparsın?’ gibi senaryo soruları da sorarlar. İşte orada da problem çözme yeteneğin devreye giriyor. Hani ilk başta bahsettiğim gibi, bir algoritmayı seçerken neden o algoritmayı seçtiğini, onun artılarını eksilerini anlatabilmen önemli. Bu arada aklıma geldi, geçen seferki sorunda da aslında Dapper’ı kullanmasaydım daha basit bir çözüm bulabilirdim sanırım. Neyse.
Sonuç olarak, teknik mülakatlar göz korkutucu olabilir ama aslında mantığını kavradığında ve bol bol pratik yaptığında gayet yönetilebilir hale geliyor. Veri yapılarını, algoritmaları, Big O gösterimini iyice öğren, bol bol kod yaz, deneme yanılma yap. Özellikle kendi projelerindeki hatalardan ders çıkarmak en büyük öğretmenindir, bana göre. Kendi yazdığım kodların sınıfta kaldığı zamanları unutmam mesela. 🙂 Hani bazen bir kod çalışmaz, saatlerce uğraşırsın da sonunda ‘Allah Allah, bu neden çalışmıyor?’ dersin ya, sonra bir bakarsın ufak bir syntax hatası yapmışsın. İşte o anki hissi yaşamak istemezsin herhalde.
Ayrıca, mülakat sırasında panik yapmamaya çalış. Eğer bir soruyu hemen çözemiyorsan, soruyu soran kişiye ‘Biraz düşünmem için zaman verebilir misiniz?’ demekte çekinme. Hatta bazen ‘Şöyle bir yaklaşımla mı başlasam, yoksa bu mu daha mantıklı olur?’ diye onlarla fikir alışverişi yapmak bile olumlu karşılanabilir. Unutma, onlar senin ne kadar bilgili olduğunu görmek istedikleri kadar, nasıl düşündüğünü ve iletişim kurduğunu da görmek istiyorlar. Yani sadece kod yazan bir robot olmanı beklemiyorlar. Kendi deneyimimden biliyorum, bazen en basit görünen sorularda bile takılıp kalabiliyorsun. Ama önemli olan pes etmemek ve öğrenmeye devam etmek. Hani dağcılıkta da zirveye tırmanırken zorlandığın anlar olur ya, ama o zirveye ulaştığında hissettiğin keyif bambaşkadır. Teknik mülakatlar da biraz öyle işte. 🙂 Bu arada, bu konularda Reddit’te de bolca tartışma var, oraya da bir göz atabilirsin.