بدبینی حرفهای و طراحی الگوریتم
برنامهنویس باید کمی بدبین باشد!
یکی از عادتهایی که به نظرم هر برنامهنویسی باید در خودش تقویت کند، این است که وقتی یک قابلیت را پیادهسازی میکند، فقط به سناریوی موفق آن فکر نکند.
اگر کاربر همهچیز را درست وارد کرد، اینترنت قطع نشد، درخواستها به ترتیب رسیدند، هیچ دادهای ناقص نبود و هیچکس همزمان با او همان کار را انجام نداد، آیا سیستم درست کار میکند؟ احتمالاً بله.
اما دنیای واقعی معمولاً آنقدر مرتب پیش نمیرود.
کاربر ممکن است دکمهای را چند بار بزند. یک درخواست ممکن است دیر برسد. دیتابیس ممکن است در میانهی عملیات با خطا مواجه شود. یک مقدار که تصور میکردیم همیشه وجود دارد، ممکن است خالی باشد. حتی ممکن است تغییری کوچک در یک بخش، رفتاری غیرمنتظره در بخشی دیگر ایجاد کند.
برای همین، من فکر میکنم برنامهنویس باید کمی بدبین باشد؛ البته نه نسبت به آدمها، بلکه نسبت به فرضهایی که دربارهی سیستم خودش دارد.
این بدبینی از همان مرحلهی طراحی الگوریتم شروع میشود. قبل از نوشتن کد، باید مشخص کنیم ورودیها چه هستند، چه خروجیای انتظار داریم، محدودیتها کداماند و در هر مرحله چه شرایطی ممکن است پیش بیاید. اگر فقط مسیر خوشبینانه را طراحی کنیم، در واقع بخش مهمی از مسئله را نادیده گرفتهایم.
مثلاً فرض کنید در یک سیستم رزرو، موجودی یک ظرفیت مشخص را بررسی میکنیم و اگر کافی بود، رزرو را ثبت میکنیم. اگر دو درخواست همزمان به سرور برسند، ممکن است هر دو ظرفیت موجود را تأیید کنند و در نهایت بیش از ظرفیت واقعی رزرو انجام شود.
اینجا مشکل را نمیتوان صرفاً با اضافه کردن یک شرط ساده حل کرد. باید ترتیب عملیات، همزمانی درخواستها و تضمینهای دیتابیس را هم در نظر گرفت. یعنی راهحل درست، از فهم مسئله و طراحی الگوریتم آغاز میشود، نه از اضافه کردن چند خط کد.
اهمیت جزئیات هم دقیقاً در همین نقطه مشخص میشود. یک شرط مرزی که فراموش شده، یک گرد کردن اشتباه در محاسبات مالی یا یک وضعیت خطا که مدیریت نشده، میتواند نتیجهی کار را بهکلی تغییر دهد.
البته این به معنی آن نیست که باید برای هر احتمال بسیار دور، معماری پیچیدهای طراحی کنیم یا توسعهی محصول را تا ابد به تعویق بیندازیم. هیچ سیستمی را نمیتوان در برابر تمام اتفاقات ممکن تضمین کرد.
هنر کار، تشخیص ریسکهای مهم و متناسب با شرایط پروژه است. در یک ابزار شخصی، ممکن است بعضی خطاها فقط کمی آزاردهنده باشند؛ در یک سیستم مالی یا عملیاتی، همان نوع خطا میتواند خسارت جدی ایجاد کند. بنابراین میزان بررسی، تست و کنترل باید با اهمیت پیامدها تناسب داشته باشد.
من وقتی بخشی از نرمافزار را طراحی میکنم، دوست دارم علاوه بر این سؤال که «چطور باید کار کند؟»، چند سؤال دیگر هم مطرح کنم: اگر ورودی اشتباه بود چه؟ اگر عملیات نصفه ماند چه؟ اگر درخواست تکراری بود چه؟ اگر دو اتفاق همزمان افتادند چه؟ و اگر فرض اولیهی ما در آینده تغییر کرد، کدام بخشها تحت تأثیر قرار میگیرند؟
لازم نیست همیشه پاسخ همهی این سؤالها از ابتدا کامل باشد. مهم این است که آنها را ببینیم، ریسکشان را بسنجیم و برای موارد مهم، راهحل و آزمون مشخص داشته باشیم.
در نهایت، برنامهنویسی فقط هنر رساندن سیستم به نتیجهی مطلوب نیست؛ هنر مدیریت مسیرهایی هم هست که ممکن است به نتیجهی نامطلوب برسند.
الگوریتم خوب به ما کمک میکند مسئله را درست حل کنیم. توجه به جزئیات مانع میشود خطاهای کوچک از چشممان پنهان بمانند. و کمی بدبینی حرفهای باعث میشود پیش از آنکه کاربر با یک مشکل واقعی روبهرو شود، خودمان آن را پیدا کنیم.
شاید یکی از نشانههای بلوغ در برنامهنویسی همین باشد: وقتی کد مینویسیم، فقط به این فکر نکنیم که چرا باید کار کند؛ به این هم فکر کنیم که تحت چه شرایطی ممکن است کار نکند.
چون نرمافزار قابل اعتماد، نرمافزاری نیست که هیچوقت با شرایط غیرمنتظره روبهرو نشود؛ نرمافزاری است که برای شرایط مهم، رفتار قابل پیشبینی و کنترلشدهای دارد.
دیدگاهها
۰هنوز دیدگاهی ثبت نشده است؛ اولین نفر باشید.
دیدگاه خود را بنویسید