نکته: وظیفه نوشتن کدهای تست برای Unit Testing بعهده فرد برنامه نویس هستش نه فرد Tester. زیرا:
- بدلیل حفظ مالکیت کدها/پروژه، Tester نباید به سورس پروژه دسترسی داشته باشه.
- بدلیل مسایل امنیتی و کاهش تهدیدها، Tester نباید به داخل کدها و مکانیزم سیستم دسترسی داشته باشه.
- همچنین Tester قادر نیست به همه ابزارها، سبکها و زبانهای مختلفی که در پروژه استفاده شده مسلط بشه و test case طراحی کنه.
- تنها برنامه نویس هستش به کدهایی که پیاده سازی کرده مسلطه و test case رو در کمترین زمان با بالاترین کیفیت تولید میکنه.
مقایسه پرفورمنس(startup, rendering, event handling):
Windows platform FLTK > wxWidgets > GTK > Qt Linux platform FLTK > GTK > (wxWidgets / Qt)
نکته: در اینجا منظور از GTK نسخه GTKmm هستش که wrapper/مخصوص ++C هستش.
نکته 2: عناصر کتابخانه wxWidgets صددرصد native هستن. اما عناصر کتابخانه FLTK و Qt و GTK فقط "شبیه" به native هستن. که برای این شبیه سازی از CSS و API های theming سیستم استفاده می کنن.
این توضیحات رو هم در نظر بگیرید:
- کتابخانه FLTK از نظر استایل بهترین گزینه برای لینوکس با محیط EDE هستش. از نظر فضای دیسک، بسیار کم حجم هستش. پرفورمنس بالاتری نسبت به بقیه کتابخانه ها داره. استفاده ازش آسون هست. از بعضی دیگر زبانهای برنامه نویسی هم پشتیبانی میکنه. در ویندوز برروی WinAPI، در لینوکس برروی X Window و در مک بر روی Quartz سوار هست. FLTK بعضی از widget های مدرن مثل Treeview رو نداره. بعضی از widget ها حالت RTL (راست به چپ) رو ندارن.
- کتابخانه wxWidgets از نظر استایل بهترین گزینه برای ویندوز و مک و لینوکس هستش. از نظر فضای دیسک، حجیم هستش. یادگیری و استفاده ازش کمی سخته. UI designer هم داره. از خیلی زبانهای برنامه نویسی پشتیبانی میکنه. در لینوکس بر روی کتابخانه GTK قرار داره و در پشت پرده از API های GTK استفاده میکنه. wxWidgets فقط کتابخانه GUI نیست، یک فریم ورک محسوب میشه.
- کتابخانه GTK از نظر استایل بهترین گزینه برای لینوکس با محیط Cinnamon, GNOME, XFCE یا Mate هستش. یادگیری و استفاده ازش آسونه. UI designer هم داره. از خیلی زبانهای برنامه نویسی پشتیبانی میکنه.
- کتابخانه Qt از نظر استایل بهترین گزینه برای لینوکس با محیط KDE, TDE یا LXQt هستش. از نظر فضای دیسک، حجیم هستش. یادگیری و استفاده ازش بواسطه Qt Creator آسونه. UI designer هم داره. از خیلی زبانهای برنامه نویسی پشتیبانی میکنه. امکانات غیر استاندارد هم داره(meta-object). طیف گسترده تری از platform ها رو در بر گرفته. Qt فقط کتابخانه GUI نیست، یک فریم ورک هستش. برای پروژه های غیر opensource باید لایسنس داشته باشید. از مدل برنامه نویسی reactive پشتیبانی می کنه. (به کمک شتابدهنده گرافیکی میشه بار سنگین رندر رو از روی پردازنده برداشت، بنابراین باعث افزایش پرفورمنس میشه)
💡 مقایسه سرعت الگوریتم binary search مقابل الگوریتم linear search برای آرایه های مرتب شده(sorted)
(برای آرایه های عددی سنگین)
$needle = range(1, 500000);
❌ Linear search algorithm
function search(array $numbers, $needle) { $_totalItems = count($numbers); for ($i = 0; $i < $_totalItems; $i ++) { if ($numbers[$i] === $needle) { return TRUE; } } return FALSE; }
📊 نتیجه(ms)
0.031199932098389
0.031199932098389
0.031199932098389
0.031199932098389
0.031199932098389
0.031199932098389
0.031200170516968
0.031200170516968
0.046799898147583
0.046800851821899
✅ Binary search algorithm
function search(array $numbers, $needle) { $_low = 0; $_high = count($numbers) - 1; while ($_low <= $_high) { $_middle = (int) (($_low + $_high) / 2); if ($numbers[$_middle] > $needle) { $_high = $_middle - 1; } else if ($numbers[$_middle] < $needle) { $_low = $_middle + 1; } else { return TRUE; } } return FALSE; }
📊 نتیجه(ms)
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
x64 Hardware
32bit OS
PHP 5.6 CLI
کد از کتاب "PHP 7 Data Structures and Algorithms"
Virtual File System یا سیستم فایل مجازی
Virtual File System(مخفف VFS) یک ساب سیستم مهم در Kernel لینوکس هست که لایه بین filesystem و برنامه های user-space رو تشکیل میده. درواقع همه filesystem ها، با تکیه بر VFS می تونن شناسایی بشن و تبادل اطلاعات کنن. همین مسئله، برنامه های user-space رو قادر کرده که توسط دستورات موجود در VFS برای خواندن و نوشتن در filesystem های گوناگون اقدام کنن:
نکته: در اینجا منظور از لایه، همون Abstraction layer و منظور از دستورات، همون System call/SysCall هستش.
نکته 2: البته به برکت wrap های GNU C Library، کمتر پیش میاد که برنامه user-space نیاز به استفاده از System call داشته باشه.
ماژول، قطعه ی نرم افزاری در بخشی جدا از Core هسته هستش که هنگام فراخونی شدن، پیوند و فعال میشه و یکسری عملیات تعریف شده ای رو انجام میده.
این ماژول می تونه سرویس باشه، filesystem باشه، پروتکل شبکه باشه، تعدادی System call باشه و یا درایور یک سخت افزار باشه; که در هر صورت ماژول نام داره.
ماژول ها در لینوکس به دو گروه تقسیم میشن:
Built-in kernel module: که با قرار دادن سورس ماژول در داخل پوشه های سورس Kernel، همراه با Kernel کامپایل میشه.
Loadable Kernel module: که با load کردن ماژول کامپایل شده در داخل سیستم در حال اجرا فعال میشه.
در این مقاله برنامه نویسی هسته لینوکس رو بررسی می کنیم
ابتدا برخی از اصول سیستم عامل و هسته لینوکس(از جمله Version های هسته، دانلود سورس، ساختمان دایرکتوری سورس، چگونگی نصب، Patch کردن، پیکربندی و Compile) رو معرفی می کنم و بعد به مباحث پیشرفته و برنامه نویسی می پردازم.
در این بین از کتابهای Advanced Linux programming، Linux Advanced Administration و Linux Kernel Development هم بهره ای می گیرم.
فهرست مندرجات
ExeStrip
این برنامه Header/Stup
[داس] رو از فایل های Exe جدا می کنه.
BootSectorWriter
این برنامه 512 بایت از داده یا فایل رو روی سکتور بوت Write می کنه. (هارددیسک و فلاپی دیسک)
وقتی برنامه ای را تایپ می کنید، یک فایل سورس(Source) ایجاد می کنید. یعنی صفحه ای با متونی شبیه به زبان لاتین که فقط برنامه نویس متوجه آن خواهد شد. این صفحه کاری نمی کند و کامپیوتر هم متوجه محتوای آن زبان نمی شود. باید پردازش و عملیاتی(از قبیل ترجمه) انجام گیرد تا این صفحه تبدیل به زبانی شود که کامپیوتر بتواند آنرا درک کند و برنامه قابل اجرایی را تولید کند(مانند فایلهای سیستم).
اولین مرحله در پردازش(ایجاد برنامه)، استفاده از ویرایشگر متنی برای نوشتن کدهای C++ می باشد. شما فایل Source رو به زبان C++ که شبیه به معماری کامپیوتر هست می نویسید(به لاتین). بعد باید آنرا به زبان و دستورالعمل های ماشینی(Machine language) تبدیل کنید که این کار بعهده کامپایلر می باشد. کامپایلر برای اینکار عملیات زیر را انجام می دهد:
(برای درک بهتر این موضوع، بر روی یک کامپایلر Open source(منبع باز/متن باز) کار کنید)
ابتدا فایل سورس(Source) خوانده می شود و به تعدادی علایم پیش پرازش(Preprocessor token
)(عناصری که کامپایر می تواند با آنها کار کند. مثل عمگر ها، ثابتها، کلمات کلیدی و...) و کاراکتر های سفید(Blank)(شامل فضاهای خالی، Tab ها و Comment ها) تبدیل می شود. در این مرحله کاراکتر های ویژه(Special) تبدیل می شوند و عبارات جدا که دو یا چند خط اشغال نمودند به یکدیگر پیوند می خورند.
سپس دستورات پیش پردازنده(#
دار ها) اجرا می شوند. این دستورات شامل include, define if
و... می باشد. در این مرحله تمامی دستوات و ماکروها Expand می شوند و عملیات و ضمیمه های لازم انجام می گیرد.
بعد پردازش کاراکترها و رشته ها انجام می گیرد. در این مرحله برنامه برای صحت شکل گرامری(Syntax) و لغات، تجزیه و تحلیل می شود(خطاها و هشدارهای Syntax در این مرحله نمایان می شود). اگر اشتباهات مهلک(Fatal) پیدا نشود، یک فایل تجزیه/تحلیل شده(معمولاً با پسوند obj) تولید می شود، تا با بقیه فایل ها ترکیب شود.
دستور پیش پردازنده #include
در هر لحظه می تواند چندین فایل را داخل برنامه ادغام(Merge) کند. و هر بار که کامپایلر به این دستور برخورد می کند، به اندازه محتوایش موقتاً پردازش را متوقف(Halt) می کند. (همینکار رو زبان های دیگه مثل PHP, C# , Python, PERL و... انجام می دهند)
در آخرین مرحله(ایجاد برنامه قابل اجرا)، پردازش فایل تولید شده(obj) توسط یک پیوند دهنده(Linker یا Link) انجام می شود. اکثر برنامه ها دارای رجوعاتی به روتین(Routine) می باشند که در خارج از برنامه جاری وجود دارند. این روتین ها باید آدرس یابی و به برنامه شما اتصال داده شوند تا بتوان با آنها کار کرد.
پیوند دهنده(Linker) تمامی فایلها را با هم ترکیب می کند و در نتیجه یک برنامه قابل اجرا تولید می شود.
لازم بذکر هست که تمامی این مراحل توسط کامپایلر انجام می شود. و شما فقط کد نویسی می کنید و بعد با یک کلیک بر روی Build/Make برنامه را تولید می کنید. (در کامپایلرهای GUI)