Tuzaklara dikkat edin! Java'da 10 yaygın hata

Tam metin 2361 kelime ve beklenen öğrenme süresi 9 dakikadır

Kaynak: unsplash

Sık sık nehir kenarında yürürüm ve ıslak ayakkabı kalmaz.Bazı hataları önlemek gerçekten zordur. Bununla birlikte, yazarın çaylaklardan kıdemli teknik liderlere kadar düzinelerce yazılım mühendisi ile yaptığı röportaja dayanarak, daha fazla durumda, adayların temel kavramları kavrayışlarında boşluklar olduğu görülüyor.

Bu makalede, bir teknik direktör ve röportajcı olarak deneyimime dayanarak, yazar Java geliştiricileri tarafından yapılan en yaygın hataları listeliyor ve vurulup vurulmadığımı görüyor.

1. Erişim değiştiricilerini yok sayın

Biraz anlaşılmaz olsa da, adaylar Java'daki korumalı erişim değiştiricilerin kapsamını gerçekten unuturlar. Belki de görüşme sırasındaki endişe ve gerginlik nedeniyle, genellikle bunlardan sadece birine cevap verebilirler:

· Korumalı alanlara, yöntemlere ve kuruculara alt sınıflardan erişilebilir.

· Korumalı alanlara, yöntemlere ve kuruculara aynı paketten erişilebilir.

Ek olarak, paketin kapsamı birçok geliştiricinin kendi testlerini yazmasına yardımcı olabilir: korunan yöntemlere test yolundan erişilebilir. Yani bu niteliği unutmak, röportajda hiç test yazmadığınızı göstermeye eşdeğerdir!

Kaynak: unsplash

2. Dize bağlantısı

Çok sayıda dizi veya büyük dizi kullanırsanız, bağlantı işlemi sırasında çok fazla bellek harcayabilirsiniz.

Yukarıdaki örnek, bazı StringBuilder ve String nesneleri oluşturmaktır: kesin olmak gerekirse, 10.000.000 StringBuilder ve 10.000.001 String.

Açıklama

Bir adım geri atın ve ne olduğunu görün.

Dize birleştirme için + operatörü kullanıldığında, birleştirme sonucunu saklayan ve sonucu hedef nesneye atayan bir ara nesne oluşturulur.

Yukarıdaki örnekte, toplam 3 nesne oluşturulmuştur: metin için 2 ve bağlantı için 1, yani, ilk dize sonucunun bir kopyası artı ikinci dize "dünya!". String değişmez olduğundan, bu string birleştirme mümkündür.

Ancak derleyici, kodu aşağıdakine dönüştürmek için yeterince akıllıdır (Java9 +, StringContactFacotry'yi kullandığı için geçerli değildir, ancak sonuçlar çok benzerdir):

Bu optimizasyon ara bağlantı nesnesini siler ve bellek 2 string metin ve 1 StringBuilder tarafından işgal edilir. Genel olarak, dizi nesnelerinin sayısı O (n²) 'den O (n)' ye düşmüştür.

İlk örneğe geri dönersek, derleyici kodu aşağıdaki gibi optimize eder:

Derleyici yalnızca dahili bağlantıyı optimize eder, ancak bu çok sayıda StringBuilder ve String nesnesi oluşturur! Dizeleri bağlamanın doğru yolu aşağıdaki gibidir, yalnızca bir StringBuilder ve bir String gereklidir.

3. Eşittir () kullanılmaz

Eşittir () yerine == (karşılaştırma operatörü) kullanıyorsanız, bu alışkanlığı değiştirmeniz gerekir ve sonuçlar şaşırtıcı olabilir.

Açıklama

İki Dizeyi ve diğer nesneleri karşılaştırmak istediğinizde, == kullanmayın. == İçerik yerine yalnızca iki işlenenin nesne referansını (bellek adresi karşılaştırması) karşılaştırır.

Yukarıdaki örnekte, dizge yerleşik dizgi mekanizmasını etkinleştiremez: bellek adresi x'ten farklıdır.

4. Boş döndür

Yazar bu yöntemi defalarca keşfetmiştir:

Boş değer döndürme ile ilgili sorun, arayan kişiyi sonuç üzerinde boş bir kontrol yapmaya zorlamaktır; bu durumda, öğe yoksa, arayan kişi boş bir liste döndürecektir.

Geliştiriciler her zaman bir istisna veya özel nesne (boş bir liste gibi) döndürmek isterler, aksi halde kodu kullanan uygulama NullPointerException tarafından etkilenecektir.

5. Parola bir dizedir

Kullanıcı tarafından sağlanan parolanın dize nesnesinde saklanması bir güvenlik sorunudur ve dizi, bellek saldırılarına karşı savunmasızdır.

JPasswordField ve Password4j'de olduğu gibi karakter kullanılmalıdır. Ancak web uygulamalarından bahsediyorsanız, çoğu web kapsayıcısı HttpServletRequest nesnesinde düz metin parolasını bir String olarak geçirir, böylece geliştiriciler bu konuda neredeyse hiçbir şey yapamazlar.

Kaynak: unsplash

Açıklama

Dizeler Java Sanal Makinesi (JVM) (yerleşik) tarafından önbelleğe alınır ve PermGen alanında (Java 8'den önce) veya yığın alanında depolanır. Her iki durumda da, önbelleğe alınan değer yalnızca çöp toplama gerçekleştikten sonra silinir: bu, belirli bir değerin dize havuzundan ne zaman silineceğini bilmenin imkansız olduğu anlamına gelir, çünkü çöp toplayıcının davranışı belirsizdir.

Diğer bir sorun da Dizelerin değişmez olması, dolayısıyla temizlenememesidir. Ancak, char değişkendir ve işlendikten sonra silinebilir (örneğin, her bir öğeyi 0 ile değiştirin). Bu basit teknik sayesinde bir saldırgan, düz metin parolası yerine yalnızca bellekteki tüm sıfırlardan oluşan bir dizi bulabilir.

6. Boşluk geçirin

Null geçmek, çağıran kodun null değerini yönetebileceğinin kabul edildiği anlamına gelir. Bunu yapamazsa, uygulama kesinlikle bir NullPointerException oluşturur.

Ek olarak, açık bir şekilde null iletmek kodu gittikçe daha kafa karıştırıcı hale getirecektir. Aşağıdaki tipik bir örnektir:

İnit () çağrıldığında, kullanılabilir Kullanıcı nesnesi yoktur. Öyleyse, Kullanıcı yoksa, Kullanıcı üzerinde çalışan bir işlevi neden çağıralım? GrantAccessToUser () içindeki mantık gerekliyse, diğer işlevlerden çıkarılmalı ve null geçirmek yerine kullanılmalıdır.

7. Ağır yöntemler

Aşağıdaki örnekler sistem performansı kaybına neden olabilir:

Pattern.compile () çok yoğun kaynak gerektiren bir işlevdir ve bir dizge aynı kalıpla her eşleştiğinde çağrılmamalıdır.

Açıklama

Pattern.compile (), daha hızlı bellek gösterimi kullanmak için modeli önceden derler. Tek bir eşleşmeyle karşılaştırıldığında, bu işlem son derece güçlü bilgi işlem gücü gerektirir.

Performansı artırmanın klasik yolu, aşağıda gösterildiği gibi Desen nesnelerini statik alanlarda önbelleğe almaktır:

Bu çözüm, aynı kaynak yoğun durum bilgisiz nesne her kullanıldığında kullanılmalıdır.

8. Yineleme sırasında koleksiyonları işleme

Bu kod ConcurrentModificationException oluşturacaktır.

Açıklama

Yineleme sırasında listeden bir öğe silindiğinde, liste yineleyici öğeleri atlamak, öğeleri yinelemek, dizinin sonunu indekslemek gibi iyi çalışmayacaktır. Bu nedenle, birçok koleksiyonun oncurrentModificationException'ı atmak daha kolaydır.

Temel dizi yineleyiciyi kullanın:

9. İstisnalar atmak yerine "dönüş kodları" kullanın

Bir anlamda, geliştiriciler istisnaların uğursuz olduğunu düşünürler, bu nedenle -1 veya "C_ERR" gibi garip değerler döndüren işlevler yazma eğilimindedirler.

Bu, özel bir İstisna oluşturmaya değer tipik bir durumdur. Örnek aşağıdaki gibi yeniden yazılabilir:

Gördüğünüz gibi, kodun okunabilirliği ve sürdürülebilirliği büyük ölçüde geliştirildi. Arayanın, her dönüş koduyla uğraşmak zorunda kalmadan yalnızca DeviceStartException içeriğini okuması gerekir.

10. StringBuffer'ı kullanın

StringBuffer'ın senkronizasyon özelliklerinden dolayı, bu örnek çok fazla bellek kullanımı oluşturacaktır. Daha karmaşık ortamlarda, okuyucu yanlışlıkla bazı gereksiz senkronizasyonların gerekli olduğuna inanabilir.

Projeye bir StringBuffer dahil edilmişse, bunun nedeni bazı eski API'lerin (yani Java5'ten önce) bunu gerektirmesi olabilir, ancak nadiren kodun eşzamanlı bir ortamda Dizeleri eklemeye çalışması olabilir. Bunun yerine StringBuilder'ı kullanın: Java5'te sunulan tüm işlemler eşzamansızdır.

Bu, röportajlarda ve aktif projelerde gördüğüm hataların sadece bir kısmı.Nesne yönelimli programlamanın (OOP) tuzaklarından, tasarım modellerinden, aşırı tasarımından, bellek sızıntılarından ve diğer kusurlarından bahsetmedim ...

Resim kaynağı: xkcd

Bu sorunları yaşıyorsanız, kodlama stilini değiştirme zamanı gelmiştir. Zor değil. Bu tuzaklardan kaçınmak, geliştiricinin deneyimini geliştirebilir ve insanları proaktif olarak bir sonraki görüşmeye hazırlayabilir.

Gerçek hataları gösterebilen ve olası hataları vurgulayabilen SonarQube gibi statik bir kod analizörü kullanın.

Kaynak: unsplash

Öğrenmeye devam etmek daha önemlidir, sadece dilbilgisi değil, aynı zamanda herhangi bir programlama dilinin arkasındaki teori. Küçük hataları sizden uzak tutmak için daha fazla kod yazın ve daha fazla pratik yapın ~

Yorum Beğen Takip Et

Yapay zeka öğrenme ve geliştirmenin kuru mallarını paylaşalım

Yeniden yazdırıyorsanız, lütfen arka planda bir mesaj bırakın ve yeniden yazdırma şartnamelerine uyun

Sıfır yuan ile başladığımda uygulamayı ücretsiz olarak nasıl çalıştırırım?
önceki
Kod yazmak, roman yazmak gibi mi? Jupyter edebi programlamayı gerçeğe dönüştürüyor
Sonraki
Gelişmeye devam edin! Python projenizi otomasyondan nasıl yararlanabilirsiniz?
Yetkili Tanıma | Jitai Test Merkezi, CNAS tarafından akredite edilmiştir
Birden fazla bloğun yıkılmasını içeren Beiyuan Caddesi'ndeki 100 günlük zorlu projelerin listesi burada
Xinxiang Kuzey Bölgesi havalanmak üzere! Yeni bir hastane ve büyük bir spor ve eğlence vadisi inşa etmek için toplam 846 milyonun üzerinde yatırım planlanıyor
Niu Tail Chong, Paiya Dağı, Jingzhou: İlkel ormanda kalan bir masal dünyası
Chen Youweier "Bin mil, on bin mil yürüyor, Fenghuang'da tünemek istemiyor"
Yongding Bölgesi köylerindeki "En Güzel Bahar Manzarası", bugünkü yumruk ring maçı, Xinqiao Kasabasında
Salgın karşıtı kahramanların ilk hattı | Huang Changyi: kurtarmada "Ying"
Jingzhou: Şakayık çiçekleri "zenginleşiyor"
Teknolojik yenilik de çok ilginç olabilir - Chenzhou Madencilik yeraltı akıllı yükseltme
Xiangtan İlçe Halk Hastanesinden Zeng Ling: Koruyucu kıyafetleri çıkarın ve beyaz önlük giyin
Sıcaklık testi, tıbbi izolasyon ... bu ilkokulun günlüğü ilk seviyeye nasıl açtığını görün
To Top