155 रीडिंग

कोड गंध 304: Null Pointer अपवाद - NULL संदर्भों से कैसे बचें जो रनटाइम दुर्घटनाओं का कारण बनते हैं

द्वारा Maximiliano Contieri9m2025/06/20
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

NULL संदर्भों से बचें जो उचित सत्यापन और null-safe पैटर्न का उपयोग करके रनटाइम दुर्घटनाओं का कारण बनते हैं
featured image - कोड गंध 304: Null Pointer अपवाद - NULL संदर्भों से कैसे बचें जो रनटाइम दुर्घटनाओं का कारण बनते हैं
Maximiliano Contieri HackerNoon profile picture

मैं NULL समस्याओं के बारे में लिखता रहता हूं, लेकिन हर दिन समाचार मुझे याद दिलाता है: NULL अभी भी जीवित है और हिट करता है।


TL;DR: उचित सत्यापन और null-safe पैटर्न का उपयोग करके runtime crashes का कारण बनने वाले NULL संदर्भों से बचें

TL;DR: उचित सत्यापन और null-safe पैटर्न का उपयोग करके runtime crashes का कारण बनने वाले NULL संदर्भों से बचें

समस्याएं

  • Runtime crashes
  • बड़ी घटनाएं और बाधाएं
  • अप्रत्याशित व्यवहार
  • कठिन डिबगिंग
  • उपयोगकर्ता निराशा
  • प्रणाली अस्थिरता
  • खराब विश्वसनीयता

मेंGoogle क्लाउडमामला :

  • खराब त्रुटि प्रसंस्करण: कोड अनल डेटा को दयालु रूप से संभालने के बजाय टूट गया
  • कोई सुविधा झंडे: सुरक्षा नियंत्रण के साथ नए कोड को धीरे-धीरे लॉन्च नहीं किया गया था
  • त्वरित वैश्विक पुनरावृत्ति: खराब डेटा दुनिया भर में तुरंत फैलता है जैसे Crowdstrike घटना में
  • कोई यादृच्छिक बैककोफ नहीं: वसूली ने बुनियादी ढांचे पर भारी भार का कारण बनाया
  • अपर्याप्त परीक्षण: डिप्लोमा के दौरान असफलता परिदृश्य का परीक्षण कभी नहीं किया गया था

समाधान

  1. शून्य से बचें
  2. null चेक का उपयोग करें यदि nulls आपके नियंत्रण से परे हैं (उदाहरण के लिए, एक बाहरी एपीआई)
  3. डिफ़ॉल्ट मूल्यों को शुरू करें
  4. रखरखाव की शर्तें
  5. Zero Objects का उपयोग करें
  6. विकल्पों का उपयोग न करें

️संपादित करें

https://hackernoon.com/code-refactoring-tips-no-015-remove-null

संदर्भ

12 जून 2019 को, Aबड़ी रोकगूगल क्लाउड प्लेटफॉर्म पर हुआ।


यह दुनिया भर में लगभग 10:49 AM से 1:49 PM PDT (3 घंटे कुल) के बीच Google क्लाउड और Google वर्कस्पेस सेवाओं के दर्जनों को प्रभावित करता है, कुछ सेवाओं को पूरी तरह से ठीक करने में अधिक समय लगता है।


बंद होने का कारण Google के एपीआई प्रबंधन प्रणाली में एक कैस्केडिंग विफलता थी:


  • Trigger के बारे में:

29 मई, 2025 को, Google ने "सेवा नियंत्रण" (उनकी एपीआई प्रबंधन प्रणाली) पर एक नया कोड तैनात किया जो अतिरिक्त कोटा नीति की जाँच जोड़ता है।


इस कोड में एक महत्वपूर्ण दोष था. इसमें उचित कमी थीगलतियां करें and wasn't protected by फ्लैग्स.


  • असफलता के बारे में:

12 जून को एक नीति परिवर्तन जिसमें सफेद/शून्यजब सर्विस कंट्रोल ने इन खाली क्षेत्रों को संसाधित करने की कोशिश की, तो यह अनियंत्रित कोड पथ में एक null पेंटर का सामना करता है, जिसके परिणामस्वरूप बाइनरी एक अंतहीन चक्र में टूट जाते हैं।


  • वैश्विक प्रभाव:

चूंकि कोटा प्रबंधन वैश्विक है, इस क्षतिग्रस्त डेटा को सेकंड में दुनिया भर में दोहराया गया था, जिससे प्रत्येक क्षेत्र में सर्विस कंट्रोल दुर्घटनाग्रस्त हो गया।


Null पेंटर अपवाद तब होते हैं जब आप वस्तुओं पर विधियों या गुणों तक पहुंचने का प्रयास करते हैं जो मौजूद नहीं हैं।


यह तब होता है जब परिवर्तकों में वैध वस्तु उदाहरणों के बजाय null संदर्भ होते हैं।


समस्या उत्पादन वातावरणों में विशेष रूप से खतरनाक हो जाती है जहां ये अपवाद आपके ऐप को खराब कर सकते हैं और उपयोगकर्ताओं को निराश कर सकते हैं।


जावा, सी #, और जावास्क्रिप्ट जैसे भाषाएं इस समस्या के लिए विशेष रूप से संवेदनशील हैं, हालांकि आधुनिक भाषा सुविधाएं और पैटर्न आपको इन दुर्घटनाओं से पूरी तरह से बचने में मदद कर सकते हैं।


Nulls दशकों से सॉफ्टवेयर उद्योग में एक महत्वपूर्ण समस्या है, फिर भी सॉफ्टवेयर इंजीनियर उनके निर्माता के चेतावनी के बावजूद उन्हें अनदेखा करना जारी रखते हैं।

नमूना कोड

ग़लत

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());
      }
  }
}

ठीक है 🙂

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(); }
}

निगरानी

  • [x] आधा स्वचालित

आप null चेक किए बिना वस्तुओं पर प्रत्यक्ष विधि कॉल के लिए कोड की समीक्षा करके संभावित null पेंटर अपवादों का पता लगा सकते हैं।


Linters उन विधियों से वापसी मूल्यों की जांच कर सकते हैं जो वापसी कर सकते हैंशून्य, uninitialized ऑब्जेक्ट फ़ील्ड्स की तलाश करें, और स्थैतिक विश्लेषण उपकरणों का उपयोग करें जो संभावित null dereferences को चिह्नित करते हैं।


आधुनिक आईडीए अक्सर चेतावनी के साथ इन मुद्दों को उजागर करते हैं।

दिन ️

  • शून्य

स्तर

  • [x] मध्यवर्ती

क्यों होता है गर्भावस्था ️

मेंअसली दुनियाया तो वस्तुएं मौजूद हैं या नहीं।


जब आप इसे अपने कार्यक्रम में सही तरीके से मॉडल करते हैं, तो आप एक स्पष्टएक-एक पत्राचारवास्तविकता और कोड के बीच


null संदर्भों की अनुमति देकर इस bijection को तोड़कर भूत वस्तुओं का निर्माण होता है जो आपके कोड में मौजूद होते हैं लेकिन वास्तविक दुनिया में नहीं होते हैं, जब आप इन अस्तित्व वाले इकाइयों के साथ बातचीत करने की कोशिश करते हैं तो दुर्घटनाएं होती हैं।


यदि आप अपने लाइसेंस प्लेट को "NULL" नाम देना चुनते हैं, तो आपकोबहुत सारे पार्किंग टिकट

एक पीढ़ी

एआई जनरेटर अक्सर null पेंटर कमजोरियों के साथ कोड बनाते हैं क्योंकि वे खुश पथ परिदृश्य पर ध्यान केंद्रित करते हैं।


वे अक्सर मार्जिन मामलों पर विचार किए बिना विधि कॉल उत्पन्न करते हैं जहां वस्तुएं हो सकती हैंशून्य, विशेष रूप से जटिल ऑब्जेक्ट हिरासतों में या बाहरी डेटा स्रोतों से निपटने पर।

पता लगाने के लिए

एआई उपकरण अनल पॉइंटर मुद्दों का पता लगा सकते हैं और ठीक कर सकते हैं जब आप रक्षात्मक प्रोग्रामिंग प्रथाओं के बारे में स्पष्ट निर्देश प्रदान करते हैं।

कोशिश कीजिए!

याद रखें: एआई सहायक कई गलतियां करते हैं

Suggested Prompt: Remove all Null References

अनुशंसित परामर्श: सभी Null संदर्भ हटाएं

Without Proper Instructions

With Specific Instructions

ChatGPT

ChatGPT

Claude

Claude

Perplexity

Perplexity

Copilot

Copilot

Gemini

Gemini

DeepSeek

DeepSeek

Meta AI

Meta AI

Grok

Grok

Qwen

Qwen

चैट

चैट

क्लॉड

क्लॉड

संदेह

संदेह

पायलट

पायलट

जुड़वां

जुड़वां

गहराई

गहराई

लक्ष्य क्या है

लक्ष्य क्या है

ग्रोक

ग्रोक

कुंडली

कुंडली

अंतर्दृष्टि

Null पेंटर अपवाद प्रोग्रामिंग में सबसे आम runtime त्रुटियों में से एक हैं।


आप उपयुक्त null चेक को लागू करके, Null Object डिजाइन पैटर्न का उपयोग करके और रक्षात्मक प्रोग्रामिंग प्रथाओं को अपनाकर इन अधिकांश दुर्घटनाओं को हटा सकते हैं।


सत्यापन कोड का छोटा ओवरहेड एप्लिकेशन स्थिरता और उपयोगकर्ता अनुभव में महत्वपूर्ण रूप से भुगतान करता है।

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

अधिक जानकारी

डिस्काउंटर

गंध मेरा हैराय.


मैं इसे अपने अरब डॉलर की गलती कहता हूं. यह 1965 में शून्य संदर्भ का आविष्कार था

मैं इसे अपने अरब डॉलर की गलती कहता हूं. यह 1965 में शून्य संदर्भ का आविष्कार था

टोनी हॉर


This article is part of the CodeSmell Series.


Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks