NULL sorunları hakkında yazmaya devam ediyorum, ancak her gün haber bana hatırlatıyor: NULL hala yaşıyor ve atıyor.
TL;DR: Doğru doğrulama ve null-safe desenleri kullanarak çalıştırma zamanının çökmesine neden olan NULL referanslarını önleyin
TL;DR: Doğru doğrulama ve null-safe desenleri kullanarak çalıştırma zamanının çökmesine neden olan NULL referanslarını önleyin
Sorunlar
- Runtime Çatışması
- Büyük olaylar ve kesintiler
- Unpredictable behavior
- Ağır Debugging
- Kullanıcı frustrasyonu
- Sistemin istikrarı
- Kötü güvenilirlik
içindeGoogle Bulutİlişki :
- Kötü hata yönetimi: Null verileri nazik bir şekilde işlemek yerine kod çöktü
- Hiçbir özellik bayrakları: Güvenlik kontrolleri ile yeni kod yavaş yavaş yayılmadı
- Anlık küresel replika: Kötü veriler Crowdstrike Olayı gibi hemen dünya çapında yayılıyor
- Hiçbir rastgele geri dönüş yok: Kurtarma altyapının aşırı yüküne neden oldu
- Yetersiz test: Başarısızlık senaryosu kurulum sırasında hiçbir zaman test edilmedi
Çözümler
- sıfırdan kaçınmak
- Null kontrollerini kullanın, eğer nulller kontrolünüzün dışında (örneğin, harici bir API)
- Başlangıç Default Values
- Gardiyan Sözleşmelerinin Uygulanması
- Null nesneleri kullanın
- Seçenekleri kullanmayın
Geri Dönüşüm ️
https://hackernoon.com/code-refactoring-tips-no-015-remove-null
bağlamı
12 Haziran 2015 ABüyük kesintilerGoogle Cloud Platform’da gerçekleşti.
Google Cloud ve Google Workspace hizmetlerini dünya çapında yaklaşık 10:49 AM'den 1:49 PM PDT'ye kadar etkiledi (3 saat toplam), bazı hizmetlerin tam olarak kurtarılması daha uzun sürdü.
Google’ın API yönetimi sisteminde bir arka planda arıza meydana geldi:
- Trigger Hakkında:
29 Mayıs 2025'te Google, "Service Control" (API yönetim sistemi) için yeni bir kod dağıttı ve ek kvota politikası kontrollerini ekledi.
Bu kod kritik bir eksikliğe sahipti.Yanlış davranışve koruma altına alınmamıştıBayraklar Özellikleri.
- Bu başarısızlık :
12 Haziran'da beyaz / beyaz içeren bir politika değişikliğisıfırService Control bu boş alanları işlemeye çalıştığında, korumasız kod yolunda bir null işaretleyici ile karşılaştı ve ikili opsiyonlar sonsuz bir döngüde çöktü.
- Küresel Etkisi :
Kvota yönetimi küresel olduğu için, bu bozuk veriler saniyeler içinde dünya çapında çoğaltıldı ve Service Control her bölgede çöktü.
Null işaretleme istisnaları, var olmayan nesnelerin yöntemlerine veya özelliklerine erişmeye çalıştığınızda meydana gelir.
Bu, değişkenlerin geçerli nesne örneği yerine null referansları içerdiğinde gerçekleşir.
Sorun, bu istisnaların uygulamanızı çözebilebileceği ve kullanıcıları hayal kırıklığına uğratabileceği üretim ortamlarında özellikle tehlikeli hale gelir.
Java, C# ve JavaScript gibi diller özellikle bu soruna duyarlıdır, ancak modern dil özellikleri ve desenleri bu çöküşlerden tamamen kaçınmanıza yardımcı olabilir.
Nulller yıllardır yazılım endüstrisinde önemli bir sorun olmuştur, ancak yazılım mühendisleri, üreticilerinin uyarılarına rağmen bunları göz ardı etmeye devam etmektedir.
Kod örnekleri
Yanlış
public class ServiceControlPolicy {
private SpannerDatabase spannerDB;
private QuotaManager quotaManager;
public void applyPolicyChange(PolicyChange change) {
// NULL POINTER: change can be null
Policy policy = spannerDB.getPolicy(change.getPolicyId());
// NULL POINTER: policy can be null from the database
String quotaField = policy.getQuotaField();
// NULL POINTER: quotaField can be null (blank field)
quotaManager.updateQuota(quotaField, change.getValue());
}
public void exerciseQuotaChecks(String region) {
// NULL POINTER: policies list can be null
List<Policy> policies = spannerDB.getPoliciesForRegion(region);
for (Policy policy : policies) {
// NULL POINTER: individual policy can be null
String quotaValue = policy.getQuotaField();
// NULL POINTER: quotaValue can be null before trim()
quotaManager.checkQuota(quotaValue.trim());
}
}
public boolean validatePolicyData(Policy policy) {
// NULL POINTER: policy parameter can be null
String quotaField = policy.getQuotaField();
// NULL POINTER: quotaField can be null before length()
return quotaField.length() > 0 &&
!quotaField.equals("null");
}
public void replicateGlobally(PolicyChange change) {
List<String> regions = getGlobalRegions();
for (String region : regions) {
// NULL POINTER: change.getPolicy() can return null
spannerDB.insertPolicy(region, change.getPolicy());
}
}
}
Doğru
public class ServiceControlPolicy {
private SpannerDatabase spannerDB;
private QuotaManager quotaManager;
public void applyPolicyChange(PolicyChange change) {
if (change == null) {
// Assuming it comes from an external API
// Beyond your control
change = new NullPolicyChange();
}
Policy policy = findPolicyOrNull(change.policyId());
String quotaField = policy.quotaField();
if (!quotaField.isEmpty()) {
quotaManager.updateQuota(quotaField, change.value());
}
}
public void exerciseQuotaChecks(String region) {
if (region == null || region.isEmpty()) {
// Assuming it comes from an external API
// Beyond your control
return;
}
List<Policy> policies = policiesOrEmpty(region);
for (Policy policy : policies) {
String quotaValue = policy.quotaField();
if (!quotaValue.isEmpty()) {
quotaManager.checkQuota(quotaValue.trim());
}
}
}
public boolean validatePolicyData(Policy policy) {
if (policy == null) {
// Assuming it comes from an external API
// Beyond your control
// From now on, you wrap it
policy = new NullPolicy();
}
String quotaField = policy.quotaField();
return quotaField.length() > 0;
}
public void replicateGlobally(PolicyChange change) {
if (change == null) {
// Assuming it comes from an external API
// Beyond your control
// From now on, you wrap it
change = new NullPolicyChange();
}
Policy policy = change.policy();
if (policy == null) {
// Assuming it comes from an external API
// Beyond your control
// From now on, you wrap it
policy = new NullPolicy();
}
List<String> regions = globalRegions();
for (String region : regions) {
spannerDB.insertPolicy(region, policy);
}
}
private Policy findPolicyOrNull(String policyId) {
Policy policy = spannerDB.policy(policyId);
return policy != null ? policy : new NullPolicy();
}
private List<Policy> policiesOrEmpty(String region) {
List<Policy> policies = spannerDB.policiesForRegion(region);
if (policies == null) {
// This is a good NullObject
return Collections.emptyList();
}
return policies.stream()
.map(p -> p != null ? p : new NullPolicy())
.collect(Collectors.toList());
}
}
class NullPolicy extends Policy {
@Override
public String quotaField() { return ""; }
@Override
public String policyId() { return "unknown-policy"; }
@Override
public Map<String, String> metadata() {
return Collections.emptyMap();
}
}
class NullPolicyChange extends PolicyChange {
@Override
public String policyId() { return ""; }
@Override
public String value() { return ""; }
@Override
public Policy policy() { return new NullPolicy(); }
}
Keşifler
- [x] Yarı otomatik
Null denetimi olmadan nesnelerdeki doğrudan metot çağrıları için kodları incelemekle potansiyel null işaretleme istisnaları tespit edebilirsiniz.
Linters, geri dönebilecek yöntemlerden geri dönüş değerlerini inceleyebilir.sıfır, başlangıçlanmamış nesne alanlarını arayın ve potansiyel null dereferences işareti statik analiz araçları kullanın.
Modern IDE’ler genellikle bu sorunları uyarılarla vurguluyor.
Güncel ️
- sıfır
Seviye
- [x] Ortaçağ
Neden bu kadar önemli ️
İçindeGerçek dünyaYani nesneler var ya da yok.
Bunu programınızda doğru bir şekilde modellediğinizde, net birTek Kişilik MektupGerçeklik ve kod arasında.
Null referanslara izin vererek bu bijeksiyonu kırmak, kodunuzda var olan ama gerçek dünyada olmayan hayalet nesneler oluşturur, bu var olmayan varlıklarla etkileşim kurmaya çalıştığınızda çöküşlere neden olur.
Eğer lisans panosunu "NULL" olarak adlandırmayı seçersenizÇok sayıda otopark bileti
Bu nesil
AI jeneratörleri sıklıkla null işaretleme hassasiyeti olan kodlar oluşturur, çünkü mutlu yol senaryolarına odaklanırlar.
Genellikle nesnelerin kullanılabileceği kenar durumları dikkate almadan metot çağrıları oluştururlar.sıfır, özellikle karmaşık nesne hiyerarşilerinde veya dış veri kaynaklarıyla uğraşırken.
Keşfedilecek Yerler
AI araçları, savunma programlama uygulamaları hakkında net talimatlar verdiğinizde null işaretçi sorunlarını tespit edebilir ve düzeltebilir.
Bunu deneyin!
Unutmayın: AI Asistanları Birçok Hata Yapar
Önerilen Prompt: Tüm null referansları kaldırmak
Önerilen Prompt: Tüm null referansları kaldırmak
Without Proper Instructions |
With Specific Instructions |
---|---|
Sonuçlar
Null işaretleme istisnaları, programlamada en yaygın çalıştırma hatalarından biridir.
Uygun null kontrollerini uygulayarak, Null Object tasarım örneği kullanarak ve savunma programlama uygulamalarını uygulayarak bu düşüşlerin çoğunu ortadan kaldırabilirsiniz.
Validasyon kodunun küçüğü, uygulama istikrarı ve kullanıcı deneyimi açısından önemli ölçüde ödüyor.
İlişkiler
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xliii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxix
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxvi
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xlii
Daha fazla bilgi
Disclaimer
Kokularım benimgörüşü.
Ben buna milyar dolarlık hatamı söylüyorum.1965 yılında null referansın icat edilmesiydi.
Ben buna milyar dolarlık hatamı söylüyorum.1965 yılında null referansın icat edilmesiydi.
Toni Şövalye
Bu makale CodeSmell serisinin bir parçasıdır.