برنامه نویسی

آموزش دیباگ کردن

دیباگ کردن یعنی «کار نمی کند» را قدم به قدم کوچک کنید تا به یک خط برسید؛ اصلاح خودش معمولا کار چند ثانیه است و آنچه وقت می برد رسیدن به آن خط است. چیزی که این کوچک کردن را ممکن می کند نه ابزار است و نه تجربه، بلکه یک تکرار مطمئن است: تا وقتی نتوانید خطا را هر بار که خواستید تولید کنید، هر تغییری حدس است.

  • درس ۱۲ از ۱۴
  • مقدماتی
  • رایگان، بدون ثبت نام

از «کار نمی کند» تا یک خط

  1. ۱

    کار نمی کند

    هر چیزی که کاربر دیده. هنوز یک گزارش است و نه یک مسئله.

  2. ۲

    با چه کاری تکرار می شود؟

    کوتاه ترین مسیر، همان داده، شرط شروع مشخص. بدون این بند، بقیه بند ها بی معنی اند.

  3. ۳

    کدام لایه؟

    مرورگر، شبکه، سرور، پایگاه داده. یک درخواست شبکه یا یک لاگ، این بند را در یک دقیقه می بندد.

  4. ۴

    کدام تابع؟

    اینجا جای نصف کردن است. ده بار نصف کردن، هزار خط را به یکی می رساند.

  5. ۵

    کدام خط؟

    خطی که باور شما و رفتار برنامه از هم جدا می شوند. معمولا همان خطی نیست که خطا رویش چاپ شده.

حالا اصلاح، کار چند ثانیه است

هر بند فقط وقتی بسته می شود که شاهدی داشته باشید، نه وقتی حدسی دارید. پریدن از بند اول به بند آخر همان چیزی است که ساعت ها وقت می برد.

آخرین بررسی: فکت ها و نام ابزارهای این درس در همین تاریخ با منابعشان بازبینی شده اند.

دیباگ کردن یعنی چه، و چرا بیشتر وقتتان صرف پیدا کردن می شود نه درست کردن؟

دیباگ کردن یعنی فاصله بین «کار نمی کند» و «این خط اشتباه است» را کم کنید. اصلاح، در بیشتر باگ هایی که یک تازه کار با آنها روبرو می شود، یک کلمه یا یک علامت است. کل کار، رسیدن به آن کلمه است.

یک تعریف دقیق تر هم هست که همه چیز را ساده می کند: باگ جایی است که باور شما درباره برنامه با کاری که برنامه واقعا می کند فرق دارد. برنامه هیچ وقت «عجیب» رفتار نمی کند و هیچ وقت خلق و خو ندارد؛ دقیقا همان کاری را می کند که نوشته اید. پس دیباگ کردن یعنی پیدا کردن نقطه ای که تصور شما از واقعیت جدا شد.

این تعریف یک نتیجه عملی دارد. اگر باگ اختلاف باور و واقعیت است، هر کاری که این دو را کنار هم بگذارد پیشرفت است و هر کاری که نگذارد نیست. چاپ کردن یک مقدار، پیشرفت است. تغییر دادن یک خط به امید اینکه شاید درست شود، نیست؛ آن قمار است و بدترین خاصیتش این است که وقتی برنده می شوید هم چیزی یاد نمی گیرید.

و یک چیز که کسی به تازه کارها نمی گوید: سرعت شما در دیباگ کردن، بیشتر از آنکه به دانش زبان برنامه نویسی ربط داشته باشد، به نظم روش شما ربط دارد. برنامه نویس با تجربه هم همان پنج مرحله را طی می کند، فقط سریع تر حدس های بی ربط را کنار می گذارد.

چرا قبل از هر کاری باید خطا را قابل تکرار کنید؟

یک تکرار مطمئن یعنی بتوانید بنویسید: «این کار را بکن، این اتفاق می افتد.» تا وقتی این جمله را ندارید، هیچ چیز دیگری معنی ندارد. هر تغییری که بدهید، بعدش نمی دانید درست شد یا فقط این بار پیش نیامد.

یک تکرار خوب سه چیز دارد: کوتاه ترین مسیری که به خطا می رسد، همان داده ای که خطا با آن رخ می دهد، و شرط شروع مشخص. «گاهی وقت ها موقع ثبت سفارش خطا می دهد» تکرار نیست. «با کاربر تازه ساخته شده، سبد خالی، و کد تخفیف منقضی، دکمه ثبت خطای ۵۰۰ می دهد» تکرار است و همین جمله نصف کار را انجام داده.

حالا تله ای که روی همین سایت بارها هزینه داده و در پرونده فنی خودمان نوشته شده است: ممکن است تکرار شما اصلا چیزی را که فکر می کنید امتحان نکند. ما وقتی فایل کش یک صفحه را پاک می کنیم، انجین وب تا یک دقیقه همان فایل پاک شده را سرو می کند، چون نتیجه بررسی وجود فایل را برای ۶۰ ثانیه نگه داشته است. پس اگر بلافاصله بعد از پاک کردن، صفحه را باز کنید، همان صفحه قدیمی را می بینید و نتیجه می گیرید که پاک کردن کار نکرد. کار کرده بود؛ شما زود نگاه کردید.

این شکل خاصی از یک اشتباه عمومی است: بین کاری که کردید و چیزی که می بینید، یک لایه هست که خبر ندارید. کش مرورگر، کش شبکه، کش کد، یک نسخه قدیمی فایل روی سرور دیگر. اولین سوالی که باید از خودتان بپرسید این نیست که «چرا کار نمی کند»، این است که «اصلا مطمئنم دارم چیزی را که عوض کردم اجرا می کنم؟» روی کد پی اچ پی، ساده ترین راه ثابت کردنش این است که یک خط چاپ عمدا اشتباه بگذارید و ببینید آیا اصلا ظاهر می شود.

پیام خطا را چطور بخوانیم؟

بیشتر تازه کارها پیام خطا را نمی خوانند. نگاهش می کنند، از قرمزی اش می ترسند، و می روند سراغ جستجو. حال آنکه پیام خطا معمولا دقیقا همان چیزی را می گوید که لازم دارید و فقط ترتیب خواندنش را کسی یاد نداده.

هر پیام خطای معمولی سه تکه دارد. نوع خطا می گوید چه دسته اتفاقی افتاده. متن می گوید چه چیزی سر چه چیزی آمده. محل فایل و شماره خط را می دهد. و پشت سرشان معمولا یک ردیف فراخوانی هست، یعنی زنجیره توابعی که تا اینجا صدا زده شده اند.

ردیف فراخوانی را از پایین به بالا نخوانید. نزدیک ترین خط به خطا، بالای فهرست است و در بیشتر زبان ها ردیف از جدیدترین به قدیمی ترین چیده می شود. ولی چیزی که واقعا به دنبالش می گردید نزدیک ترین خط نیست؛ نزدیک ترین خطی است که خودتان نوشته اید. اگر پنج خط اول ردیف مربوط به کتابخانه ای است که خودتان ننوشته اید، مسئله معمولا آنجا نیست؛ مسئله در اولین خط از کد خودتان است که آن کتابخانه را صدا زده و چیز اشتباهی به آن داده.

و مهم ترین نکته این بخش: شماره خطی که خطا می دهد، جایی است که مشکل دیده شد، نه لزوما جایی که ساخته شد. اگر خط ۴۲ می گوید متغیر خالی است، خط ۴۲ سالم است؛ جایی که باید آن متغیر پر می شد و نشد، بالاتر است. یک مثال روزمره: پیام «تلاش برای صدا زدن یک متد روی مقدار null» تقریبا هیچ وقت درباره خطی نیست که در آن نوشته شده. درباره خطی است که انتظار داشتید آن مقدار را بسازد و به جایش چیزی برنگرداند، و بین آن دو خط ممکن است ده تابع فاصله باشد.

وقتی برنامه هیچ خطایی نمی دهد چه کار کنیم؟

سخت ترین باگ ها آنهایی هستند که خطا نمی دهند. برنامه اجرا می شود، تمام می شود، و نتیجه اشتباه است یا اصلا نتیجه ای نیست. اینجا اولین کاری که باید بکنید این است که مطمئن شوید واقعا خطایی نیست، یا خطا هست و شما آن را نمی بینید. این دو خیلی فرق دارند و در بیشتر موارد جواب دومی است.

سه جای معمول که خطا در آنها گم می شود: تنظیمات زبان که نمایش خطا را روی سرور خاموش کرده، بلوکی که خطا را می گیرد و کاری با آن نمی کند، و کانال خروجی اشتباه. آن سومی کمتر شناخته شده است و بیشترین وقت را می گیرد.

یک برنامه خط فرمان دو کانال خروجی جدا دارد و یک کد خروج. اگر شما فقط کانال اول را بخوانید، یک ابزار خراب و یک نتیجه خالی برایتان دقیقا یک شکل دارند. مثال واقعی از همین سرور، همان روزی که این درس نوشته شد: دستور پرس و جوی پایگاه داده وردپرس را اجرا کردیم و صفر بایت روی خروجی استاندارد داد. اگر همان جا نتیجه می گرفتیم «هیچ ردیفی نیست»، اشتباه بود. کد خروج ۱ بود و روی کانال خطا نوشته بود که اصلا نتوانسته به پایگاه داده وصل شود.

پس قانون این بخش: نتیجه خالی، شاهد نبودن چیزی نیست. قبل از اینکه به یک خروجی خالی اعتماد کنید، کد خروج را نگاه کنید و کانال خطا را جدا بخوانید.

همین اشتباه شکل ساده تری هم دارد که برای همه پیش می آید: ابزار جستجوی شما چیزی پیدا نمی کند و شما نتیجه می گیرید که آن چیز وجود ندارد. روی همین سایت، برچسب robots صفحه اصلی با کوتیشن تکی چاپ می شود. اگر با کوتیشن دوتایی دنبالش بگردید، صفر نتیجه می گیرید و می گویید برچسب نیست. برچسب هست. الگوی جستجوی شما اشتباه بود، و ابزار هم دقیقا همین را گفت: «چیزی که خواستی پیدا نشد.» بقیه اش را شما اضافه کردید.

برنامه خطا می دهد، یا بی صدا کار اشتباه می کند؟

خطا می دهد

پیام را کامل بخوانید

  • نوع خطا، متن، فایل و شماره خط
  • در ردیف فراخوانی، اولین خط از کد خودتان
  • خط خطا جای دیده شدن است نه ساخته شدن
بی صدا

اول ثابت کنید خطا واقعا نیست

  • نمایش خطا روی سرور خاموش است؟
  • بلوکی خطا را گرفته و دور ریخته؟
  • کد خروج و کانال خطا را جدا نگاه کردید؟

این دو شاخه دو روش کاملا جدا می خواهند. بیشترین وقتی که تلف می شود مال کسی است که در شاخه سمت بی صدا ایستاده و دنبال پیام خطا می گردد.

نصف کردن: کوتاه ترین راه رسیدن به آن یک خط

وقتی تکرار دارید و خطا را خوانده اید و هنوز نمی دانید کجاست، یک روش هست که تقریبا همیشه جواب می دهد و به هوش شما هم وابسته نیست: نصف کنید.

منطقش ساده است. اگر برنامه شما هزار خط است و ندانید مشکل کجاست، هزار جا برای گشتن دارید. اگر نصفش را غیرفعال کنید و خطا هنوز باشد، پانصد جا حذف شد. ده بار نصف کردن، هزار را به یک می رساند. ده قدم، برای مسئله ای که با نگاه کردن ساعت ها طول می کشید.

سه شکل عملی این کار را در روز خودتان می بینید. روی کد: نصف تابع ها را کامنت کنید یا زودتر return بگذارید. روی داده: فایل ورودی هزار ردیفی را به پانصد ردیف ببرید و ببینید خطا می ماند یا نه، تا به کوچک ترین ورودی برسید که هنوز خطا می دهد؛ آن ورودی خودش نصف جواب است. روی زمان: اگر دیروز کار می کرد و امروز نه، بین دو نسخه بگردید نه بین هزار خط. گیت برای همین یک دستور به اسم git bisect دارد که خودش نصف می کند و شما فقط بعد از هر قدم می گویید این نسخه سالم بود یا خراب.

و یک نکته که مبتدی ها را نجات می دهد: وقتی نصف می کنید، حتما کوچک ترین نمونه ای که هنوز خطا می دهد را جدا نگه دارید. یک فایل ده خطی که همان خطا را می سازد، از یک پروژه هزار خطی که همان خطا را می سازد بی نهایت باارزش تر است، چون دیگر هیچ چیز اضافه ای در آن نیست که حواس شما را پرت کند. اگر بخواهید از کسی کمک بگیرید هم همین ده خط را می فرستید و نه کل پروژه را.

یک دور نصف کردن

  1. نصف را خاموش کنید

    نصف توابع، نصف ردیف های ورودی، یا بازه ای از نسخه ها. مهم نیست کدام، مهم این است که نصف باشد.

    ۱
  2. همان تکرار را دوباره اجرا کنید

    دقیقا همان مسیر و همان داده. اگر تکرار عوض شود، نتیجه این دور به درد نمی خورد.

    ۲
  3. هنوز خراب است؟ نیمه سالم را دور بریزید

    اگر خراب است مشکل در نیمه روشن است، و اگر درست شد در نیمه خاموش. هر دو حالت، نصف فضا را حذف می کند.

    ۳
  4. کوچک ترین نمونه خراب را نگه دارید

    ده خطی که همان خطا را می سازد، هم شما را می رساند و هم چیزی است که به کمک کننده می دهید.

    ۴

این حلقه فقط وقتی جواب می دهد که هر دور دقیقا یک چیز عوض شود. دو تغییر همزمان، حلقه را به حدس زدن برمی گرداند.

هر بار فقط یک چیز را عوض کنید، و بنویسید چه چیزی را امتحان کردید

وقتی به یک ناحیه کوچک رسیدید، وسوسه می شوید سه چیز را با هم عوض کنید تا زودتر تمام شود. اگر درست شد، نمی دانید کدام یک درستش کرد. اگر خراب تر شد، حالا سه متغیر دارید به جای یکی. این تنها جایی است که عجله کردن قطعا کندتان می کند.

روش درست شکل ثابتی دارد. یک فرضیه بسازید که بشود غلط بودنش را ثابت کرد: نه «فکر می کنم مشکل از کش است» بلکه «اگر مشکل از کش باشد، با پاک کردنش نتیجه عوض می شود.» بعد ارزان ترین آزمایشی را انتخاب کنید که این فرضیه را رد یا تایید کند، فقط همان یک چیز را عوض کنید، و نتیجه را ببینید. اگر فرضیه غلط بود، برگردانیدش سر جای اول. این برگرداندن را مبتدی ها انجام نمی دهند و بعد از یک ساعت، کد پر است از تغییرهای بی ربطی که خودشان باگ تازه می سازند.

و یک عادت که ارزشش را کسی باور نمی کند تا یک بار امتحان کند: یک فایل متنی باز کنید و هر چیزی را که امتحان کردید با نتیجه اش بنویسید. سه خطی و کوتاه. این کار سه چیز به شما می دهد؛ دیگر یک چیز را دو بار امتحان نمی کنید، وقتی خسته شدید و فردا برگشتید از صفر شروع نمی کنید، و اگر مجبور شدید مسئله را به کسی توضیح دهید، توضیح از قبل آماده است.

خیلی وقت ها نوشتن همان توضیح، خودش جواب را می دهد. آدم ها اسمی هم برایش دارند: توضیح دادن مسئله با صدای بلند برای یک شنونده بی طرف، حتی اگر آن شنونده یک عروسک پلاستیکی روی میز باشد. دلیلش این است که برای توضیح دادن مجبورید فرض هایتان را یکی یکی بگویید، و باگ معمولا در فرضی است که آنقدر بدیهی به نظر می رسید که هیچ وقت به زبان نیاورده بودید.

چاپ کردن یا دیباگر؟ و روی سرور زنده چه کار کنیم؟

دو ابزار اصلی دارید و بحث «کدام بهتر است» بی معنی است، چون کار متفاوتی می کنند.

چاپ کردن یعنی یک خط اضافه می کنید که مقدار یک متغیر را نشان دهد. مزیتش این است که همه جا کار می کند، از یک اسکریپت کوچک تا یک سرور که به آن دسترسی ندارید، و هیچ چیزی نصب نمی خواهد. عیبش این است که هر بار یک عکس لحظه ای می گیرید و اگر جای اشتباهی گذاشته باشید باید دوباره اجرا کنید. برای بیشتر باگ های روزمره کافی است و کسی که می گوید حرفه ای ها چاپ نمی کنند، حرفه ای ها را از نزدیک ندیده.

دیباگر برنامه را وسط راه نگه می دارد و می گذارد همه متغیرها را با هم ببینید و خط به خط جلو بروید. جایی می ارزد که ندانید اصلا کجا را باید چاپ کنید، یا وقتی مسیر اجرا آنقدر پیچ دارد که نمی دانید کدام شاخه رفته است. یاد گرفتنش نیم روز وقت می برد و آن نیم روز را زود پس می گیرید.

روی سرور زنده هیچ کدام از این دو به شکل معمولش جواب نمی دهد. نمی توانید دیباگر وصل کنید و نباید چیزی چاپ کنید که کاربر ببیند. آنجا فقط یک چیز دارید: لاگ. و همین جا یک اشتباه رایج هست که ارزش دارد یک بار برایتان تعریف شود: نوشتن در لاگ به معنی دیده شدن نیست. سرور ممکن است سطح خطاها را طوری تنظیم کرده باشد که پیام شما اصلا ثبت نشود، یا فایل لاگ جایی باشد که فکرش را نمی کنید. قبل از اینکه دنبال باگ بگردید، یک خط بی معنی در لاگ بنویسید و پیدایش کنید. تا وقتی آن یک خط را ندیده اید، ندیدن بقیه پیام ها هیچ چیزی را ثابت نمی کند.

سه چیز که هیچ وقت نباید در لاگ بنویسید هم همین جا گفته شود: رمز، توکن، و اطلاعات شخصی کاربر. لاگ فایلی است که چند نفر می خوانند و مدت ها می ماند.

مسیر سریع با هوش مصنوعی

مسیر سریع، «خطا را کپی کن و بپرس چرا» نیست. آن کار جواب هایی می گیرد که به نظر درست می آیند و ربطی به برنامه شما ندارند، چون مدل سه چیزی را که نمی تواند حدس بزند در اختیار ندارد. کاری که واقعا سریع است این است: سه شاهد را جمع کنید، و از مدل به جای اصلاح، <strong>فهرست فرضیه ها به ترتیب احتمال، هر کدام با ارزان ترین آزمایشی که ردش می کند</strong> بخواهید. خودتان یکی از آزمایش ها را اجرا می کنید و در یک دور، نصف فهرست حذف می شود. این کار قضاوت است پس مدل قوی می خواهد و نه سریع؛ انتخاب فعلی ما میان مدل های کدنویسی در <a class="text-link" href="/ai/code/">بهترین هوش مصنوعی برای کدنویسی</a> آمده و همان جا به روز می شود.

  1. سه شاهد را جمع کنید: تکرار دقیق، متن کامل خطا با ردیف فراخوانی، و فهرست چیزهایی که از آخرین باری که کار می کرد عوض شده اند.
  2. صریح بگویید که کد نمی خواهید. در این مرحله فقط فرضیه می خواهید، وگرنه مدل به جای فکر کردن، وصله می نویسد.
  3. ارزان ترین آزمایش فهرست را خودتان اجرا کنید و نتیجه خام را، بدون تفسیر، برگردانید. تفسیر شما همان چیزی است که مدل را با خودتان هم عقیده می کند.
  4. وقتی به یک فرضیه رسیدید، تازه آن وقت اصلاح را بخواهید، و بخواهید کوچک ترین تغییر ممکن باشد. بعد خودتان همان تکرار اول را دوباره اجرا کنید.

نسخه آماده کپی

یک باگ دارم و کد نمی خواهم. فقط فرضیه می خواهم.

شاهد ۱ - تکرار دقیق:
{این کار را می کنم: ...} {این اتفاق می افتد: ...} {هر بار تکرار می شود / گاهی}

شاهد ۲ - متن کامل خطا (اگر خطایی هست):
{اینجا بچسبانید، با ردیف فراخوانی، بدون خلاصه کردن}
{اگر خطایی نیست بنویسید: خطایی نیست. خروجی مشاهده شده: ... خروجی مورد انتظار: ...}

شاهد ۳ - از آخرین باری که کار می کرد چه چیزی عوض شده:
{کد / نسخه کتابخانه / تنظیمات سرور / داده / هیچ چیز، تا جایی که می دانم}

محیط: {زبان و نسخه اش} روی {سیستم عامل یا سرور}

کاری که می خواهم:
۱. حداکثر ۵ فرضیه برای علت، مرتب از محتمل ترین به کم احتمال ترین.
۲. برای هر فرضیه، ارزان ترین آزمایشی که آن را رد یا تایید می کند، به شکل یک دستور یا یک بررسی مشخص.
۳. برای هر فرضیه، بنویس اگر درست باشد چه چیز دیگری هم باید ببینم. اگر آن نشانه را ندیدم، فرضیه می افتد.
۴. جدا بنویس چه اطلاعاتی نداری که اگر داشتی ترتیب فهرست عوض می شد.

هیچ کدی ننویس. اصلاح را در پیام بعدی می خواهم.

قبل از اعتماد به خروجی: فهرست فرضیه ها حدس هایی است مرتب شده بر اساس شباهت به چیزهایی که مدل دیده، نه بر اساس برنامه شما. آزمایش ها را خودتان اجرا کنید و هیچ وقت بیش از یک تغییر در هر دور ندهید. سه چیز را هم در پیام نگذارید: رمز و توکن، لاگی که اطلاعات شخصی کاربران در آن است، و کد مشتری بدون اجازه او.

هوش مصنوعی در این کار

در دیباگ کردن، مدل ها یک کار را واقعا بهتر از شما انجام می دهند: خواندن یک ردیف فراخوانی از کتابخانه ای که تا حالا ندیده اید و گفتن اینکه این پیام معمولا یعنی چه. کار دومی هم هست که خوب انجام می دهند و کمتر کسی از آن استفاده می کند: تولید فهرست فرضیه ها، چون فهرست ساختن دقیقا همان چیزی است که ذهن خسته شما بعد از دو ساعت انجام نمی دهد. موضع ما این است که مدل را در نقش تولیدکننده فرضیه بگذارید و نه تعمیرکار: تصمیم اینکه کدام فرضیه آزمایش شود و نتیجه آزمایش چه بود، مال شماست.

ابزارهایی که واقعا کمک می کنند

  • Claude Code برای دیباگ کردن مزیت اصلی اش این است که مخزن را می بیند، پس به جای اینکه از شما بپرسد آن تابع کجا صدا زده شده، می رود و پیدا می کند. خودش رایگان نصب می شود ولی بدون اشتراک کلود یا حساب کنسول انتروپیک کار نمی کند، و ایران در فهرست کشورهای پشتیبانی شده انتروپیک نیست.
  • GitHub Copilot برای این موضوع یک چیز مهم دارد: در همان ویرایشگر است، پس وقتی خط خطا را باز کرده اید لازم نیست جای دیگری چیزی بچسبانید. نکته دسترسی اش هم غیرمعمول است و ارزش دانستن دارد؛ صفحه کنترل تجاری خود گیتهاب می گوید مجوزی از خزانه داری آمریکا گرفته که خدمات ابری اش را برای توسعه دهندگان ساکن ایران، رایگان و پولی، پوشش می دهد. ما آن جمله را نقل می کنیم و بیشتر از آن ادعا نمی کنیم: پرداخت از ایران مسئله جداگانه ای است و آن را آزمایش نکرده ایم. طرح رایگانش تا دو هزار تکمیل در ماه است.
  • Claude برای همان کاری که این بخش توصیه می کند مناسب است: متن کامل خطا را بدهید و فهرست فرضیه ها بخواهید، بدون کد. ایران در هیچ یک از دو فهرست کشورهای پشتیبانی شده انتروپیک نیست؛ این را از صفحه خود انتروپیک خوانده ایم و نه از تست شبکه.
  • Gemini برای وقتی که خطا از یک کتابخانه یا سرویس بزرگ و پرمستند است خوب جواب می دهد. صفحه خود گوگل می گوید اپ وب جمنای در بیش از دویست و سی کشور و منطقه کار می کند و ایران در آن فهرست نیست.

کجا نتیجه معکوس می دهد

خطر مخصوص دیباگ کردن این است که مدل با شما هم عقیده می شود. اگر بنویسید «فکر می کنم مشکل از کش است»، برایتان دلیل می آورد که چرا مشکل از کش است، و آن دلیل ها هم منطقی به نظر می رسند. شما به دنبال یک نظر بی طرف رفته بودید و یک بلندگو گرفتید. دستور بالا برای همین می گوید تفسیر خودتان را ننویسید و فقط نتیجه خام آزمایش را برگردانید.
خطر دوم عددی است و منبع دارد. در نظرسنجی سالانه استک اورفلو در سال ۲۰۲۵، بزرگ ترین شکایت توسعه دهندگان از ابزارهای هوش مصنوعی «راه حل هایی که تقریبا درست اند ولی نه کاملا» بود با ۶۶ درصد، و شکایت دوم «دیباگ کردن کد تولیدشده با هوش مصنوعی وقت بیشتری می برد» با ۴۵.۲ درصد. یعنی همان ابزاری که برای سریع تر رفع کردن باگ به آن پناه می برید، اگر بگذارید کد بنویسد، خودش می تواند سهم تازه ای به کار دیباگ شما اضافه کند. انتروپیک هم در مستنداتش این دسته اطمینان بی پشتوانه را توهم می نامد و روش های کم کردنش را توضیح می دهد. برای اینکه بدانید هر کدام از این ابزارها از ایران چطور قابل پرداخت است، راهنمای خرید را ببینید.

منبع ها: Stack Overflow 2025 Developer Survey: AI Anthropic: reduce hallucinations Anthropic: supported countries GitHub and Trade Controls GitHub Copilot plans Google: where the Gemini web app is available

حد این توصیه

همه چیز این درس روی یک فرض ایستاده: خطا قابل تکرار است. برای باگ هایی که فقط زیر بار سنگین، یا فقط وقتی دو کار همزمان اجرا می شوند، یا هر چند روز یک بار پیش می آیند، این روش کار نمی کند و روش دیگری لازم است که اسمش لاگ گذاری و صبر کردن است و درس خودش را می خواهد. سه چیز دیگر را هم عمدا نیاورده ایم: باگ های همزمانی، عیب یابی چیزی که کدش را ندارید، و ابزارهای پروفایل کردن که برای کندی به کار می آیند و نه برای خرابی. و یک صداقت آخر: کوچک کردن مسئله همیشه به یک خط نمی رسد. گاهی به یک تصمیم طراحی می رسد که سه ماه پیش گرفته شده، و آن دیگر باگ نیست.

از تجربه خود ما

مثال «نتیجه خالی شاهد نبودن چیزی نیست» از حافظه نقل نشده؛ همان روزی که این درس نوشته شد روی همین سرور اجرا شد. دستور wp db query وردپرس را با یک شمارش ساده روی جدول نوشته ها اجرا کردیم: خروجی استاندارد صفر بایت داد، کد خروج ۱ بود، و تنها چیزی که واقعا اتفاق افتاده بود روی کانال خطا نوشته شده بود: ERROR 2002 (HY000): Can't connect to local server through socket '/run/mysqld/mysqld.sock'. یعنی ابزار حتی به پایگاه داده وصل نشده بود. اسکریپتی که فقط خروجی استاندارد را می خواند، دقیقا همان چیزی را می بیند که یک جستجوی بی نتیجه تولید می کند و هیچ راهی ندارد تفاوتشان را بفهمد. همان روز مثال دوم را هم روی صفحه اصلی همین سایت گرفتیم: برچسب robots با کوتیشن تکی چاپ می شود، پس جستجوی name="robots" صفر نتیجه می دهد در حالی که برچسب سر جایش است.

سوال هایی که واقعا پرسیده می شوند

از کجا بفهمم مشکل از کد من است یا از سرور؟

کوچک ترین برنامه ممکن را همان جا اجرا کنید: یک فایل که فقط یک جمله چاپ می کند. اگر آن هم کار نکرد، مشکل از کد شما نیست. اگر کار کرد، سرور سالم است و باید همان کوچک ترین نمونه را قدم به قدم بزرگ کنید تا جایی که خراب شود؛ همان قدم، جواب است.

دیباگر یاد بگیرم یا چاپ کردن کافی است؟

برای ماه های اول چاپ کردن کافی است و کسی به خاطر آن شما را قضاوت نمی کند. نشانه اینکه وقتش رسیده این است که ببینید دارید پشت سر هم چاپ اضافه می کنید و هر بار دوباره اجرا می کنید؛ آن الگو یعنی به عکس های لحظه ای جدا احتیاج ندارید، به دیدن همه چیز با هم احتیاج دارید. یاد گرفتنش نیم روز است.

کدم روی کامپیوتر خودم کار می کند ولی روی سرور نه. از کجا شروع کنم؟

از فهرست تفاوت ها، نه از کد. نسخه زبان، نسخه کتابخانه ها، متغیرهای محیطی، دسترسی فایل ها، منطقه زمانی و تنظیمات نمایش خطا. تقریبا همیشه جواب یکی از همین شش تاست، و پیدا کردنش با مقایسه دو تا دو تا سریع تر است تا با خواندن دوباره کدی که می دانید درست است.