بایگانی نویسنده: Sina

تجربه من از محیط کار Unity و KDE

لینوکس معروفه به سیستم عاملی که شما می‌تونید داخل اون کاپوت رو بزنید بالا و خودتون سیستم رو دستکاری کنید. این یکی از دلایلی هست که لینوکس رو به عنوان اولین انتخاب برای من تبدیل می‌کنه.
توی توزیع های مختلف لینوکسی، اوبونتو رو من استفاده می‌کنم به خاطر جامعه‌ی بزرگی که پشتش هست در نتیجه توش کمتر به مشکل می‌خورم و اگر هم چیزی بخوام سریع می‌تونم برطرفش کنم.
از دلایل دیگه ‌ای که اوبونتو رو استفاده می‌کنم سازگاری اون با کارت گرافیک NVIDIA هست که روی سیستمم دارم .
قبلا توزیع های دیگه ای مثل fedora، suse و … رو هم امتحان کردم ولی در نهایت اوبونتو روی سیستم من بهتر جواب می‌داده.

توی سایت اوبونتو قسمتی هست به نام Flavours که اجازه میده اوبونتو رو با محیط گرافیکی مختلف و با نرم‌افزار های پیشفرض مختلف داشته باشیم .
من همیشه اوبونتو پیشفرض که با محیط unity هست رو استفاده می‌کردم ولی ایندفعه توزیعی رو به نام kubuntu نصب کردم.
همونطور که از اسمش احتمالا حدس میزنید محیط گرافیکیش KDE هست و نرم‌افزار های پیشفرض خودش رو داره

توی این پست در مورد تجربه خودم داخل این دو محیط می‌نویسم و این که من کدوم رو ترجیح میدم. شاید توی پست های بعدی هم در مورد I3 که یک مدیر پنجره هست هم بنویسم و در مورد اون هم نظر و تجربه ام رو بگم.

مزیت ها و معایب Unity

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

در کل می‌تونم بگم که این محیط خیلی ساده و معمولیه. در کمتر از ۱۰ دقیقه می‌تونید تمام تنظیمات و محیط گرافیکی سیستم رو ببینید و امتحانش کنید.
به شکل پیشفرض امکان گرافیکی خاصی مثل انیمیشن یا شخصی سازی بهتون نمیده و شاید خفن ترین کاری که می‌شه داخلش انجام داد تغییر تم باشه.
البته اینم بگم که با نصب کردن برنامه هایی مثل tweak tool و یا تغییراتی که مستقیم توی فایل های کانفیگ میدید می‌تویند تغییراتی که میخواید رو بوجود بیارید.

مزیت ها و معایب KDE

محیط KDE نسبت به Gnome و Unity سابقه بیشتری داره و در سال 1996 ساخته شده.
مثل محیط های گرافیکی دیگه یک نوار ابزار داره که به شکل پیشفرص پایین صفحه قرار داره اما خودتون می‌تونید اون رو به هر طرف که می‌خواید منتقل کنید. من ترجیح میدم که بالا‌ی صفحه باشه.
داخل این نوار هم می‌تونید widget هایی که میخواید رو اضافه کنید مثلا من دو تا ویجت رو که ترجیح میدم داشته باشم رو اضافه کردم . یکی وضعبت کارت شبکه رو نشون میده و اون یکی هم وضعیت cpu رو .
اگر دکمه windows رو که ما توی لینوکس بهش میگیم super فشار بدید یک منو شبیه start ویندوز باز میشه که میتوندی داخل اون لیست برنامه ها و یا امکانات دیگه مثل خاموش کردن و خروج سیستم و …چیز های دیگه رو ببینید.
محیط KDE نسبت به Unity امکانات گرافیکی بیشتری بهتون میده. توی قسمت تنظیمات این سیستم تقریبا میتونید هر چیزی رو شخصی سازی کنید حتی شکل صفحه لاگین به سیستم و یا splash screen (صفحه ای که موقع لود شدن سیستم نشون داده میشه و لوگوی سیستم عامل رو داره).
تکرار می‌کنم که این کار ها توی محیط Unity هم شدنی هست اما برای این کار مستقیما باید فایل ها کانفیگ رو دست کاری کنید و از داخل منو ها و محیط گرافیکی این امکان رو ندارید.

به نظر من یکی از مزیت هایی که توی KDE هست شکل مدیریت کردن پنجره ها و فضا‌ی کاری یا همون work space هست.
توی KDE شما میتونید هر چنتا که میخواین work space بسازید. هر work space رو مثل یک کامپیوتر جدا در نظر بگیرید که پنجره های کاملا متفاوتی نسبت به بقیه work space ها می‌تونه داشته باشه .مثلا توی تصویر بالا من دو تا work space دارم که یکیش مربوط به کار های شرکته و اون یکی هم مربوط به کار های شخصی خودمه . هر کدوم از این work space ها هم 8 تا virtual desktop دارن.

KDE یا Unity ?

من جواب دقیق به این سوال نمی‌تونیم بدم و این کاملا سلیقه ای محسوب میشه. هر دوشون کارایی و سرعت خوبی دارن و بدون مشکل می‌تونید باهاشون کار کنید.
انتخاب من در حال حاضر KDE هست اون هم به خاطر اینکه میذاره پنجره هام رو راحت تر مدیریت کنم.
اگر توی انتخاب این دوتا محیط شک دارید بهترین راه تست کردن و تجربه ای هست که از این محیط ها بدست میارید . پیشنهاد میکنم روی ماشین مجازی هر دو محیط رو تست کنید و بعد محیط سیستم اصلیتون رو انتخاب کنید.
من فعلا از KDE استفاده می‌کنم و راضی هستم. البته محیط های دیگه مثل XFCE و LXDE و خیلی محیط های دیگه هم هستن که میتونید اون ها رو هم تست کنید.
از خوبی های لینوکس میشه به همین تفاوت ها اشاره کرد که دست کاربر رو باز میذاره تا اون چیزی رو که خودش می‌خواد داشته باشه و در آخر این جمله از کتاب انسان خردمند رو یاد آوری میکنم که تکامل نتیجه تفاوت هاست.

پلاگین Time Tunnel برای وردپرس

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

اسم پلاگین TimeTunnel هست و اگر از وردپرس برای مدیریت وبلاگتون استفاده می‌کنید پیشنهاد می‌کنم که نصبش کنید.
این پلاگین کمک می‌کنه پست هایی که به خاطر گذر زمان فراموش شدن دوباره بالا بیان و فرصت دوباره خونده شدنشون فراهم بشه

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

git logo

معرفی سایت oh shit git

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

git logo


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

نویسنده وبسایت oh shit git اومده چنتا از مشکلاتی که معمولا توی کار با گیت پیش میان رو اونجا نوشته و راه حل شون رو هم گفته.
نگاه کردنشون جالبه، شاید روزی مشکلی رو حل کنند

Arpanet پدربزرگ اینترنت فعلی

Arpanet اولین شبکه پکت سوئیچ گسترده، که به شکل توزیع شده کنترل می‌شد و جزو اولین شبکه هایی بود که از tcp/ip استفاده می‌کرد.
این شبکه توسط آرپا (ARPA) که میشه Advanced Research Projects Agency که زیر مجموعه ای از سازمان دفاع آمریکا محسوب میشه بوجود اومد و به مرور بزرگ شد تا تبدیل شد به اینترنتی که امروز داریم.
توی عکس های زیر می‌تونید مراحل تبدیل شدن یک ایده‌ی ساده و اولیه و تبدیل اون به شبکه آرپا رو ببینید. اگر عکس های بیشتر رو می‌خواید به اینجا سر بزنید.

ARPANET in 1969

ARPANET in 1977

چرا من از لینوکس استفاده می‌کنم : اتوماتیک کردن کارهام

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

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

کاری که می‌خوام بکنم این هست که به شکل خودکار هر هفته روز های یکشنبه ساعت ۸ شب که تقریبا مطمئنم سیستمم روشنه یک ایمیل برام بیاد که رزرو غذا رو بهم یاد آوری کنه. البته اگر سیستمم هم خاموش باشه مشکلی نیست و راه حلش استفاده از anacron هست ولی من اینجا از اون استفاده نمی‌کنم

برای این کار به دوتا چیز نیاز دارم :
۱- اول اینکه بتونم یک ایمیل ارسال کنم
۲- بتونم این کار رو به شکل خودکار توی ساعت و روز خاصی انجام بدم

برای مورد اول از ترمینال لینوکس استفاده می‌کنم و با استفاده از آدرس ایمیل خودم به خودم ایمیل می‌زنم . اگر نمی‌دونید که چطوری از ترمینال ایمیل بفرستید کافیه مراحلی که اینجا گفته شده رو دنبال کنید .
برای قسمت دوم هم از cron job داخل لینوکس استفاده می‌کنم
cron job ها داخل لینوکس این امکان رو به ما میدن که بتونیم یکسری کار ها رو داخل زمان های مشخصی به شکل schedule انجام بدیم مثلا بهش بگیم که هر هفته ساعت ۲ شب که همه خوابن یک بکاپ از سیستم بگیر و اون رو روی هارد فلان با اسم و تاریخ فلان ذخیره کن.

خب اول یک برنامه یک خطی می‌نویسم و توی فایلی به نام food_reserve.sh ذخیره می‌کنم
کد برنامه میگه که یک ایمیل با متن reserve your food otherwise you have egg و موضوع Reserve Food برای ایمیل من که sinasoheili79[at]gmail.com هست ارسال کن

#!/bin/sh

echo "reserve your food otherwise you have egg" | mail -s "Reserve Food" sinasoheili79@gmail.com

حالا باید به cron بگیم که این فایل رو هر یکشنبه ساعت 8 شب که میشه ساعت 20 اجرا کن . برای این کار دستور crontab -e رو اجرا میکنم و محتوای فایلی که باز میشه رو به شکل زیر تغییر میدم

# m h  dom mon dow   command
  0 20   *   *   0    ~/bin/./food_email.sh

اگر براتون سوال هست که چرا مقدار dow رو 0 گذاشتم دلیلش این هست که خارجی ها روز اول هفتشون دو شنبه هست و توی کامپیوتر ما از 0 شروع می‌کنیم به شمردن پس روز یکشنبه رو باید 0 در نظر بگیریم. اگر برای مشخص کردن زمان داخل crontab شک دارید می‌تونید از این استفاده کنید.

پی‌نوشت : مسلما راه های ساده‌تری مثل استفاده از تقویم یا برنامه های reminder هم هست ولی من ترجیح میدم از این روش استفاده کنم چون باعث میشه با پیاده کردن همین برنامه ساده چیز های جدید یادبگیرم


حمله درب پشتی از طریق کامپایلر

حمله‌ی درب پشتی از طریق کامپایلر یا Compiler backdoor attack یکی از حمله هایی است که هنوز به شکل رسمی روشی برای جلوگیری از آن معرفی نشده است
توی این پست روش کار این حمله رو توضیح میدم و سعی میکنم اون رو برای کامپایلر زبان C پیاده کنم.

معرفی

کن تامسون، برنامه نویس سیستم عامل یونیکس در سال 1984 در مراسم Turing Award داخل سخنرانیش حمله درب پشتی از طریق کامپایلر رو معرفی و در موردش صحبت می‌کنه.
در سال 2015 نرم افزار XcodeGhost که برای ساخت برنامه های شرکت اپل از اون استفاده می‌شده از همین تکنیک استفاده می‌کرده و گفته میشه که این اولین حمله در مقیاس بزرگ برای اپ استور اپل بوده و باعث شده بیش از 4000 برنامه داخل فروشگاه اپل آلوده بشه.
همانطور که از اسم حمله هم مشخصه، کامپایلر شما زمانی که می‌خواهد کد شما رو کمپایل کنه بدون سر و صدا یک در پشتی رو داخل کد های شما ایجاد میکنه
شما هم که از این درب پشتی خبر ندارید پس برنامه خودتون رو منتشر می‌کنید و این شروع ماجراست. .

چرا این حمله مهمه ؟

برای جواب دادن به این سوال نیاز هست که کمی عمیق تر به مشکل نگاه کنیم.
بذارید اینجوری شروع کنیم که اصلا از کجا می‌تونیم مطمئن باشیم که کامپایلری که الان ازش استفاده می‌کنیم توی برنامه هامون درب پشتی درست نمیکنه ؟
احتمالا جواب این هست که خب کد های مربوط به کامپایلر به شکل open source هست و اگر چنین مشکلی وجود داشته باشه حتما هستند کسایی که اون کد رو بخونن و متوجه چنین مشکلی بشن.
حالا سوال جدید این هست که اگر فرض کنیم کد مربوط به کامپایلر منبع باز باشه و کسی هم باشه که اون کد رو کنترل کنه و بخونه، کد مربوط به خود کامپایلر نیاز داره که توسط یک کامپایلر دیگه کامپایل بشه و ما چطوری می‌تونیم مطمئن بشیم که اون کامپایلر، درب پشتی رو داخل کامپلر اول ایجاد نمی‌کنه ؟
ممکنه بگید که خب می‌تونیم از یک disassembler استفاده کنیم و چک کنیم که فایل های اجرایی کامپایلر ما کد مخربی داخلشون نباشه.
اما این روش هم جوابگو نیست چون disassembler هم در نهایت یک برنامه است و ممکنه خود این برنامه هم رفتار بدی از خودش نشون بده و زمانی که می‌خواهد کد های مربوط به کامپایلر رو برای ما ایجاد کنه، کد های بد رو در داخل سورس کد مخفی کنه و نمایش نده.
ممکنه دوباره در جواب بگید که خب این روش خیلی سخته و ممکنه اصلا کسی سراغ عملی کردن این مسئله نره و در جواب باید بگم که ساخت این کامپایلر خیلی ساده تر از اون چیزی هست که فکر می‌کنید و در ادامه نشون میدم که چطور توی کمتر از ۱۰۰ خط کد این کامپایلر رو میشه ساخت.

ساخت کامپایلر

برای نشان دادن این حمله من از این ریپوزیتوری استفاده می‌کنم.
برای شروع بیاید نگاهی به فایل Login.cpp بندازیم. توی این فایل برنامه ی ساده ای هست که میگه اگر کاربر رمز ورود رو test123 بزنه می‌تونه وارد بشه

#include <iostream>

using namespace std;

int main() {
    cout << "Enter password:" << endl;
    string enteredPassword;
    cin >> enteredPassword;
    if(enteredPassword == "test123")    
        cout << "Successfully logged in as root" << endl;
    else
        cout << "Wrong password, try again." << endl;
}

حالا بیایید این برنامه رو با استفاده از کامپایلری که داریم کامپایل کنیم. پس داخل ترمینال کد زیر رو می‌زنیم

./Compiler Login.cpp -o Login

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

#include <string>
#include <cstdlib> 

using namespace std;

int main(int argc, char *argv[]) {
    string allArgs = "";
    for(int i=1; i<argc; i++)
        allArgs += " " + string(argv[i]);
    string shellCommand = "g++" + allArgs;
    system(shellCommand.c_str());
}

همونطور که داخل کد هم مشخصه این کد از کامپایلر ++g استفاده ‌میکنه و فایل ما رو کامپایل می‌کنه
توی این کد هم مشکلی نیست پس چطوری این درب پشتی به کد ما اضافه می‌شه.

قبل از اینکه در مورد اضافه شدن درب پشتی به کد حرف بزنم خوبه که با اصطلاح self-hosting آشنا بشیم
اگر دفت کرده باشید کد کامپایلر ما خودش به زبان C نوشته شده و فایل اجرایی کامپایلر ما می‌تونه فایل برنامه خودش رو هم کامپایل کنه.
مثلا داخل کد زیر من کد برنامه کامپایلرم رو با فایل اجرایی همون کامپایلر، کامپایل می‌کنم.

./Compiler Compiler.cpp -o newCompiler

این به این معنا هست که برای کامپایل کردن سورس کد ورژن جدید کامپایلرمون می‌تونیم از ورژن های قبلی خودش استفاده کنیم.
زبان های دیگه ای هم مثل C++ ، Java و یا python هم این ویژگی رو دارند
جلوتر در مورد اینکه این ویژگی چه تاثیری داره صحبت می‌کنم اما حالا بیایید در مورد اینکه درب پشتی چطور به کد اضافه می‌شه صحبت کنیم.
زمانی که شما فایل Login.cpp رو کامپایل می‌کنید اتفاق های زیر داخل کامپایلر می‌افته:
1- فایل Login.cpp داخل یک فایل موقت به نام LoginWithBackdoor.cpp کپی می‌شود.
2- فایل LoginWithBackdoor.cpp به اون شکلی که می‌خوایم اصلاح میشه. مثلا یک کلمه عبور جدید به اون اضافه می‌شه.
3- فایل LoginWithBackdoor.cpp به جای فایل Login.cpp کامپایل میشه
4- در نهایت فایل LoginWithBackdoor.cpp پاک میشه
اگر به فایل EvilCompiler.cpp نگاه کنیم می‌تونید این مراحل رو ببینید

اما کسی از این کامپایلر استفاده نمی‌کنه چون با خوندن سورس کد ‌مربوط به EvilCompiler.cpp متوجه این مشکل می‌شه پس باید راهی پیدا کنیم که این مشکل رو هم حل کنه. برای حل این مشکل از self-hosting استفاده ‌می‌کنیم.

مخفی کردن ساخت درب پشتی در کامپایلر

فرض کنید کسی برای اطمینان از درست عمل کردن کامپایلر، سورس کد های کامپایلر را دانلود کند و بخواهد خودش آن را کامپایل و از ان استفاده کند.
در این حالت اگر سورس کد EvilCompiler.cpp رو به کاربر بدیم ، کاربر متوجه حمله ما میشه و اگر سورس کد Compiler.cpp رو به کاربر بدیم دیگه درب پشتی به وجود نمیاد

برای رفع این مشکل باید از خاصیت self-hosting استفاده کنیم.
کاربر زمانی که می‌خواهد سورس کد کامپایلر رو کامپایل کنه نیاز به یک کامپایلر داره. ما ( در نقش طراح حمله ) می‌تونیم سورس کد Compiler.cpp رو به عنوان اولین کامپایلر ساخته شده برای این زبان به کاربر نشون بدیم ولی فایل اجرایی EvilCompiler.cpp به عنوان اولین کامپایلر به کاربر داده بشه. در نتیجه هر بار که کاربر سورس کد Compiler.cpp رو با این فایل اجرایی کامپایل کنه، همون روش اضافه کردن درب پشتی تکرار می‌شه و درب پشتی به کامپایلر اضافه می‌شه.

عکس زیر کل این روش رو به خوبی نشون می‌ده :

استفاده از هش برای کشف درب پشتی

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

و اما درسی که ما می‌گیریم …

همانطور که دیدید حمله compiler backdoor attack حمله بسیار جالب و هوشمندانه ای محسوب میشه.
اما این حمله دو نکته مهم رو به ما یاد میده :
۱- به هیچ کدی که توسط شما نوشته و ایجاد نشده باشه نمیشه اعتماد کرد
2- هر چه به سمت لایه های پایین تر کامپیوتر ها و برنامه ها پیش میریم پیدا کردن باگ ها و درب های پشتی و .. سخت تر میشه

اگر توضیحات اضافه تری در مورد این حمله می‌خواید می‌تونید به منبع سر بزنید

در نام گذاری از واحد استفاده کنید !!

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

مشکل کجاست ؟
به کد های زیر که به زبان های پایتون، جاوا و هسکل نوشته شدند نگاه کنید.
همه این  کد ها یک کار رو انجام می‌دهند یعنی سیستم رو برای یک مدت زمانی به تعلیق در میارن یا به عبارت دیگه از نظر زمانی توی اجرای برنامه تاخیر ایجاد می‌کنند. ظاهر کد که خیلی خوب و سادس ولی مشکل کجاست ؟‌

time.sleep(300)
Thread.sleep(300)
threadDelay 300


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

راه حل چیه؟

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

def frobnicate(timeout: int) -> None:
    ...

frobnicate(300)


این کد رو بنویسیم

def frobnicate(*, timeout_seconds: int) -> None:
    # The * forces the caller to use named arguments
    # for all arguments after the *.
    ...

frobnicate(timeout_seconds=300)


برای زبان هایی مثل جاوا هم که چنین امکانی رو ندارند میشه به شکل زیر یک متغیر تعریف کرد و واحد رو داخل اون مشخص کرد

sleep_seconds = 300
time.sleep(sleep_seconds)

۲ – استفاده از نوع داده خاص
راه حل اول همیشه جوابگو نیست چون زبان هایی مثل جاوا این امکان رو ندارن که بشه آرگومان ها رو همراه با اسم ارسال کرد. اما می‌تونیم نوع داده های خودمون رو داشته باشیم. مثلا به حای اینکه ورودی تابع من یک عدد int باشه که نشون دهنده زمان هست، ورودی از نوع کلاسی با عنوان TimeUnit باشه که واحد های زمانی رو داخل خوش مشخص میکنه.
یعنی به جای کد زیر

def frobnicate(timeout: int) -> None:
    ...

frobnicate(300)


از این کد استفاده کنیم

def frobnicate(timeout: timedelta) -> None:
    ...

timeout = timedelta(seconds=300)
frobnicate(timeout)


اما مسئله به اینجا ختم نمیشه و این مشکل نه تنها توی برنامه نویسی بلکه جا های دیگه هم وجود داره مثلا فرض کنید که می‌خواهیم با یک api کار کنیم و اون api جواب زیر رو برای ما ارسال می‌کنه.

{
   "error_code": "E429",
   "error_message": "Rate limit exceeded",
   "retry_after": 100,
}



راه حل هایی که گفته شد برای این موارد هم کاربرد داره مثلا برای این مورد می‌تونیم جواب رو به این شکل برگردونیم.

{
   "error_code": "E429",
   "error_message": "Rate limit exceeded",
   "retry_after_seconds": 100,
}


یا مثلا داخل فایل های کانفیگ برنامه ها ممکنه به چنین مواردی بر بخورید

request_timeout = 10



که بهتر هست به یکی از شکل های زیر تغییر کنند

request_timeout = 10s
request_timeout_seconds = 10


در نهایت این رو یادمون باشه که کدی خوبه که آدم های دیگه هم بتونن اون رو بخونن و هر چی کد های ساده تری رو بنویسیم برنامه نویس بهتری هستیم. کد های پیچیده  نوشتن نه تنها خفن بودن آدم ها رو نشون نمیده بلکه باعث میشه کم کم از بازی حذف بشیم و کسی دوست نداشته باشه باهامون کار کنه یا داخل پروژه هامون مشارکت کنه
منبع