آیا می‌دانستید که مهندسین نرم‌افزار و برنامه‌نویسان چه تفاوت‌هایی با یکدیگر دارند؟

آیا می‌دانستید که مهندسین نرم‌افزار و برنامه‌نویسان چه تفاوت‌هایی با یکدیگر دارند؟

اگر بخواهیم در یک جملۀ کوتاه تفاوت مابین مهندسین نرم‌افزار و برنامه‌نویسان (دولوپرها) را عنوان کنیم، به این گزاره بسنده خواهیم کرد که تمام مهندسان نرم‌افزار می‌توانند کدنویسی کنند، اما همۀ دولوپرها نمی‌توانند نرم‌افزاری را مهندسی کنند!

Software Engineer (مهندس نرم‌افزار) کیست؟
در یک کلام، مهندس نرم‌افزار شخصی است كه وظیفه‌اش نوشتن نرم‌افزاری است که از هر حیث کامل باشد؛ فردی که در حرفۀ خود علم کدنویسی و منطق را درهم می‌آمیزد و تنها به‌ عنوان یک راه کسب درآمد به آن نگاه نمی‌کند. به عبارت دیگر، اینکه فقط بدانیم چگونه کد بزنیم از ما یک مهندس نرم‌افزار نخواهد ساخت.

تقریباً هر فردی می‌تواند برنامه‌نویسی را یاد بگیرد چرا که یادگیری آن چندان دشوار نیست. همچنین می‌شود گفت که هر دولوپری می‌تواند برنامه‌های ساده‌ای توسعه دهد که در دیوایس‌های شخصی خود کار کند اما هیچ تضمینی نیست که این برنامه‌ها بر روی سیستم‌های دیگر افراد نیز به همان خوبی کار کنند.

برای درک بهتر این موضوع، مثالی از دنیای واقعی می‌زنیم. برای مثال، فردی را در نظر بگیرید که در حمام خانۀ خود آواز می‌خواند و خود را سرگرم می‌کند؛ اما این فرد در مهمانی‌ها برای حفظ اعتبار خود هرگز نمی‌تواند و نمی‌خواهد که دست به چنین کار پُرریسکی بزند! اگر بخواهیم در این حوزه مثال‌های بیشتری بزنیم، می‌توان موارد زیر را عنوان کرد:
- ما فارسی و ریاضی را در مدرسه آموختیم، اما همۀ ما نویسنده یا ریاضی‌دان نشده‌ایم.
- بسیاری از ما به‌ راحتی می‌توانیم پخت غذا را یاد بگیریم، اما در مهمانی‌های بزرگ که باید برای تعداد زیادی از افراد غذا درست کنیم، این وظیفهٔ را بر عهدهٔ یک آشپز حرفه‌ای و باتجربه می‌گذاریم.
- همچنین ما هیچ‌وقت از یک کارگر روزمُزد نمی‌خواهیم که یک خانه برایمان بسازد.

به طور خلاصه، پیام اصلی مقاله این است که نوشتن یک برنامهٔ ساده بسیار متفاوت از نوشتن برنامه‌های «مهندسی‌شده» است اما اکنون این سؤال به ذهن می‌رسد که خودِ کدنویسی به چه معنا است؟ در ساده‌ترین تعریف ممکن، کدنویسی عبارت است از ارائۀ یکسری دستورالعمل‌ها به کامپیوتر به این منظور که با دریافت ورودی‌هایی خاص، کاری را روی آن‌ها انجام داده و در نهایت یکسری خروجی قابل‌پیش‌بینی در اختیارمان قرار دهد.

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

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

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

افراد باهوش مشکلات رو حل می‌کنن اما نابغه‌ها از بروز اون‌ها جلوگیری می‌کنن!

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

کیفیت سورس‌کد
سورس‌کد یک برنامۀ عالی، واضح و قابل‌خواندن است؛ همچنین می‌توان آن‌ را به‌ آسانی توسعه داد. نیاز به توضیح نیست که چنین برنامه‌هایی با برنامه‌های دیگر به‌ خوبی کار می‌کنند و نگاه‌داری سورس‌کدشان به یک کابوس برای مهندسان نرم‌افزار تبدیل نخواهد شد!

بنابراین کیفیت کد چیزی نیست که بتوان آن را با پول مقایسه کرد و دربارۀ آن وارد مذاکره شد! به‌ علاوه اینکه استفاده از راه‌های میانبُر و درهَم در کدنویسی، به هر دلیلی از جمله پایان یافتن مهلت (دِدلاین) انجام آن، هرگز قابل‌قبول نیست.

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

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

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

در علوم کامپیوتر تنها دو کار سخت وجود داره؛ نامعتبرسازی قسمتی از دیتای موجود در کَش (یا اصطلاحاً Cache Invalidation) و نام‌گذاری چیزهای مختلف مثل متغیر، متد، کلاس و غیره!

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

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

در نوشتن یک برنامه مسلماً اشتباهاتی نیز پیش خواهد آمد؛ اما ویژگی کلیدی یک نرم‌افزار خوب این است که بتوان به‌ آسانی این اشتباهات را رفع کرد. ارورهایی که در برنامه‌ها رخ می‌دهند باید پیام‌های واضحی داشته باشند و لاگ مربوط به آن‌ها نیز به‌ صورت متمرکز در جایی در سیستم ثبت شود که بتوان آن‌ها را در صورت نیاز مانیتور کرد.

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

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

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

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

برخی از مهندسان نرم‌افزار این کار را با نوشتن کد شروع می‌کنند؛ ایشان چنین کدهایی را Test Case می‌نامند که به‌ منظور شبیه‌سازی سناریوهای مختلف نوشته می‌شوند. در نهایت، کدی روی سرور دیپلوی خواهد شد که تمام سناریوهای مختلف روی آن تست شده و نتیجۀ مطلوب حاصل شده باشد.

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

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

همچنین اگر هزینۀ اجرای برنامه‌ها را در نظر بگیریم، هر برنامه برای اجرا نیاز به منابع سیستمی دارد و برخی از این برنامه‌ها تا مدت‌ها منابع مورد استفاده را آزاد نمی‌کنند! مهندسان نرم‌افزار برنامه‌هایی کارآمد خواهند نوشت که از منابع کامپیوتری، استفاده‌های غیرضروری نمی‌کنند. به‌ عنوان‌ مثال، ذخیرۀ داده‌ها در حافظۀ کَش (داده‌هایی که بسیار مورد استفاده قرار می‌گیرند) یک استراتژی است که در اینجا می‌تواند مثمرثمر باشد؛ اما این شاید تنها یکی از هزاران ابزار و تغییراتی است که می‌تواند اجرای برنامه را سریع‌تر و کارآمدتر سازد.

یک دولوپر تازه‌کار ممکن است راه‌حل کم‌ارزشی به شما پیشنهاد دهد و اجرای چنین راه‌حلی احتمالاً هزینه‌های زیادی برای شما و همچنین مشتریان‌تان داشته باشد، اما این در حالی است که اولین کاری که یک دولوپر باتجربه انجام می‌دهد این است که یک راه‌حل کارآمد را به شما پیشنهاد خواهد داد.

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

- فرم‌های لاگین: فرم‌هایی را که برای دریافت داده‌های کاربران مانند آدرس ایمیل ایشان طراحی می‌شوند را در نظر بگیرید؛ یک برنامه با طراحی خوب چند ویژگی‌ دارا است از جمله اینکه بزرگی یا کوچکی حروف را نادیده می‌گیرد، اسپیس‌های اضافی بین کلمات را حذف می‌کند یا به دلیل روشن بودن کلید Caps Lock کاربر، به وی سخت نمی‌گیرد همچنین این اپلیکیشن در صورتی که آدرس ایمیل جدید را قبول کرد، بلافاصله یک ایمیل تأییده ارسال می‌کند تا اگر کاربر سهواً ایمیل خود را اشتباهی وارد کرده، متوجه شود (مثلاً ممکن است کاربر فراموش کرده‌ باشد علامت @ در آدرس ایمیل خود درج کند یا به جای com نوشته باشد ocm.)

- فرایند ریدایرکت کردن: هنگامی که کاربر به لینک جدیدی برای انجام کاری هدایت (ریدایرکت) می‌شود، یک برنامۀ خوب مهندسی شده، لینک اصلی کاربر را ذخیره می‌کند تا زمانی که کار وی انجام شد، مجدد او را به لینک و مکان اولیه هدایت کند. همچنین یک برنامۀ خوب می‌تواند هرگونه اطلاعات و تعاملاتی که قبلاً کاربر انجام داده بود را به خاطر داشته باشد تا در صورت نیاز، بتواند آن‌ها را در گام‌های آیندۀ مرتبط با گام‌های قبلی، بازیابی کرده و در اختیار وی قرار دهد. مثلاً فرض کنید که به عنوان یک کاربر در وب‌سایت Expedia و در لیست پروازها جستجوهایی انجام داده‌اید؛ سپس تصمیم گرفتید یک اکانت برای خود ایجاد کنید. تمام جستجوهای قبلی شما باید در اکانت جدید ذخیره شود، در این صورت شما می‌توانید از دیوایس‌های کاملاً متفاوت نیز به آن‌ها دسترسی داشته باشید.

- خود را جای کاربر قرار دهید: یک برنامۀ خوب با در نظر گرفتن انواع و اقسام کاربر هدف طراحی می‌شود. خودتان را به‌ جای کاربران‌تان قرار دهید و صرفاً یکسری فیچر به اپلیکیشن خود اضافه نکنید! فرض کنید شما یک بلیط هواپیما در یک آژانس مسافربری را رزرو می‌کنید اما فراموش می‌کنید شمارۀ پرواز خود را مشخص کنید. پس از تأییدیۀ رزرو، به وب‌سایت این آژانس مراجعه می‌کنید تا شمارۀ پرواز خود را در فرم مربوطه اضافه کنید. اگر وب‌سایت به‌ خوبی طراحی نشده باشد، چند دقیقه‌ای طول خواهد کشید تا شما فیچر مد نظر را پیدا کنید. در واقع، لینکی برای دستیابی به آن وجود ندارد، بنابراین مجبور می‌شوید تمام لینک‌هایی که به این فیچر منجر می‌شوند را مجدد باز کنید. ممکن است وقتی صفحۀ مورد نظر را یافتید، در اولین بار نتوانید آن فیچر را ببینید به این دلیل که در داخل فرمی بزرگ گم شده است و قابل‌روئیت نیست. این یک نمونه از برنامه‌ای است که با تفکر از نقطه‌نظر کاربر طراحی نشده است (در همین راستا، توصیه می‌کنیم به مقالهٔ Design Thinking چیست؟ مراجعه نمایید.)

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

برخی کاربران، نرم‌افزار را با ورودی‌های بد یا اشتباه مورد استفاده قرار می‌دهند. بعضی از آن‌ها عمداً تلاش خواهند کرد که به نرم‌افزار آسیب برسانند و آن را هَک کنند. لازم به ذکر است که مسائل امنیتی تنها به ورودی‌های بد و مخرب محدود نمی‌شوند، گاهی‌اوقات ورودی‌های معمولی نیز می‌توانند تأثیری مخرب بر امنیت داشته باشند. برای مثال، فرض کنید که کاربری رمزعبور خود را فراموش می‌کند؛ در این صورت می‌توان سناریوهای زیر را در نظر گرفت:
- چند بار می‌تواند آن را امتحان کند؟
- آیا پس‌ از چند بار تلاش، اکانت وی قفل خواهد شد؟
- اگر شخص دیگری سعی کند اکانت کاربری را قفل کند چه‌طور؟
- آیا شما به عنوان مهندس نرم‌افزار اجازه می‌دهید که کاربران رمزعبور خود را از طریق یک کانکشن رمزگذاری نشده ارسال کنند؟
- اگر کاربری سعی در ورود به یک اکانت از یک مکان غیرعادی را داشت چه کاری انجام می‌دهید؟
- اگر یک لاگین خودکار انجام شود، چه کاری انجام می‌دهید؟
-برای محافظت از کاربران خود در مقابل حملاتی مانند XSS ،Man In The Middle و Social Phishing چه کاری انجام می‌دهید؟
- آیا یک استراتژی بکاپ دارید که اگر مثلاً یک حملهٔ DDoS روی سرورهای خود داشتید، بتوانید اطلاعات را بازیابی کنید؟

این سؤالات فقط چند نمونه از برخی نگرانی‌های موجود برای نرم‌افزارها است که باید برای آن‌ها پلنی تعریف شود (به‌ طور خلاصه، Man In The Middle حمله‌ای است که مهاجم به‌ طور مخفیانه وارد کانکشن گیرنده و فرستنده می‌شود و احتمالاً ارتباط بین دو طرف را تغییر می‌دهد بدین منظور که به دیتای ارسال شده بین گیرنده و فرستنده دسترسی یابد و این در حالی است که دو طرف معتقدند که آن‌ها به‌طور مستقیم با یکدیگر ارتباط دارند. Social Phishing هم حمله‌ای در تلاش برای به دست آوردن اطلاعات حساس کاربران مانند نام‌کاربری، رمزعبور و جزئیات کارت اعتباری (و پول) ایشان است که اغلب با پنهان‌سازی خود به عنوان یک هویت قابل‌اعتماد در ارتباطات الکترونیکی، حمله صورت می‌گیرد. نام‌گذاری این نوع حملات به دلیل شباهت استفاده از طعمه در تلاش برای گرفتن قربانی صورت است.)

برنامه‌های ایمن هرگز اطلاعات حساس خود را به‌ صورت اصطلاحاً Clear Text (متن خوانا) ذخیره نمی‌کنند، بلکه به‌ صورت داده‌های رمزگذاری شدهٔ یک‌طرفه (یعنی داده‌هایی که رمزگذاری آن آسان بوده ولی فرآیند معکوس آن یا رمزگشایی داده‌ها بسیار سخت است) ذخیره می‌کنند؛ برای این منظور هم از الگوریتم‌هایی که شکستن رمز داده‌ها در آن‌ها سخت است، استفاده می‌کنند.

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

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

استقبال از ابزارهای مختلف
شکی نیست که مهندسین نرم‌افزار برای حل مسائل نیاز به ابزارهای بیشتر و بهتری دارند. استفاده از این ابزارها نتایج متفاوتی را در حل مشکلات خواهند داشت و اغلب مهندسین نرم‌افزار نیز از این ابزارها استقبال می‌کنند.

مثلاً شرایطی را تصور کنید که هنوز ابزارهایی بهتر از پروتکل‌هایی همچون FTP برای دیپلوی فایل‌ها روی سرور وجود نداشت یا برای دیباگ کردن خطاها و عملکرد شبکه، ابزارهایی همچون Chrome DevTools موجود نبود! درک و بهبود ابزارها یکی از راه‌های رسیدن به آینده‌ای روشن است چرا که ابزارهای بهتر به شما کمک می‌کنند تا شما به یک دولوپر بهتر مبدل گردید. این ابزارها را پیدا کرده و از آن‌ها استفاده کنید و در صورت امکان -و چنانچه اپن‌سورس بودند- آن‌ها را بهبود بخشید.

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

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

به عنوان یک قانون کلی، بدون وجود قابلیت ‌استاتیک‌ تایپ در سیستم، نرم‌افزاری را کدنویسی نکنید. اگر زبان انتخابی شما دارای این قابلیت نیست، زبان برنامه‌نویسی خود را عوض کنید یا یک Transpiler برای آن پیدا کنید. بدین ترتیب، در آینده با استفاده از چنین ابزارهایی می‌توان عمل Type Checking را به زبان‌های نیتیوی که این قابلیت را ندارند، افزود (Transpiler یا Transcompiler یک نوع کامپایلر است که سورس‌کد نوشته شده با یک زبان برنامه‌نویسی را به عنوان ورودی دریافت کرده و سورس‌کد معادل آن را در یک زبان برنامه‌نویسی دیگر تولید می‌کند.)

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

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

منبع


اکرم امراه‌نژاد