Bu kitap nasıl okunur: junior, mid ve senior cevap arasındaki fark
Kitabın yapısı, cevap seviyelerinin ölçütü ve mülakattan önceki günlere göre çalışma planı.
Bu bölümde
Bu kitap iki quiz'in (Teknik mülakat provası ve Java/Spring temelleri) ve live coding provasının konularını tek yerde toplar. Son kısım ("Gerçek mülakattan", Bölüm 21-24) gerçek live coding mülakatında sorulan soruları cevaplar; bu sorular kitap boyunca "Gerçek mülakatta soruldu" kutusuyla ve içindekilerde SORULDU etiketiyle işaretlidir. Her bölüm bir konuyu baştan anlatır, quiz'deki soruları çözümleriyle ve nedenleriyle açıklar, quiz'de sorulmayan ama aynı alanda sık gelen konuları ekler ve aynı soruya junior, mid ve senior seviyede verilen cevapları karşılaştırır.
Amaç ezber değil. Bir cevabı senior yapan şey bilginin miktarı değil, bilginin neden, ne zaman ve ne pahasına sorularına bağlanmasıdır. Kitabın her bölümü bu bağlantıyı kurmaya çalışır.
Konu anlatımı
Bölümlerin yapısı
Her bölüm aynı iskeleti izler. Bir konuya hangi amaçla döndüğüne göre doğrudan ilgili başlığa atlayabilirsin.
| Başlık | Ne için |
|---|---|
| Konu anlatımı | Konuyu ilk kez ya da baştan öğrenmek |
| Quiz'deki sorular: çözüm ve nedenleri | Quiz'de yanlış yaptığın ya da tahminle doğru yaptığın soruyu anlamak |
| Üç seviyede cevap | Sözlü mülakata hazırlanmak, kendi cevabını kalibre etmek |
| Sorulmadı ama sorulabilir | Kapsamı genişletmek, sürpriz soruya hazırlanmak |
| Sık yapılan hatalar | Live coding'de ve kod review'da düşülen tuzaklar |
| Hızlı tekrar | Mülakattan önceki akşam 10 dakikalık tekrar |
| Kaynaklar | Birincil kaynaktan derinleşmek |
Üç seviye: neyi ölçüyoruz?
Mülakatçı aynı soruyu herkese sorar; farkı cevabın derinliği ve yönü belirler. Kitap boyunca şu ölçüt kullanılır:
| Junior | Mid | Senior | |
|---|---|---|---|
| Cevapladığı soru | Ne? | Nasıl çalışır? | Ne zaman, neden, ne pahasına? |
| Bilgi | Tanım, ezber cümle | Mekanizma, doğru araç, yaygın tuzaklar | Alternatifler, sınırlar, ölçek, operasyon |
| Hata senaryoları | Yok | Bilinen tuzaklar | Failure mode, gözlemlenebilirlik, geri dönüş planı |
| Trade-off | Yok | Kısmen | Açık ve sayısal |
| Bağlam | Genel | Kod seviyesi | Ekip, production, maliyet, kullanıcı etkisi |
| Netleştirme | Sormaz | Bazen | Varsayımını söyler ya da sorar |
Örnek: "HashMap ile ConcurrentHashMap farkı nedir?"
HashMap thread-safe değildir, ConcurrentHashMap thread-safe'tir. Çoklu thread varsa ConcurrentHashMap kullanırım. Bir de ConcurrentHashMap null key ve null value kabul etmez.
HashMap'e eşzamanlı yazılırsa veri kaybolabilir, resize sırasında yapı bozulabilir. ConcurrentHashMap Java 8'den beri bütün tabloyu kilitlemez; boş bucket'a CAS ile yazar, dolu bucket'ta sadece o bucket'ın ilk node'u üzerinde synchronized kullanır. Okumalar kilitsizdir. Ama tek tek işlemler atomik olsa da containsKey + put gibi bileşik işlemler atomik değildir; bunun için computeIfAbsent ya da merge kullanırım.
Önce asıl sorunun ne olduğuna bakarım. Map'i paylaşan thread'ler varsa ConcurrentHashMap doğru başlangıç, ama thread-safety tek tek metotlarda bitmiyor. Check-then-act yazıyorsak yarış yine var; atomik bileşik işlem için computeIfAbsent/merge kullanırım. computeIfAbsent'in içinde 80 ms'lik bir HTTP çağrısı yapmam; o sırada aynı bucket'a düşen diğer key'ler de bekler. Bunun yerine bir CompletableFuture'ı cache'leyip çağrıyı kilit dışında yaparım ya da Caffeine gibi TTL ve boyut sınırı olan bir cache kullanırım, çünkü sınırsız bir map zamanla memory leak'e dönüşür. size() eşzamanlı güncellemede yaklaşık bir değerdir; metrik olarak kullanacaksam bunu bilirim. Son olarak, servis birden fazla pod'da çalışıyorsa process içi map pod'lar arasında tutarlılık sağlamaz; o ihtiyaç varsa Redis ya da veritabanı gerekir.
Junior cevap yanlış değil ama "neden" ve "ne zaman yetmez" yok. Mid cevap mekanizmayı ve en önemli tuzağı (bileşik işlemler) biliyor. Senior cevap aynı bilgiye üç şey ekliyor: kilit içinde uzun iş yapmanın maliyeti, sınırsız cache'in operasyonel riski ve tek JVM'in ötesindeki ölçek. Ayrıca "önce asıl sorun ne?" diye problemden başlıyor.
Takip sorusu: "Bu cache'i Caffeine'e taşısan hangi ayarları neye göre seçersin?"
Senior cevap formülü
Uzun konuşmak senior yapmaz. Kısa ve yoğun bir senior cevabı çoğunlukla şu sırayı izler:
- Problemi ya da varsayımı netleştir. "Tek pod mu, birden fazla mı?", "Okuma mı yazma mı ağır?"
- Önerini söyle ve tek cümleyle gerekçelendir.
- Mekanizmayı göster. Neden çalıştığını bir seviye alttan anlat.
- Trade-off ve sınırı söyle. "Bunu şu durumda kullanmam."
- Operasyonu ekle. Nasıl ölçerim, nasıl test ederim, bozulursa nasıl anlarım?
- Gerekirse deneyimden somut bir örnek ver. Bankacılık tarafındaki deneyimin burada güçlü bir kaynak: idempotency, tutarlılık, denetlenebilirlik, regülasyon.
Bir soruya cevap verirken "Kısaca X; detayına girersem..." diye başlamak işe yarar. Mülakatçı önce net cevabı alır, sonra derinliği sen seçersin. Mülakatçı yeterli bulursa zaten keser.
"Senior" görünmek için her şeye pattern ve soyutlama eklemek ters teper. Gereksiz katman eklemek de bir junior sinyalidir. "Burada Strategy gereksiz, iki if yeterli; üçüncü firma gelirse çıkarırım" diyebilmek seniorlıktır.
Kitabın bölüm haritası
| Kısım | Bölümler |
|---|---|
| Java | 1 OOP ve nesne tasarımı · 2 Dilin ince noktaları · 3 JVM bellek ve GC · 4 Lambda ve Stream · 5 Concurrency |
| Spring | 6 IoC, DI ve bean yaşam döngüsü · 7 Spring Boot ve konfigürasyon · 8 Transaction ve JPA |
| Veri | 9 SQL sorguları · 10 PostgreSQL: index, izolasyon, kilitleme · 11 NoSQL, arama ve CAP |
| Dağıtık sistemler | 12 Kafka · 13 Saga, outbox ve idempotency · 14 Dayanıklılık |
| Operasyon | 15 Kubernetes, gözlemlenebilirlik ve teslimat |
| Zanaat | 16 Test stratejisi ve TDD · 17 SOLID, design pattern'ler ve refactoring · 18 REST API tasarımı ve hata yönetimi |
| Live coding | 19 Live coding algoritmaları · 20 Sistem tasarımı, code review ve mülakat davranışı |
| Gerçek mülakattan | 21 Gerçek mülakatta sorulanlar ve dead letter queue · 22 Case: deposit, withdraw, exchange · 23 Production'da hata ayıklama, loglama ve tracing · 24 Spring'in iç yüzü |
Quiz'deki sorular: çözüm ve nedenleri
Bu giriş bölümünde quiz sorusu yok. Her quiz sorusu konusuna ait bölümde çözülür. Soru kimliğinden bölüme gitmek için:
| Quiz | Sorular | Bölüm |
|---|---|---|
| Teknik mülakat provası | q1, q4 | 5 |
| q2 | 1 | |
| q3 | 4 ve 9 | |
| q5, q8 | 8 | |
| q6 | 7 | |
| q7 | 6 | |
| q9, q10 | 10 | |
| q11 | 11 | |
| q12, q13 | 12 | |
| q14 | 13 | |
| q15 | 14 | |
| q16 | 3 ve 15 | |
| q17 | 15 | |
| q18 | 8, 13 ve 16 | |
| q19 | 17 | |
| q20 | 20 | |
| Java/Spring temelleri | j1-j4 | 1 |
| j5-j8, j10 | 2 | |
| j9, j11 | 3 | |
| j12-j16 | 4 | |
| j17-j19 | 5 | |
| j20-j22 | 6 | |
| j23, j24 | 7 | |
| j25 | 9 | |
| j26, j27 | 10 | |
| j28 | 11 | |
| Live coding | k1, k2 | 17 |
| k3, k4 | 16 | |
| k5 | 18 | |
| k6 | 20 | |
| k7-k10 | 19 | |
| s1-s15 | 9 | |
| z1-z14 | 16, 17, 18, 20 |
Üç seviyede cevap
Soru: "Kendini teknik olarak nasıl tanımlarsın?"
seviye: Başlangıç etiketler: [behavioral, self-intro] kaynak: Tahmini
Java ve Spring Boot ile backend geliştiriyorum. REST API yazıyorum, veritabanı olarak PostgreSQL kullanıyorum, Kafka ile de çalıştım.
Beş yıldır Java ve Spring Boot ile backend geliştiriyorum. Son dönemde bankacılık tarafında müşteri ve hesap verisinin sahibi olan bir ekipteyim; REST API'ler, PostgreSQL ve Kafka ile event tabanlı entegrasyonlar yazıyorum. Test yazmaya ve kod review'a önem veriyorum.
Beş yıldır Java ve Spring ile backend geliştiriyorum; son bir buçuk yıldır bir bankada müşteri ve hesap verisinin sahibi olan bir ekipte çalışıyorum. Orada beni en çok geliştiren şey, hatanın pahalı olduğu bir alanda tutarlılık ve geriye uyumluluk üzerine düşünmek oldu: idempotent API'ler, event'lerle veri senkronizasyonu, sözleşmeyi bozmadan değişiklik yapmak. Bir feature'ın sahibi olarak tasarımdan production'a kadar sürecin tamamını yürüttüm. Yeni rolde beni çeken şey ölçek: aynı tasarım kararlarını çok daha yüksek trafik altında vermek.
Junior cevap teknoloji listesi. Mid cevap bağlam ekliyor. Senior cevap bir tema (tutarlılık ve sahiplik), somut sorumluluk ve pozisyonla bağlantı kuruyor. Kendi cümlelerinle yaz ve 60-90 saniyede bitecek kadar kısa tut.
Takip sorusu: "Feature owner olarak verdiğin ve sonradan yanlış çıkan bir teknik karar var mı?"
Sorulmadı ama sorulabilir
Mülakattan önceki günlerde çalışma planı
| Kalan süre | Ne yap |
|---|---|
| 3+ gün | Her gün 2-3 bölüm: konu anlatımı + quiz soruları. Akşam ilgili live coding kata'sını süre tutarak çöz. |
| 2 gün | Bölüm 16, 17, 18 ve 20 (live coding'e en yakın bölümler). Kata 1 ve 2'yi bir kez daha, sesli düşünerek çöz. |
| 1 gün | Bütün bölümlerin "Üç seviyede cevap" ve "Sık yapılan hatalar" kısımları. |
| Son akşam | Sadece "Hızlı tekrar" kartları ve Bölüm 20'deki oturum akışı. Yeni konu öğrenme. |
Bilmediğin bir soru gelirse
Bilmediğini kabul etmek, uydurmaktan her zaman iyidir. Senior bir kalıp: "Bunu production'da kullanmadım; benzer bir problemi şöyle çözerdim, şu varsayımla... Doğrulamak için şu dokümana bakardım." Bu cevap bilgi eksiğini akıl yürütmeyle kapatır.
Sık yapılan hatalar
- Tanımla yetinmek. "Thread-safe değildir" deyip neden ve ne olacağını söylememek. Doğrusu: her tanımın arkasından bir "çünkü" ve bir "bu yüzden" getirmek.
- Varsayımı söylememek. "Bu servis kaç pod?" sorusunu sormadan cache tasarlamak. Doğrusu: varsayımı yüksek sesle söylemek.
- Her şeye evet demek. "Her yerde retry kullanırım" demek. Doğrusu: retry'ın sadece idempotent işlemde güvenli olduğunu söylemek.
- Sınırı söylememek. Her tekniğin bozulduğu bir nokta vardır; onu söylemeyen cevap eksik kalır.
Hızlı tekrar
S: Senior cevabı mid cevaptan ayıran üç şey nedir?
C: Trade-off ve sınırı söylemek, operasyonel etkiyi (ölçme, test, failure mode) eklemek, problemi ve varsayımları netleştirerek başlamak.
S: Bir cevaba nasıl başlamak işe yarar?
C: Önce kısa ve net cevap, sonra "detayına girersem..." ile derinlik. Mülakatçı yeterli bulursa keser.
S: Bilmediğin bir soruda ne yaparsın?
C: Bilmediğini söyler, benzer bir problemden akıl yürütür, varsayımını açıklar ve nasıl doğrulayacağını söylersin.