شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)
همانطور که می گویند، اگر از کد قدیمی خود خجالت نمی کشید، پس به عنوان یک برنامه نویس رشد نمی کنید - و من با این نظر موافقم. من بیش از 40 سال پیش برنامه نویسی را برای سرگرمی و 30 سال پیش به صورت حرفه ای شروع کردم، بنابراین اشتباهات زیادی دارم. خیلی زیاد. من به عنوان یک استاد علوم کامپیوتر، به دانش‌آموزانم یاد می‌دهم که از اشتباهات خود، اشتباهات من و دیگران بیاموزند. فکر می کنم وقت آن رسیده که درباره اشتباهاتم صحبت کنم تا حیا را از دست ندهم. امیدوارم برای کسی مفید باشند.

مقام سوم - کامپایلر مایکروسافت سی

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

زمانی که سال دوم خود را در MIT تمام کردم، چه در زندگی و چه در برنامه نویسی جوان و بی تجربه بودم. در تابستان، من در مایکروسافت، در تیم کامپایلر C کارآموزی کردم. در ابتدا کارهای معمولی مانند پشتیبانی از پروفایل انجام می‌دادم، و سپس کار بر روی سرگرم‌کننده‌ترین بخش کامپایلر (همانطور که فکر می‌کردم) به من سپرده شد - بهینه‌سازی backend. به طور خاص، من باید کد x86 را برای بیانیه‌های شاخه بهبود می‌دادم.

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

این یک کابوس بود. سالها بعد به من گفتند که برنامه نویسی که کد من را به ارث برده از من متنفر است.

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)

درس آموخته شد

همانطور که دیوید پترسون و جان هنسی در "معماری کامپیوتر و طراحی سیستم های کامپیوتری" می نویسند، یکی از اصول اصلی معماری و طراحی این است که به طور کلی کارها را در سریع ترین زمان ممکن انجام دهیم.

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

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

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

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

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

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)

رتبه دوم: تبلیغات در شبکه های اجتماعی

وقتی در گوگل روی تبلیغات رسانه‌های اجتماعی کار می‌کردم (Myspace را به خاطر دارید؟)، چیزی شبیه به این را در C++ نوشتم:

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
      keywords->add(user->interests(i)->keywords(i)) {
  }
}

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

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

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)

درس آموخته شد

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

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

این چیزی است که بگو درباره توماس واتسون، رئیس افسانه ای IBM:

یک دستور دولتی به ارزش حدود یک میلیون دلار اعلام شد. شرکت IBM - یا بهتر است بگوییم، شخصاً توماس واتسون پدر - واقعاً می خواست آن را بدست آورد. متأسفانه نماینده فروش نتوانست این کار را انجام دهد و IBM در مناقصه شکست خورد. روز بعد، این کارمند وارد دفتر آقای واتسون شد و یک پاکت روی میز او گذاشت. آقای واتسون حتی به خود زحمت نداد که به آن نگاه کند - او منتظر یک کارمند بود و می دانست که این یک نامه استعفا است.

واتسون پرسید چه اتفاقی افتاده است.

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

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

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

مکان اول: App Inventor API

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

هر چه بدتر بهتر

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

چگونه باید باشد: طراحی باید در اجرا و رابط کاربری ساده باشد. سادگی رابط کاربری مهمتر از سادگی پیاده سازی است.

هر چه بدتر، بهتر: طراحی باید در پیاده سازی و رابط کاربری ساده باشد. سادگی پیاده سازی مهمتر از سادگی رابط است.

یک دقیقه آن را فراموش کنیم. متأسفانه چندین سال است که آن را فراموش کرده ام.

برنامه مخترع

زمانی که در گوگل کار می کردم، بخشی از تیم بودم برنامه مخترع، یک محیط توسعه آنلاین کشیدن و رها کردن برای توسعه دهندگان مشتاق اندروید. سال 2009 بود و ما عجله داشتیم که نسخه آلفا را به موقع منتشر کنیم تا در تابستان بتوانیم کلاس های مستر برای معلمانی برگزار کنیم که بتوانند از محیط در هنگام تدریس در پاییز استفاده کنند. من داوطلب شدم تا Sprites را پیاده سازی کنم، دلتنگ نحوه نوشتن بازی ها در TI-99/4. برای کسانی که نمی دانند، اسپرایت یک شی گرافیکی دو بعدی است که می تواند حرکت کند و با سایر عناصر نرم افزار تعامل داشته باشد. نمونه هایی از جن ها عبارتند از سفینه های فضایی، سیارک ها، مرمرها و راکت ها.

ما App Inventor شی گرا را در جاوا پیاده سازی کردیم، بنابراین فقط یک دسته از اشیاء در آنجا وجود دارد. از آنجایی که توپ ها و اسپرایت ها بسیار شبیه به هم رفتار می کنند، من یک کلاس اسپرایت انتزاعی با ویژگی ها (فیلدهای) X، Y، Speed ​​(سرعت) و Heading (جهت) ایجاد کردم. آنها روش های مشابهی برای تشخیص برخورد، پرش از لبه صفحه نمایش و غیره داشتند.

تفاوت اصلی بین توپ و اسپرایت این است که دقیقاً چه چیزی ترسیم شده است - یک دایره پر شده یا یک شطرنجی. از آنجایی که من ابتدا sprites را پیاده‌سازی کردم، منطقی بود که مختصات x و y گوشه سمت چپ بالای جایی که تصویر قرار دارد را مشخص کنم.

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)
هنگامی که sprites کار می کردند، تصمیم گرفتم که می توانم اشیاء توپ را با کد بسیار کمی پیاده سازی کنم. تنها مشکل این بود که من ساده ترین مسیر را انتخاب کردم (از دید مجری)، که مختصات x و y گوشه سمت چپ بالای کانتور را نشان می دهد که توپ را قاب می کند.

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)
در واقع لازم بود مختصات x و y مرکز دایره همانطور که در هر کتاب درسی ریاضی و هر منبع دیگری که از دایره ها ذکر شده است نشان داده شود.

شرم آور ترین اشتباهات در حرفه برنامه نویسی من (تا کنون)
برخلاف اشتباهات گذشته من، این یکی نه تنها همکارانم، بلکه میلیون‌ها کاربر App Inventor را نیز تحت تأثیر قرار داد. بسیاری از آنها کودک یا کاملاً تازه وارد برنامه نویسی بودند. آنها هنگام کار روی هر برنامه ای که توپ در آن حضور داشت، مجبور بودند مراحل غیرضروری زیادی را انجام دهند. اگر اشتباهات دیگرم را با خنده به یاد بیاورم، این یکی حتی امروز هم عرق می کند.

من بالاخره به تازگی، ده سال بعد، این باگ را اصلاح کردم. "Patched"، نه "Fixed"، زیرا همانطور که Joshua Bloch می گوید، API ها ابدی هستند. نمی‌توانیم تغییراتی ایجاد کنیم که بر برنامه‌های موجود تأثیر بگذارد، ویژگی OriginAtCenter را با مقدار false در برنامه‌های قدیمی و درست در همه برنامه‌های آینده اضافه کردیم. کاربران ممکن است یک سوال منطقی بپرسند: چه کسی حتی فکر کرده است که نقطه شروع را در جایی غیر از مرکز قرار دهد. به چه کسی؟ به یک برنامه نویس که ده سال پیش برای ایجاد یک API معمولی تنبل بود.

درس های آموخته شده

هنگام کار بر روی API ها (که تقریباً هر برنامه نویسی گاهی اوقات مجبور است انجام دهد)، باید بهترین توصیه های ذکر شده در ویدیوی Joshua Bloch را دنبال کنید.چگونه یک API خوب ایجاد کنیم و چرا اینقدر مهم است" یا در این لیست کوتاه:

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

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

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

نتیجه

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

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

منبع: www.habr.com

اضافه کردن نظر