80 पॉइंट द्वारा GN⁺ 2025-07-15 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • पूर्णता और गति के बीच संतुलन आसान नहीं है, लेकिन स्थिति के अनुसार उचित गुणवत्ता और समयसीमा का पालन महत्वपूर्ण है
  • पहले ड्राफ्ट (rough draft) के रूप में विकास करना और बाद में कोड की गुणवत्ता सुधारना एक प्रभावी तरीका है
  • requirements को ढीला करने या अत्यधिक मांगों को कम करने से गति और दक्षता बढ़ सकती है
  • भटकाव से बचना और छोटे-छोटे यूनिट में बार-बार commit करना, साथ ही मूल बात पर ध्यान केंद्रित करने की आदत जरूरी है
  • तेज़ development में मदद करने वाली code reading, data modeling, scripting, debugging, pure functions उन्मुखता जैसी ठोस skills मौजूद हैं

“कोड कितना अच्छा होना चाहिए?” – गुणवत्ता मानक और व्यावहारिक चुनाव

  • शुरुआती दिनों में मैं चाहता था कि हर कोड परफेक्ट हो
    • मैंने ऐसे कोड का सपना देखा जिसमें हर function अच्छी तरह test किया गया हो, variable names सुंदर हों, abstraction स्पष्ट हो, और बिल्कुल bug-free code हो
  • लेकिन समय के साथ मैंने यह वास्तविकता सीखी कि “कोई एक सही जवाब नहीं होता”
    • स्थिति के अनुसार जरूरी code quality अलग होती है
    • 24 घंटे का game jam: तैयार कोड का बहुत साफ़-सुथरा या bug-free होना जरूरी नहीं
      • सीमित समय में चलने वाला परिणाम बनाना ज्यादा महत्वपूर्ण है
    • pacemaker software: एक गलती भी किसी इंसान की जान को खतरे में डाल सकती है
      • इसलिए सबसे उच्च स्तर की reliability और safety अनिवार्य है
  • ज़्यादातर projects इन दो चरम सीमाओं के बीच मौजूद होते हैं
    • कुछ कंपनियाँ तेज़ delivery चाहती हैं, इसलिए थोड़े bugs स्वीकार्य होते हैं
    • कुछ projects उच्च गुणवत्ता चाहते हैं, लेकिन schedule ढीला होता है
    • वास्तविक काम में इस संतुलन को समझने की क्षमता महत्वपूर्ण है
    • पहले यह समझना चाहिए कि team का ‘good enough’ मानक क्या है
      • जैसे acceptable bugs की सीमा क्या है, किन हिस्सों में पूर्णता जरूरी नहीं है, आदि व्यावहारिक मानकों को साथ मिलकर देखना चाहिए
  • मेरा व्यक्तिगत मानक यह है
    • “10 में 8 अंक की गुणवत्ता, वह भी समयसीमा के भीतर”
      • कोड अपना उद्देश्य ठीक से पूरा करे, कोई गंभीर समस्या न हो, लेकिन छोटे-मोटे issues रह सकते हैं
      • सबसे महत्वपूर्ण बात है समय पर जमा करना
    • हालांकि यह मानक भी project के संदर्भ के अनुसार लचीले रूप से बदला जाता है
      • कभी-कभी perfection के लिए schedule खिसकना भी ठीक है,
      • और कभी कम polish के बावजूद पहले जल्दी पूरा करना ज्यादा मूल्यवान होता है

Rough drafts – rough draft और prototyping का व्यावहारिक उपयोग और फायदे

  • software development में भी writing की तरह draft (rough draft, spike, walking skeleton) बनाना बहुत उपयोगी है
  • जितनी जल्दी हो सके rough draft implement करके, बाद में उसे निखारकर पूर्ण समाधान में बदला जाता है
  • मेरे rough draft code में बहुत bugs होते हैं: tests fail होते हैं, TODO comments बिखरे होते हैं, exceptions handle नहीं होते, print/log का ज़रूरत से ज़्यादा उपयोग होता है,
    performance पर ध्यान नहीं होता, WIP commit messages होते हैं, अनावश्यक packages जुड़ जाते हैं, repeated code, hardcoding, linter warnings — कुल मिलाकर अव्यवस्थित होता है
  • यह प्रक्रिया अक्षम लग सकती है, लेकिन उद्देश्य है “कम से कम उस अवस्था तक पहुँचना जहाँ समस्या की असली प्रकृति समझ में आ जाए”
  • स्वाभाविक है कि ऐसे draft-stage code को final deployment में नहीं भेजा जाता; वास्तविक release से पहले इसे ज़रूर refine किया जाता है
    (कभी टीम draft code को जैसा है वैसा ही ship करने का दबाव बनाती है, लेकिन मैं यथासंभव उसका विरोध करता हूँ)
  • rough draft approach के मुख्य फायदे

    • “unknown unknowns” को जल्दी सामने लाता है
      • बाद में फेंक दिए जाने वाले code से बेहतर है कि prototype चरण में ही अनजानी रुकावटें मिल जाएँ
    • prototype बनाते समय कई समस्याएँ अपने-आप गायब हो जाती हैं
      • धीमे functions या गलत structure भी बाद में पूरी तरह गैर-ज़रूरी हो सकते हैं, जिससे समय की बर्बादी बचती है
      • बहुत जल्दी optimization या testing पर ज़रूरत से ज़्यादा मेहनत करने की आवश्यकता नहीं
    • फोकस बढ़ाता है
      • अनावश्यक refactoring, naming पर ज़रूरत से ज़्यादा सोच, दूसरे codebase को छेड़ना जैसी भटकनों को रोकता है
        और सिर्फ मौजूदा समस्या पर गहराई से काम करने देता है
    • अनावश्यक early abstraction को रोकता है
      • पहले काम करने वाला समाधान जल्दी बनाने की प्रक्रिया में भविष्य के लिए अनावश्यक abstractions कम बनती हैं
      • सिर्फ मौजूदा समस्या पर ध्यान देकर, बेवजह जटिल design से बचा जा सकता है
    • प्रगति का स्पष्ट संचार
      • rough draft के ज़रिए यह अधिक सटीक अनुमान लगाया जा सकता है कि अभी कितना काम बाकी है
      • कुछ काम करता हुआ पहले दिखा देने से stakeholders की feedback और direction changes जल्दी हो जाते हैं
  • rough draft को व्यवहार में चलाने के तरीके

    • जिन फैसलों को बाद में पलटना मुश्किल हो (binding decision), उन्हें draft चरण में ज़रूर आज़माएँ
      • उदाहरण: language, framework, DB schema जैसी बड़ी दिशाओं की शुरुआती पुष्टि
    • हर temporary workaround/hack को TODO comments आदि में ज़रूर दर्ज करें
      • polish चरण में git grep TODO आदि से सबकी समीक्षा करके सुधार किया जा सकता है
    • Top-Down क्रम में development
      • UI, API जैसी usage surface से scaffold तैयार करें; अंदरूनी logic में hardcoding/temporary implementation स्वीकार्य हो सकती है
      • व्यवहार में UI/user experience तय होते-होते नीचे की logic अक्सर बदलती है, इसलिए ऊपर की layer से implementation शुरू करना फायदेमंद है
      • नीचे से सब कुछ परफेक्ट बनाकर फिर ऊपर फिट करने का तरीका अक्षम है
    • छोटे बदलाव अलग patch में बाँटें

requirements बदलने की कोशिश

  • यह ज़ोर दिया गया है कि कम करना, तेज़ और आसान होता है
  • वास्तविक काम में, दिए गए task की requirements को ढीला किया जा सकता है या नहीं, इस पर हमेशा सोचना चाहिए
    • उदाहरण के सवाल:
      • क्या कई screens को एक में मिलाया जा सकता है?
      • क्या हर मुश्किल edge case को सचमुच संभालना ज़रूरी है?
      • अगर 1000 inputs support करने हैं, तो क्या 10 inputs support करना काफी होगा?
      • क्या polished product की जगह prototype चल सकता है?
      • क्या इस feature को पूरी तरह हटाया जा सकता है?
  • यह approach development speed और efficiency बढ़ाती है
  • संगठन की संस्कृति को भी धीरे-धीरे अधिक शांत और तर्कसंगत गति की ओर ले जाने की कोशिश की जाती है
    • अचानक और बड़े बदलावों की मांग अक्सर काम नहीं करती
    • क्रमिक सुझावों, चर्चा के तरीके में बदलाव आदि से माहौल धीरे-धीरे बदला जाता है

कोड में भटकाव (Distraction) से बचना

  • सिर्फ बाहरी माहौल (notifications, meetings) ही नहीं, बल्कि कोड पर काम करते समय असंबंधित चीज़ों में भटक जाना भी बड़ी बाधा है
  • मैं भी अक्सर bug ठीक करते-करते किसी बिल्कुल असंबंधित हिस्से में उलझ जाता हूँ, और मूल task टल जाता है
  • इसके लिए दो ठोस तरीके:
    • timer सेट करना: हर task के लिए समय सीमा तय करें, और alarm बजते ही मौजूदा प्रगति की जाँच करें
      • जब काम अनुमान से ज़्यादा समय लेने लगे, तब यह सतर्क करता है
      • alarm के साथ git commit कर दें तो छोटा-सा achievement भी महसूस होता है
      • (यह तरीका time estimation की practice में भी उपयोगी है)
    • pair programming: साथ काम करने से बेवजह भटकाव कम होता है और focus बनाए रखने में मदद मिलती है
  • कुछ developers के लिए ऐसा भटकाव टालना स्वाभाविक होता है, लेकिन मेरे लिए सचेत ध्यान और आदत बनाना ज़रूरी है

छोटे बदलाव, छोटे हिस्सों में तोड़ना

  • पहले एक manager था जो बड़े patches और व्यापक changes को बढ़ावा देता था,
    लेकिन अनुभव से यह बहुत अक्षम साबित हुआ
  • मुझे लगभग हमेशा छोटा और focused diff बेहतर लगता है
    • कोड लिखने का मानसिक बोझ कम होता है
    • code review आसान और तेज़ हो जाता है, साथियों की थकान कम होती है, और मेरी गलतियाँ भी आसानी से दिख जाती हैं
    • समस्या आने पर rollback आसान और सुरक्षित होता है
    • एक बार में बदली जाने वाली चीज़ें कम होने से नए bugs का जोखिम भी घटता है
  • बड़े features या feature additions भी छोटे बदलावों के संचय से पूरे होते हैं
    • उदाहरण: अगर नई screen जोड़नी हो, तो bug fix/dependency upgrade/feature addition को अलग-अलग patches में बाँटा जा सकता है
  • यह ज़ोर दिया गया है कि छोटे-छोटे बदलाव तेज़ और उच्च-गुणवत्ता वाले software development में मदद करते हैं

तेज़ development में सचमुच मदद करने वाली ठोस skills

ऊपर की बातें कुछ हद तक अमूर्त हैं, लेकिन ऐसी व्यावहारिक skills भी हैं जो वास्तव में तेज़ development में प्रभावी हैं

  • code reading : अब तक सीखी गई सबसे महत्वपूर्ण developer capability

    • अगर आप मौजूदा code को कुशलता से समझ सकते हैं, तो debugging बहुत आसान हो जाती है
    • open source/third-party libraries के bugs या कमजोर documentation भी कम डरावने लगते हैं
    • दूसरों का code पढ़कर सीखने की मात्रा बहुत बड़ी होती है, और यह overall problem-solving ability को सीधे बेहतर बनाती है
  • data modeling : समय लगे तो भी data model को सही तरह से design करना महत्वपूर्ण है

    • गलत तरह से design किया गया database schema बाद में तरह-तरह की समस्याएँ और महँगे बदलाव लाता है
    • ऐसा design कि invalid state को व्यक्त ही न किया जा सके, bugs को जड़ से कम करता है
    • जहाँ data store होता हो या बाहर से आदान-प्रदान होता हो, वहाँ तो और भी सावधानी जरूरी है
  • scripting : Bash, Python आदि से छोटे scripts जल्दी लिखने की क्षमता development efficiency को बहुत बढ़ाती है

    • हर हफ्ते कई बार markdown sorting, data cleanup, duplicate files ढूँढने जैसी automation tasks में इसका उपयोग होता है
    • Bash में Shellcheck जैसे tools से syntax errors पहले ही रोके जा सकते हैं
    • जिन tasks में बहुत robust होना जरूरी नहीं, वहाँ LLM की मदद से जल्दी काम पूरा किया जा सकता है
  • debugger का उपयोग : debugger इस्तेमाल करना सिर्फ print/log से संभव नहीं होने वाली तेज़ diagnosis और code flow समझने के लिए जरूरी है

    • जटिल bugs की root cause analysis बहुत तेज़ हो जाती है
  • सही समय पर आराम : जब अटक जाएँ, तो साहस के साथ ब्रेक लें

    • लंबे समय तक जूझने पर भी न सुलझने वाली समस्या, 5 मिनट के ब्रेक के बाद तुरंत सुलझ जाने का अनुभव बहुत आम है
    • focus की efficiency के लिए भी यह महत्वपूर्ण है
  • pure functions और immutable data उन्मुखता : functional programming में pure functions और immutable data को पसंद करने से

    • bugs कम होते हैं, state track करने का बोझ घटता है, और code की clarity/predictability बढ़ती है
    • कई बार यह जटिल class hierarchy design से अधिक सरल और प्रभावी होता है
    • यह हमेशा संभव नहीं होता, लेकिन मूल रूप से पहले इसी दिशा में सोचा जाता है
  • LLM (large language model) का उपयोग : LLM (जैसे ChatGPT आदि) की कमियाँ भी हैं, लेकिन repetitive या automatable development tasks में यह बड़ी speed-up देता है

    • अपने code में LLM को कैसे जोड़ना है और उसकी सीमाएँ क्या हैं, यह अच्छी तरह समझकर सक्रिय रूप से उपयोग किया जा रहा है
    • community के विभिन्न अनुभव, tips और examples का भी संदर्भ लिया जाता है
      इन सभी skills को लंबे समय तक बार-बार अभ्यास किया गया है, और वे वास्तव में तेज़ development के लिए बड़ी संपत्ति साबित हुई हैं

सारांश

  • सॉफ़्टवेयर को तेज़ी से विकसित करते हुए मैंने जो मुख्य सबक सीखे, वे ये हैं
    • हर task के लिए जरूरी code quality standard को स्पष्ट रूप से समझें
    • rough draft (ड्राफ्ट) जल्दी लिखें ताकि पूरे ढाँचे की रूपरेखा सामने आ सके
    • requirements को ढीला करने की संभावनाएँ हमेशा खोजें
    • भटकाव में आए बिना focus बनाए रखें
    • बदलाव छोटे रखें और बार-बार commit करें, बड़े patches से बचें
    • ठोस व्यावहारिक skills (code reading, data modeling, debugging, scripting आदि) का लगातार अभ्यास करें
  • ये सब सुनने में बहुत स्वाभाविक लगते हैं, लेकिन इन सबकों तक पहुँचने में वास्तव में बहुत समय लगा

2 टिप्पणियां

 
nicewook 2025-07-15

काफ़ी सारी बातें ऐसी हैं जिनसे सहमति महसूस होती है.
टिप्पणियाँ भी अच्छी हैं, लेकिन जब कोई इस तरह उन्हें व्यवस्थित करके कहता है, यानी उनके लिए एक मंच तैयार करता है, तो उस पर आपत्ति, समर्थन और पूरक बातें जुड़ते हुए वह और अधिक पूर्ण बनती हुई लगती है.

पुनश्च: हाल में "उबाऊ तकनीक" जैसा अभिव्यक्ति अक्सर दिख रही है, अंग्रेज़ी में यह boring technology है.

 
GN⁺ 2025-07-15
Hacker News राय
  • पिछले कुछ वर्षों में मैंने तेज़ और पर्याप्त रूप से मज़बूत सिस्टम बनाना सीख लिया है

    • मैंने सीखा कि एक टूल को गहराई से सीखना महत्वपूर्ण है। ऊपर-ऊपर से ज़्यादा उपयुक्त दिखने वाले टूल की तुलना में वह टूल जिसमें मैं निपुण हूँ, कहीं अधिक प्रभावी है। वास्तव में ज़्यादातर प्रोजेक्ट्स में Django बिल्कुल सही विकल्प होता है

    • कभी-कभी यह सोचकर प्रोजेक्ट शुरू किया कि कहीं Django बहुत भारी न पड़ जाए, लेकिन नतीजतन प्रोजेक्ट शुरुआती इरादे से बहुत आगे बढ़ गया। उदाहरण के लिए, मैंने एक status page app बनाया, और जल्दी ही समझ आ गया कि Django की सीमाओं से बचने की कोशिश करना अक्षम है

    • Django model के अनुकूल ज़्यादातर apps में data model ही मूल है। prototype होने पर भी data model refactoring टालने से बाद में लागत और कठिनाई घातांकीय रूप से बढ़ जाती है

    • ज़्यादातर apps को single-page app या भारी frontend framework की ज़रूरत नहीं होती। कुछ हिस्सों में ज़रूरत पड़ सकती है, लेकिन पूरे पेज का 80% पारंपरिक Django views से अच्छी तरह चल जाता है। बाकी के लिए AlpineJS या HTMX पर विचार किया जा सकता है

    • ज़्यादातर मामलों में खुद बनाना ज़्यादा आसान होता है। Django से CRM, status page, support system, sales process जैसी कई चीज़ें जल्दी बनाई जा सकती हैं। commercial CRM integration से यह कहीं तेज़ है

    • इतनी सामान्य तकनीक चुनो कि वह लगभग उबाऊ लगे। Python/Django/Postgres का संयोजन ज़्यादातर समस्याएँ हल कर देता है। Kubernetes, Redis, RabbitMQ, Celery वगैरह भूल भी सकते हो। Alpine/HTMX अपवाद हैं, क्योंकि उनसे ज़्यादातर JS stack से बचा जा सकता है

    • मेरे लिए Redis और Kubernetes 2025 की ‘उबाऊ तकनीक’ हैं। दोनों बेहद स्थिर हैं, इनके use case स्पष्ट हैं, और इनके नुकसान भी पहले से अच्छी तरह ज्ञात हैं, इसलिए इन पर भरोसा अधिक है। मैं व्यक्तिगत रूप से इन दोनों का प्रशंसक हूँ। ये वही काम ठीक-ठीक कर देते हैं जो मैं चाहता हूँ, इसलिए भरोसेमंद लगते हैं

    • मुझे भी Django बहुत पसंद है। इससे प्रोजेक्ट अविश्वसनीय रूप से तेज़ी से शुरू और deploy किया जा सकता है

      • काम पर हम Go इस्तेमाल करते हैं, लेकिन वही API endpoint बनाने में कोड 10 गुना लंबा हो जाता है। query parameter, pagination जैसी सुविधाएँ जुड़ती हैं तो कोड और बढ़ता जाता है। permission model जोड़ें तो और भी बदतर हो जाता है
      • बेशक performance का अंतर भी बड़ा है, लेकिन असल में performance का अधिकांश हिस्सा DB query पर निर्भर करता है। Python में भी यह काफ़ी तेज़ है
    • अगर सच में ‘उबाऊ तकनीक’ चुननी है, तो Postgres पर भी एक बार फिर सोचना चाहिए

      • Sqlite बहुतों की सोच से कहीं ज़्यादा स्केल संभाल सकता है। खासकर local development/isolated CI instance में, और छोटे apps में तो production में भी पर्याप्त हो सकता है
    • मैं Django प्रोजेक्ट्स में Celery काफ़ी बार इस्तेमाल करता हूँ। इसकी complexity मुझे पसंद नहीं, लेकिन PaaS environment में यह शायद सबसे कम दर्दनाक विकल्प है

      • हर बार मैं सोचता हूँ कि Celery के बिना काम चला लूँ, लेकिन अंत में HTTP से trigger होने वाले jobs timeout से टकराते हैं और Celery इस्तेमाल करनी पड़ती है। उस चरण पर threads, cron job (खासतौर पर PaaS में कठिन), और Celery — इन तीनों में से एक चुनना पड़ता है। जानना चाहूँगा कि आप लोग इसे कैसे संभालते हैं
    • “ज़्यादातर apps को SPA या भारी frontend framework की ज़रूरत नहीं होती” और “एक टूल को गहराई से सीखो” — ये दोनों बातें टकराती हुई लगती हैं

      • मैं हर पेज React में बनाता हूँ। वजह यह नहीं कि SPA हमेशा ज़रूरी है, बल्कि इसलिए कि अंततः client-side state management की ज़रूरत आ ही जाती है, और इसलिए मुझे शुरू से ही सब कुछ React में बनाना अधिक सुविधाजनक लगा। शुरुआत में यह भारी लगे, लेकिन अंततः यह ज़्यादा प्रभावी है
  • जब rough draft के रूप में कोड छोड़ दिया जाता है, तो अक्सर manager उसी को ‘final version’ के रूप में ship कर देता है

    • इसलिए मैं शुरुआत से ही robust code लिखता हूँ। यहाँ तक कि test harness भी लगभग production स्तर जितना मज़बूत बनाता हूँ

    • असली बात है बहुत उच्च गुणवत्ता वाले modules बनाना। जो हिस्से बदलने की संभावना बहुत कम रखते हैं, या जिनमें बदलाव बहुत बड़ा मुद्दा बन सकता है, उन्हें पूरी तरह स्वतंत्र module के रूप में अलग करके dependency की तरह import करता हूँ

    • इन्हीं modules की वजह से मैं नए apps बहुत तेज़ी से विकसित कर सकता हूँ और गुणवत्ता भी लगातार ऊँची रख सकता हूँ

    • जिनका मैंने खुद इस्तेमाल किया है, उनमें RVS_Checkbox, ambiamara, RVS_Generic_Swift_Toolbox आदि शामिल हैं

    • एक सवाल है: क्या Swift में comment marker के रूप में * ################################################################## जैसी code pattern का उपयोग standard माना जाता है?

      • source code में यह काफ़ी दृश्य रूप से उभरकर दिखता है
  • प्रोजेक्ट के scale के अनुसार approach बहुत बदल जाती है

    • व्यक्तिगत प्रोजेक्ट या छोटे team में ‘तेज़ और rough’ तरीके से development करना सबसे उपयुक्त होता है। यही small-scale development की ताकत है

    • छोटे scale पर bug आए भी तो जल्दी ठीक किए जा सकते हैं, और team के सभी लोग लगभग पूरे code को पूरी तरह समझते हैं

    • scale बढ़ते ही architecture mistakes और bug fixes की लागत विस्फोटक रूप से बढ़ जाती है। architecture अनिवार्य रूप से जटिल होता जाता है, और बड़े refactoring लगभग असंभव हो जाते हैं। ऐसे माहौल में हर कदम पर correctness सर्वोच्च प्राथमिकता होनी चाहिए

    • context वास्तव में बहुत महत्वपूर्ण है। ‘बड़े scale’ का मतलब कितना है, यह अलग-अलग हो सकता है, लेकिन मेरे अनुभव में apps के बीच API पर जल्दी सहमति बना लेना ताकि frontend/backend दोनों जल्दी काम शुरू कर सकें, हमेशा सही रहा है

      • जितनी जल्दी हो सके production server पर deploy करके testing और teams के बीच issues सामने लाना प्रभावी होता है
      • लेखक शायद code के दृष्टिकोण पर केंद्रित है, लेकिन मुझे लगता है कि बड़े teams में यह और भी महत्वपूर्ण है
      • हालाँकि teams के बीच layered dependency वाली architecture मुझे पसंद नहीं, फिर भी व्यवहार में यह काफ़ी होती है
    • ऐसी स्थिति में system को छोटा करके चलाना चाहिए। हर कोई विशाल system चाहता है, लेकिन वास्तव में उसकी ज़रूरत नहीं होती

  • एक कहावत है कि “24 घंटे के game jam में code quality की चिंता करने की ज़रूरत नहीं”, लेकिन मेरे ज़्यादातर hackathon/code review अनुभव में सबसे अच्छे परिणाम देने वाली teams code quality और rudimentary testing environment दोनों का ध्यान रखती थीं

    • ऊपर की दोनों बातें (तेज़ी के लिए code quality छोड़नी पड़ती है बनाम अच्छे performing teams की quality ऊँची होती है) वास्तव में परस्पर विरोधी नहीं हैं। अच्छी teams सिर्फ code की सुथराई पर अटकी नहीं रहती थीं

    • game jam के मामले में अगर code की cleanliness पर ज़रूरत से ज़्यादा ज़ोर दिया जाए, तो उल्टा कुल परिणाम खराब हो सकता है। UE blueprint जैसे systems दिखाते हैं कि ‘साफ़-सुथरापन’ से ज़्यादा परिणाम को प्राथमिकता क्यों देनी चाहिए

    • कुछ लोग code की ‘cleanliness’ का समग्र मूल्यांकन करते हैं, जबकि कुछ लोग अनावश्यक code improvement के बारीक cost/benefit का आकलन करते हैं

      • मेरी राय में दूसरा तरीका हर स्थिति में कहीं बेहतर परिणाम देता है — चाहे hackathon हो या high-reliability product code
  • “prototyping करने पर अनपेक्षित ‘unknown unknowns’ सामने आते हैं” इस बात के विपरीत, जब मैं पहली बार किसी चीज़ को छूता हूँ तो मुझे हमेशा सिर्फ़ उसके फायदे दिखते हैं, कमियाँ नहीं

    • वास्तव में edge case handling, user-friendly error message, side effect हटाने जैसी चीज़ों में, यानी feature को सचमुच पूरा करने के चरण में ही असली समस्याएँ (unknown unknowns) सामने आती हैं

    • शायद मेरे अनुभव वाले unknown unknowns टूल/framework/library से आते हैं, जबकि लेखक समस्या-क्षेत्र स्वयं से आने वाले unknown unknowns की बात कर रहा है

    • यह भी सही है कि rough draft बहुत ज़्यादा rough नहीं होना चाहिए। जिन हिस्सों को हल्के में नहीं लिया जाना चाहिए, वहीं से असली समस्याएँ फूटती हैं

      • उदाहरण के लिए, अगर rally driver पहले से ट्रैक research ढंग से न करे, तो उसे अप्रत्याशित ख़तरों (जैसे मोड़ के आगे स्पीड बम्प) का सामना करना पड़ सकता है
    • जब अपने उपयोग के लिए टूल बनाता हूँ, तो उसे थोड़ा ढीले-ढाले तरीके से भी बनाया जाए तो अक्सर ठीक-ठाक इस्तेमाल हो जाता है, और इतनी तेज़ी से बने टूल में खामियाँ होने पर भी ज़्यादा परेशानी नहीं होती

  • आजकल की tech industry में लगातार होने वाली layoffs ही software quality और engineer productivity के लिए सबसे बड़ा ख़तरा हैं

    • नौकरी जाने का डर और जल्दी नतीजे देने का दबाव creativity और experimentation की भावना को मार देता है और burnout लाता है

    • हर कोई AI जैसी trending चीज़ों की भीड़-मानसिकता में बह जाता है, और आलोचना भी नहीं कर पाता

    • यह LLM auto-coding से भी ज़्यादा तात्कालिक समस्या है

    • software quality के लिए सबसे बड़ा ख़तरा हमेशा से यह रहा है कि consumer गुणवत्ता के लिए पैसे नहीं देना चाहता

      • भले ही ऐसे users हों जो quality को ‘महसूस’ कर सकें, फिर भी सिर्फ़ गुणवत्ता के आधार पर नए product को सफल बनाना काफ़ी नहीं होता
      • software के बाहर, जैसे कार या घरेलू उपकरणों में, गुणवत्ता के अनुसार कीमत बदलती है, लेकिन software में ऐसा नहीं है
    • programming-level vendor lock-in असल में SaaS lock-in से कहीं ज़्यादा विनाशकारी है

      • hardware market पहले से ही कुछ ही कंपनियों के प्रभुत्व में है, और अब वही दिन आएगा जब software पर भी वही कंपनियाँ कब्ज़ा कर लेंगी
      • नतीजतन computer programmer की जगह सिर्फ़ LLM prompter बचेगा
  • 24 घंटे के game jam जैसे तेज़ cycle में उल्टा खराब code घातक साबित होता है

    • code जितना साफ़ होगा, गलतियाँ उतनी कम होंगी, working memory पर बोझ कम होगा, और आख़िरी समय में इच्छित बदलाव, feature addition, या problem fix करना उतना आसान होगा

    • 24 घंटे के प्रोजेक्ट में सबसे ज़्यादा चीज़ें इस वजह से बिगड़ती हैं कि आपने धीरे कोड लिखा, ऐसा नहीं; बल्कि इसलिए कि आप खुद को किसी कोने में फँसा लेते हैं या अप्रत्याशित समस्या से पटरी से उतर जाते हैं

    • इसका मतलब यह नहीं कि हर bug पकड़ना ही होगा। लेकिन अगर बुनियादी गुणवत्ता कम हो तो कुल मिलाकर प्रोजेक्ट अनुभव बहुत कठिन हो जाता है

    • यह सिद्धांत ज़्यादा समय वाले प्रोजेक्ट्स पर भी लागू होता है। ज़्यादा समय होने का मतलब यह नहीं कि लापरवाही से लिखना बेहतर है

    • अगर अच्छा code लिखना आदत बन जाए, तो बिना अतिरिक्त लागत के गुणवत्ता सुनिश्चित की जा सकती है। और अगर थोड़ा ज़्यादा समय भी लगे, तब भी यह अंततः मूल्यवान है

    • मैं भी सहमत हूँ। मैंने कई game jam किए हैं, लेकिन ‘ढीला-ढाला code’ सिर्फ़ deadline से 1-2 घंटे पहले, और सिर्फ़ उन files में स्वीकार्य होता है जिन्हें कोई दूसरा नहीं छुएगा

      • common logic को व्यवस्थित करना जैसी code cleanup, सोचने से कम समय लेती है
      • व्यवहारिक रूप से, अस्त-व्यस्त code से पैदा होने वाले bugs, code cleanup से बचाए गए समय की तुलना में कहीं ज़्यादा बड़े और जोखिमपूर्ण होते हैं
      • हालाँकि, आपस में मिलती-जुलती लेकिन अलग functionality (जैसे light fade out बनाम color fade out) के लिए मैं duplicate code छोड़ देता हूँ। क्योंकि requirements आसानी से अलग दिशा में जा सकती हैं
    • तेज़ और अच्छा code लिखने का जवाब आख़िरकार बहुत सारा code लिखने में है

      • दोहराव वाले काम से नापसंदगी हो सकती है, लेकिन व्यवहार में वही असरदार है
      • जो लोग समय के भीतर साफ़-सुथरा coding कर लेते हैं, वे वही लोग हैं जिन्होंने उस तरह का code बहुत लिखा होता है
    • जब बहुत जल्दी हो, तो fancy asset loader जैसी चीज़ों की चिंता नहीं करता, बस static files से काम चला लेता हूँ

      • अगर path traversal जैसी ज़रूरत हो, तो बस breadth first search जैसे सरल तरीके से निपटा लेता हूँ
      • यह ‘खराब code’ नहीं, बल्कि सिर्फ़ अस्थायी उपाय और तेज़ समाधान है
      • बेशक, नियमों के तहत ऐसे modules का उपयोग मना भी हो सकता है, तब दिए गए नियमों के अनुसार चलना होगा
    • मुझे लगता है कि ‘अच्छा code लिखने में ज़्यादा समय लगता है’ वाली धारणा एक गलतफ़हमी है। किसी न्यूनतम स्तर से ऊपर की requirements के लिए, अच्छा code गति में बाधा नहीं बनता

  • “किस स्तर को ‘good enough’ कहा जाए” इसका मानदंड हर team में अलग होता है, और यही मेरे करियर में सबसे बड़े टकराव का कारण रहा है

    • big tech पृष्ठभूमि वाले लोग अपर्याप्त testing से असंतुष्ट होते हैं, और startup पृष्ठभूमि वाले लोग गति धीमी होने से

    • ‘good enough’ के मानदंड को स्पष्ट रूप से दस्तावेज़ित करके team के भीतर साझा करना उपयोगी होगा

    • यही तो team charter है, यानी ‘हम कैसे काम करते हैं’ दस्तावेज़

  • लेख में न बताई गई एक महत्वपूर्ण बात है समय के साथ development speed का धीमा होना

    • जैसे-जैसे प्रोजेक्ट और team का आकार बढ़ता है, development speed स्वाभाविक रूप से कम होती जाती है

    • यानी, तत्काल development speed में थोड़ा नुकसान सहकर भी दीर्घकाल में speed कम न गिरे, इसके लिए शुरुआती चरण में testing, documentation, decision log, Agile meeting वगैरह की तैयारी ज़रूरी है

    • observability जैसी सुविधाएँ या testing-friendly code structure पहले से तैयार न हों, तो बाद में उसका बहुत बुरा असर पड़ता है

    • मैं solo developer हूँ, लेकिन decision log, testing और documentation — इन तीनों की अहमियत को गहराई से महसूस करता हूँ

      • मैं real-time design record लिखता हूँ जिसे मैं “lab notebook” कहता हूँ, और यही बाद में testing और documentation की नींव बनता है
      • lab notebook हो तो देर से शुरू करने पर भी बेहतर documentation जल्दी लिखी जा सकती है। testing यह सत्यापित करने में भी मदद करती है कि design बदला तो नहीं
      • बहुत छोटे, एक-बार उपयोग वाले tools के लिए सीधे शुरू कर देना ठीक है, लेकिन लंबे समय तक चलने वाले system के लिए धीरे सही, मज़बूत नींव बनाना अंततः अधिक तर्कसंगत और maintainable परिणाम देता है
      • यह शायद लोकप्रिय राय नहीं है, लेकिन design पहले कागज़ पर करना और फिर उसे digital में ले जाना प्रभावी होता है
  • यह मेरे लिए भी परिचित pattern है। rough draft, या idea validation के लिए मैं किसी दूसरी scripting language या manually चलाए जाने वाली चीज़ों को जोड़कर छोटे code से शुरुआत करता हूँ

    • ऐसे process से गुज़रकर कई बार हम इस निष्कर्ष पर भी पहुँचे हैं कि “हमें वह चीज़ बनाने की ज़रूरत ही नहीं है जो हम बनाना चाहते थे”
    • coding करते हुए ध्यान भटकने वाली बात से मैं पूरी तरह सहमत हूँ। चीज़ों को व्यवस्थित करते-करते अक्सर rabbit hole में फँस जाते हैं, commit का आकार बड़ा हो जाता है, और साथियों के लिए review करना मुश्किल हो जाता है। अंत में कई बार पूरा काम फेंककर फिर से छोटा और उद्देश्य-केंद्रित तरीके से शुरू करना पड़ता है
    • कभी-कभी उपयोगी टुकड़ों को अलग निकालकर दूसरे PR में भेजा जा सकता है
    • business जल्दी परिणाम चाहता है, और code के trade-off को तब तक नहीं समझता जब तक debt का पहाड़ जमा होकर development speed बहुत धीमी न कर दे
    • महत्वपूर्ण चीज़ संतुलन है, और हर प्रोजेक्ट पर अलग मानदंड लागू हो सकते हैं
    • इसलिए छोटे, केंद्रित, सरल बदलाव बार-बार करना मददगार होता है
    • लेकिन बड़े solution को छोटे टुकड़ों में बाँटना उतना आसान नहीं जितना लगता है
    • मैं अक्सर देखता हूँ कि लोग बिल्कुल असंबंधित और इस्तेमाल भी न होने वाला code यह सोचकर commit कर देते हैं कि ‘बाद में काम आएगा’; लेकिन priority बदलने, लोगों के बदलने वगैरह के कारण एक साल बाद वह सब बेकार code बन जाता है, और उस समय की योजना भी किसी को याद नहीं रहती