52 पॉइंट द्वारा GN⁺ 2025-02-06 | 6 टिप्पणियां | WhatsApp पर शेयर करें
  • अनुभवी डेवलपर्स ने नए डेवलपर्स के साथ software development की philosophy साझा की है
  • इसमें ground-up rewrite से बचने, schedule management, code quality, automation, edge case handling आदि विभिन्न विषयों पर सलाह शामिल है

किसी भी कीमत पर ऐसी स्थिति से बचें जहाँ ground-up rewrite आकर्षक लगने लगे

  • ground-up rewrite का प्रलोभन तब पैदा होता है जब जमा हो चुका technical debt मौजूदा code को maintain करना मुश्किल बना देता है
  • code complexity बढ़ने के शुरुआती warning signals, जैसे साधारण बदलाव भी कठिन लगना, comments/documentation लिखना मुश्किल होना, core code को समझने वाले लोगों की संख्या कम होना आदि, समय रहते पहचानकर सक्रिय रूप से समाधान तलाशने चाहिए
  • विस्तार का चरण समाप्त होने के बाद complexity कम करने और quality को व्यवस्थित करने वाला integration चरण ज़रूर होना चाहिए
  • अगर ground-up rewrite अपरिहार्य हो जाए, तो इसका मतलब है कि project पहले ही risk zone में प्रवेश कर चुका है
  • risk कम करने के लिए technical debt को लगातार manage करना और code quality को ध्यान से monitor करना चाहिए

उपलब्ध समय के आधे में पूरे काम का 90% पूरा कर लें

  • पहली बार code लिखकर उसे चलने लायक बना देना कुल काम का लगभग आधा हिस्सा ही होता है
  • उसके बाद के चरण, जैसे edge cases संभालना, testing, deployment, documentation, performance, maintainability आदि, ठीक से पूरा करने में अनुमान से कहीं अधिक समय लगता है
  • पर्याप्त buffer रखना चाहिए ताकि अनपेक्षित समस्याओं या polishing जैसे अंतिम कामों को संभाला जा सके
  • अंततः, ‘शुरुआत में code को किसी तरह चलने लायक बनाना’ और ‘उसे एक पूर्ण feature बनाना’ के बीच के अंतर को समझकर schedule में शामिल करना चाहिए

अच्छी practices को automate करें

  • अगर डेवलपर्स से बार-बार सिर्फ़ मौखिक रूप से या documentation में यह कहा जाए कि “ऐसे करना है”, तो गलतियों की संभावना बनी रहती है
  • जहाँ संभव हो, automated tests या scripts के ज़रिए “rule violation होने पर build fail” जैसे तरीके से enforce करना अधिक प्रभावी होता है
  • नई जोड़ी गई rules, जैसे प्रतिबंधित API या अनिवार्य comments, के लिए भी धीरे-धीरे automation लागू करके errors और omissions कम किए जा सकते हैं
  • लेकिन हर चीज़ automate नहीं की जा सकती, और बहुत सख्त rules development flow में बाधा डाल सकते हैं, इसलिए संतुलन ज़रूरी है

चरम (pathological) data को भी ध्यान में रखें

  • केवल normal input या golden path के आधार पर code का आकलन करना जोखिमभरा है
  • ऐसी स्थितियों की कल्पना करनी चाहिए जहाँ requests delay हों या बीच में रुक जाएँ, data बहुत विशाल हो (लाखों से करोड़ों rows), या strings अजीब हों (बहुत लंबी, slash या space शामिल हो)
  • edge cases के लिए गहराई से तैयारी करना ही अंतिम code quality तय करता है

आमतौर पर इसे और सरल लिखने का कोई तरीका होता है

  • शुरुआत में code को काम करने लायक बनाने के बाद, थोड़ा समय लेकर उसे और सरल तथा स्पष्ट रूप में सुधारना अच्छा रहता है
  • भले ही कोई समाधान “अच्छा” लगे, फिर भी यह देखने की आदत महत्वपूर्ण है कि क्या उससे बेहतर तरीका मौजूद है
  • लंबे और जटिल code को संक्षिप्त रूप में refactor करने की प्रक्रिया अंतिम quality को बेहतर बनाती है

code को testable बनाकर लिखें

  • interface और side effects को न्यूनतम रखने से automated tests लिखना बहुत आसान हो जाता है
  • अगर structure को test करना कठिन है, तो संभव है कि encapsulation ठीक से नहीं हुआ है
  • code structure को इस तरह design करने से कि testing अच्छी तरह हो सके, bugs जल्दी पकड़े जा सकते हैं

सिर्फ़ यह काफ़ी नहीं कि code ‘सैद्धांतिक रूप से’ सही है

  • कोई code संरचनात्मक रूप से सुरक्षित दिखे, तब भी environment बदलने या calling pattern बदलने पर समस्याएँ आ सकती हैं
  • यदि code security से संबंधित है, तो वर्तमान call sites सुरक्षित होने पर भी भविष्य में बदलाव की संभावना को ध्यान में रखकर design करना चाहिए
  • code ऐसा होना चाहिए जो “स्पष्ट रूप से सुरक्षित हो, और बदलाव के बाद भी समस्या न पैदा करे”

टिप्पणियाँ

  • “मैं यह पत्र छोटा नहीं लिख सका क्योंकि उसे छोटा लिखने का समय नहीं था” इस वाक्य का स्रोत Pascal है
  • हमेशा off-by-one error से सावधान रहें
  • wiki में नई guideline जोड़ना
    • अगर कंपनी में documentation/knowledge sharing की व्यवस्था ठीक से स्थापित न हो, तो जानकारी बिखर जाती है और भ्रम पैदा होता है
    • आधिकारिक दस्तावेज़ approval process से गुजरते-गुजरते पुराने हो सकते हैं, या कई wiki साथ-साथ मौजूद होने से यह स्पष्ट नहीं रहता कि आधिकारिक सामग्री कौन-सी है
    • एक ही wiki तय करके सारी सामग्री वहीं इकट्ठा करना, और जो कमी हो उसे डेवलपर्स द्वारा सीधे लिखकर या reverse-engineering के माध्यम से भरना, प्रभावी तरीका हो सकता है
    • अगर documentation अन्य जगहों, जैसे source control या code comments, से अच्छी तरह जुड़ी हो, तो उसे up-to-date रखना आसान होता है
    • अगर automated tests और build environment जटिल हों या डेवलपर्स के लिए खुले न हों, तो ऐसी स्थिति बन सकती है कि किसी ने वास्तव में पूरे tests चलाकर ही न देखे हों
    • Jenkins build scripts को सरल रखना अच्छा है, ताकि वे “cd project; ./build-it” जैसे रूप में हों, और इन scripts को source control में भी शामिल किया जाए
    • अगर पूरी टीम एक ही environment, जैसे virtual machine image या build settings, साझा करके build और testing कर सके, तो समस्याओं को पहले से कम किया जा सकता है
    • development चरण में ही edge cases पर विचार करके destroy_object(foo) को ऐसा बनाना कि foo NULL होने पर भी सुरक्षित चले, या create_object() असफल होने पर destroy_object() को अंदर ही call करना, उपयोगी हो सकता है
    • अंततः, यह महत्वपूर्ण है कि सभी डेवलपर्स documentation और build/testing environment तक आसानी से पहुँच सकें और उसमें भाग ले सकें
  • दस्तावेज़ीकरण और automated testing: knowledge sharing के लिए documents या wiki का महत्व, और Jenkins जैसे CI/CD environment की settings साझा की जा सकें, इस तरह का व्यावहारिक सुझाव उल्लेखित है
  • लोगों से मनचाहा व्यवहार करवाने के लिए, जब तक वे उसे याद न कर लें, “असुविधा पैदा करना” से अधिक प्रभावी व्यवहार-परिवर्तन का कोई साधन नहीं है
  • शतरंज की एक कहावत “अगर कोई चाल अच्छी लगे, तो पहले उसे चला दो” की तरह ही programming में भी विपरीत दृष्टिकोण मौजूद है; हर बात के दो पहलू होते हैं।

6 टिप्पणियां

 
bbulbum 2025-02-07

> आमतौर पर इसे और सरल तरीके से लिखने का कोई न कोई तरीका होता है

मेरा मानना है कि अधिक संक्षिप्त समाधान के बारे में सोचना कोड और नीतियों की जटिलता को कम करता है.

 
kipsong133 2025-02-06

> "जहाँ तक संभव हो, कुल काम का 90% आधे समय में पूरा करें"

मुझे लगता है कि यह बात वाकई सही है। एक ही बार में सब कुछ परफ़ेक्ट बनाने की कोशिश करने से बेहतर है कि जल्दी से दो बार देख लिया जाए; इससे गलतियाँ भी कम होती हैं और समय प्रबंधन भी बेहतर हो जाता है।

 
jhj0517 2025-02-06
  1. सर्वोत्तम प्रथाओं का automation (टेस्ट कोड CI/CD pipeline)
  2. शुरुआत में कोड को काम करने लायक बनाएं, फिर थोड़ा समय लेकर बाद में उसे और सरल और स्पष्ट तरीके से बेहतर बनाना अच्छा है
  3. ऐसी स्थिति से हर हाल में बचें जहाँ पूर्ण पुनर्लेखन (ground-up rewrite) आकर्षक दिखे
 
winterjung 2025-02-06

> हमेशा off-by-one error पर ध्यान रखें

मुझे समझ नहीं आ रहा था कि off-by-one error क्या होता है, लेकिन यह for (int i = 1; i < n; ++i) { ... }, for (int i = 0; i <= n; ++i) { ... } जैसी boundary conditions से जुड़ी errors की श्रेणी है।

 
ethanhur 2025-02-06

> किसी भी कीमत पर ऐसी स्थिति से बचें, जहाँ ground-up rewrite आकर्षक लगने लगे

मुझे लगता है कि यह कई IT कंपनियों के बिज़नेस को आगे बढ़ने से रोकने वाला एक pitfall है, और जब technical debt बहुत ज़्यादा जमा हो जाती है, तो जो engineering organizations उसे कम नहीं कर पातीं (या कम करना नहीं चाहतीं), वे full rewrite को आकर्षक विकल्प मानने लगती हैं.

अगर वास्तव में उसे उचित ठहराने वाली ठोस वजह न हो, तो rewrite को जितना संभव हो टालना चाहिए — इस बारे में लेखकों की सोच से मैं गहराई से सहमत हूँ.

 
GN⁺ 2025-02-06
Hacker News राय
  • सॉफ़्टवेयर डेवलपमेंट कोशिश और सीखने की एक दोहरावदार प्रक्रिया है। अनुभवी डेवलपर कोड लिखने और टेस्टिंग के ज़रिए अपनी समझ बढ़ाते हैं और बहुत कुछ सीखते हैं, लेकिन यह बात मीटिंग या प्लानिंग में अक्सर साफ़ दिखाई नहीं देती। जूनियर डेवलपर के लिए production-ready कोड देना मुश्किल हो सकता है, और वे ऐसे काम से बचना चाहते हैं जो बाद में फेंक दिया जाए। अगर मैनेजर के पास डेवलपमेंट का अनुभव कम हो, तो यह समस्या और बढ़ सकती है

  • "मैंने लंबा पत्र लिखने के लिए क्षमा मांगी, क्योंकि मेरे पास उसे छोटा लिखने का समय नहीं था" वाला उद्धरण फ्रांसीसी गणितज्ञ और दार्शनिक Blaise Pascal का है, और इसका मतलब है कि संक्षेप में लिखना ज़्यादा कठिन होता है

  • 90/50 नियम इस बात पर ज़ोर देता है कि कोड की गुणवत्ता बढ़ाने के लिए टेस्टिंग और exception handling को महत्व देना चाहिए। automated tests सेट करना codebase के लिए स्पष्ट अपेक्षाएँ तय करने में मदद करता है

  • कंप्यूटर साइंस की शिक्षा अक्सर जटिल कोड लिखने की ओर ले जाती है, लेकिन आसानी से पढ़े जा सकने वाले कोड लिखना ज़्यादा महत्वपूर्ण है। इसके लिए variables और functions के नामकरण, consistent formatting, और modular design की ज़रूरत होती है

  • Ratchet नाम का एक mechanism भविष्य के लिए एक परिपूर्ण तरीका प्रदान करता है

  • अनुभव और domain awareness को सामान्यीकृत करने की कोशिश गलत generalization तक ले जा सकती है। डेवलपमेंट जटिलता को संभालने की कला है, और असफलताओं से सीखना महत्वपूर्ण है

  • "काम के पहले 90% में 90% समय लगता है, और बाकी 10% में भी एक और 90% समय लग जाता है" वाला उद्धरण डेवलपमेंट की वास्तविकता को अच्छी तरह दिखाता है। exception handling, errors, usability, security आदि पर विचार करते समय बहुत-सा अप्रत्याशित काम सामने आता है

  • Joel Spolsky का लेख rewrite के जोखिमों के बारे में चेतावनी देता है और DevOps की समझदारी पर ज़ोर देता है

  • कोड की readability को बेहतर बनाना चाहिए, और यह समझना चाहिए कि bug मिलने में जितनी देर होती है, उसकी लागत उतनी बढ़ती है। functional programming के सिद्धांतों को प्राथमिकता देना और strong type systems का उपयोग करना फायदेमंद है