بناء البرمجيات من الصفر: مشاريع مفتوحة المصدر لتعلم كيف تعمل الأنظمة فعليًا

مشاركة

قراءة Documentation تعلمك كيف تستخدم أداة، لكن محاولة بناء نسخة صغيرة منها تجبرك على فهم ما يحدث خلف الواجهة: كيف تُخزَّن البيانات، كيف تُحلَّل المدخلات، كيف تتواصل العمليات عبر الشبكة، وكيف تتعامل الأنظمة مع الأخطاء والحالة والموارد.

مطور يعمل على مشروع برمجي من الصفر أمام شاشة تعرض مشروع Build Your Own في بيئة تطوير حقيقية.

هذه هي فكرة مشاريع Build Your Own X: لا تحاول إنشاء بديل Production لـGit أوSQLite أوDocker، بل تختار جزءًا محددًا من النظام وتعيد تنفيذه بحيث يصبح السلوك الداخلي مفهومًا وقابلًا للاختبار.

وتوجد اليوم مجموعات عملية ممتازة لهذا النوع من التعلم، أبرزها مستودع Build Your Own X ومشروع Coding Challenges. هذا الدليل يوضح كيف تستفيد منهما، وما المشاريع التي تستحق أن تبدأ بها، وكيف تنتقل من Parser صغير إلى Git وقواعد البيانات والحاويات وخوادم الويب دون الوقوع في فخ نسخ الكود فقط.

ماذا يعني بناء برنامج «من الصفر» فعلًا؟

مصطلح from scratch لا يعني بالضرورة الامتناع عن استخدام كل مكتبة أو كتابة كل شيء بلغة Assembly. المقصود تعليميًا هو أن تعيد تنفيذ الآلية التي تريد فهمها بدل إخفائها خلف مكتبة جاهزة.

إذا كان هدفك فهم HTTP، مثلًا، يمكنك استخدام Socket توفره اللغة، لكنك تقرأ الطلب وتفسر Request Line وHeaders وتبني Response بنفسك. وإذا أردت فهم Git، فلا تحتاج إلى إعادة كتابة كل أوامره؛ يكفي أن تبدأ بكيفية تمثيل Objects وReferences وCommits.

الأمر نفسه ينطبق على المشاريع الأخرى:

  • JSON Parser يفهم Grammar ويقرر إن كان الإدخال صالحًا.
  • Shell صغيرة تشغّل العمليات وتتعامل مع Arguments وPipes.
  • Web Server يستقبل اتصالات TCP ويحلل HTTP.
  • Key-Value Store يدير التخزين والفهرسة والاسترجاع.
  • Git مبسط يخزن Objects ويبني Commits وReferences.
  • Container Runtime تعليمي يعزل عملية باستخدام إمكانات Linux.
  • Regex Engine ينفذ المطابقة بدل استدعاء مكتبة Regular Expressions الجاهزة.

إذا كانت هياكل البيانات والبحث والتعقيد ما تزال غير مألوفة، فمن الأفضل تثبيت الأساس أولًا عبر فهم الخوارزميات وهياكل البيانات الأساسية قبل الانتقال مباشرة إلى Database أوCompiler.

لماذا تكشف هذه المشاريع ما لا يظهر في الدروس التقليدية؟

عند استخدام Framework جاهز قد يبدو تنفيذ الميزة بسيطًا: تستدعي Function فتحصل على النتيجة. عند إعادة بناء الجزء نفسه تبدأ الأسئلة الهندسية الحقيقية في الظهور.

  • كيف أمثل البيانات في الذاكرة أو على القرص؟
  • ماذا يحدث إذا وصل Input ناقص أو غير صالح؟
  • أين يجب أن أخزن State؟
  • كيف أميز بين Syntax وSemantics؟
  • ماذا يحدث إذا قطع Client الاتصال في منتصف الطلب؟
  • كيف أختبر السلوك بدل اختبار Implementation بعينها؟
  • متى أستخدم Structure بسيطة ومتى أحتاج Index أوCache؟
  • كيف أعرف أن نسختي متوافقة مع Protocol أوFile Format حقيقي؟

هذه الأسئلة هي الفارق بين معرفة Syntax لغة برمجة وفهم كيفية تصميم Software System.

Build Your Own X: مكتبة للمشاريع أكثر من كونه دورة واحدة

مستودع codecrafters-io/build-your-own-x يجمع أدلة خطوة بخطوة لإعادة إنشاء تقنيات معروفة. القائمة الحالية لا تقتصر على نوع واحد من البرمجيات؛ فهي تشمل قواعد البيانات وGit والحاويات وNetwork Stacks وأنظمة التشغيل ولغات البرمجة ومحركات Regex والمتصفحات وخوادم الويب ومحركات الرسوم وغيرها.

الميزة الأساسية هنا هي التنوع. إذا أردت فهم Database ستجد أكثر من مسار ولغة، وإذا كان اهتمامك بالأنظمة منخفضة المستوى يمكنك الانتقال إلى Shell أوMemory Allocator أوOperating System، بينما يستطيع مطور الويب اختيار Web Server أوFront-end Framework أوBrowser Engine.

لكن Build Your Own X ليس منهجًا متدرجًا بالضرورة. بعض الروابط سهلة نسبيًا، وبعضها يتطلب معرفة قوية بالأنظمة أوC أوالشبكات. لذلك لا تختَر المشروع بناءً على اسمه فقط؛ افحص مسبقًا ما الذي سيطلب منك تنفيذه.

Coding Challenges: بناء أداة حقيقية على مراحل قابلة للاختبار

يأخذ Coding Challenges الفكرة في اتجاه مختلف قليلًا. بدل تقديم مجموعة روابط فقط، تُقسم المشاريع إلى خطوات، وتوجد عادة طريقة واضحة لاختبار ما بنيته في كل مرحلة.

تتضمن القائمة مشاريع صغيرة نسبيًا مثل wc وJSON Parser وgrep، ثم مشاريع أكبر مثل Web Server وShell وRedis Server وGit وDNS Resolver وDocker.

وهذا يجعلها مناسبة خصوصًا لمن يعرف لغة برمجة بالفعل لكنه يحتاج إلى مشاريع تجبره على تحويل المعرفة النظرية إلى Software يعمل بمدخلات ومخرجات وحالات خطأ واختبارات.

Build Your Own X أم Coding Challenges؟

المصدر ما الذي يقدمه؟ متى يكون مناسبًا؟
Build Your Own X مجموعة كبيرة من Tutorials ومشاريع خارجية بلغات ومستويات متعددة عندما تعرف نوع النظام الذي تريد دراسته وتريد مقارنة أكثر من مسار
Coding Challenges مشروع محدد مقسم إلى مراحل مع أهداف واختبارات عملية عندما تريد مسار تنفيذ واضحًا بدل البحث بين عدد كبير من Tutorials

لا يوجد سبب لاختيار أحدهما وترك الآخر. طريقة فعالة هي العثور على الفكرة عبر Build Your Own X، ثم البحث عن Challenge مشابهة توفر Scope واختبارات، مع الرجوع إلى Specification أوDocumentation الرسمية عندما يتعلق المشروع ببروتوكول أوتنسيق حقيقي.

مسار عملي من مشروع صغير إلى أنظمة أكثر تعقيدًا

1. ابدأ بأداة Command-Line أوJSON Parser

مشروع مثل wc أوJSON Parser صغير مناسب لأنه يفرض عليك التعامل مع Input وOutput وملفات وأخطاء، لكن نطاقه يظل محدودًا.

في تحدي JSON Parser مثلًا تبدأ بقبول Object فارغ صالح ورفض المدخل غير الصالح، ثم تضيف Strings وNumbers وBooleans وnull، وبعدها Arrays وObjects المتداخلة.

ما تتعلمه هنا ليس JSON فقط، بل فكرة تحويل نص إلى Tokens أوStructures، والتحقق من Grammar، وتصميم رسائل أخطاء واختبارات تغطي Valid وInvalid Input.

2. ابنِ Web Server صغيرًا

خادم ويب بسيط من أفضل المشاريع التي تربط البرمجة بالشبكات. النسخة الأولى لا تحتاج إلى TLS أوHTTP/2 أوReverse Proxy. يكفي أن تستطيع:

  1. فتح TCP Socket.
  2. الاستماع لاتصال.
  3. قراءة Request.
  4. استخراج Method وPath.
  5. إرجاع Status Line وHeaders وBody.
  6. التعامل مع أكثر من اتصال لاحقًا.

يوفر Coding Challenges مشروع Build Your Own Web Server لهذا الغرض. وعند تنفيذ HTTP فعليًا، من الأفضل الرجوع إلى المواصفات الحالية بدل اعتبار أي Tutorial قديم مرجعًا نهائيًا؛ يعرّف RFC 9110 دلالات HTTP والمصطلحات المشتركة بين إصدارات البروتوكول.

وإذا بدت Sockets أوTCP أوالعنونة غامضة، فمن المفيد أولًا مراجعة أساسيات شبكات الحاسوب وTCP/IP حتى لا يتحول المشروع إلى نسخ Calls شبكية دون فهم مسار الاتصال.

مخطط يوضح الانتقال من JSON Parser وWeb Server إلى Git وقاعدة بيانات وShell ثم Container Runtime مع المفاهيم التي يتعلمها المطور.
مسار مقترح لبناء الأنظمة تدريجيًا، من Parsing والملفات إلى الشبكات والعمليات والتخزين وعزل Linux.

3. أعد بناء جزء من Git

Git مثال ممتاز على نظام نستخدمه يوميًا بينما تبقى بنيته الداخلية مخفية خلف أوامر مثل add وcommit.

توضح وثائق Git Internals الرسمية أن Git في جوهره يعتمد على مخزن محتوى موجّه بالعناوين، ثم توجد فوقه واجهة نظام التحكم بالإصدارات. ومن أهم أجزاء المستودع الداخلي objects وrefs وHEAD وIndex.

يمكن أن يبدأ Git التعليمي بنطاق صغير:

  • إنشاء Repository.
  • تخزين Blob.
  • إنشاء Tree.
  • إنشاء Commit.
  • تحديث Reference.
  • عرض History.

بعد ذلك يمكن إضافة Staging أوDiff أوالتعامل مع Remote. يطبق Build Your Own Git هذا الأسلوب تدريجيًا، بينما يوفر قسم Git في Build Your Own X عدة Implementations بلغات مختلفة.

القيمة هنا أنك ستفهم لماذا لا يمثل Commit مجرد «نسخة من مجلد»، وكيف ترتبط Objects ببعضها، ولماذا تستطيع Git الاحتفاظ بتاريخ كبير بكفاءة.

4. ابنِ Key-Value Store قبل قاعدة بيانات SQL كاملة

محاولة البدء بنظام شبيه PostgreSQL كاملة خطوة كبيرة جدًا. مشروع أفضل في البداية هو Persistent Key-Value Store يدعم عمليات مثل:

  • SET key value
  • GET key
  • DELETE key
  • الحفظ إلى القرص.
  • إعادة فتح البيانات بعد Restart.

بعد ذلك يمكن إضافة Index أوB-Tree أوWrite-Ahead Log أوTransactions حسب مستوى المشروع.

لفهم لماذا تصبح قواعد البيانات الحقيقية أكثر تعقيدًا، تعرض وثائق معمارية SQLite الرسمية فصلًا واضحًا بين Parsing وCode Generation والآلة الافتراضية وB-Tree وPage Cache وطبقة نظام التشغيل. كما تستخدم SQLite أشجارًا منفصلة للجداول والفهارس داخل ملف قاعدة البيانات.

المغزى ليس نسخ SQLite، بل ملاحظة كيف يتحول مشروع «احفظ قيمة في ملف» تدريجيًا إلى مشكلة تشمل تنظيم Pages والفهرسة والتزامن والتعافي بعد الفشل.

5. ابنِ Shell لفهم العمليات ونظام التشغيل

Shell تعليمية تعلمك مجموعة مختلفة من المفاهيم. ابدأ بقراءة Command ثم تقسيم Arguments وتشغيل Process خارجية، وبعدها أضف Built-in commands مثل cd.

يمكن توسيع المشروع لاحقًا ليدعم:

  • Environment Variables.
  • Redirection.
  • Pipes.
  • Background Processes.
  • Exit Codes.
  • Signals.

عند هذه النقطة ستبدأ في رؤية العلاقة بين Shell وبين Process Model الذي يوفره نظام التشغيل، بدل التعامل مع Terminal كصندوق أسود يستقبل أوامر نصية.

6. انتقل إلى Containers بعد فهم Linux Processes

مشروع Container Runtime من أقوى تمارين System Programming، لكنه ليس نقطة بداية جيدة للمبتدئ.

الحاوية ليست ببساطة «آلة افتراضية صغيرة». توضح وثائق Docker أن Docker ينشئ Namespaces وControl Groups للحاويات، وهي من الآليات الأساسية للعزل والتحكم في الموارد على Linux.

وتعرّف وثائق Linux الـNamespace بأنها تجريد يجعل موردًا عالميًا في النظام يبدو للعمليات الموجودة داخله وكأنه Instance معزول خاص بها.

لذلك قد يشمل Container Runtime تعليميًا مراحل مثل:

  1. تشغيل Process.
  2. إنشاء UTS Namespace وعزل Hostname.
  3. عزل Mounts وFilesystem.
  4. إنشاء PID Namespace.
  5. إعداد Root Filesystem.
  6. تحديد بعض الموارد عبر cgroups.
  7. لاحقًا جلب Container Image وفك طبقاتها.

يوفر Build Your Own Docker مثالًا عمليًا لهذا النوع من التدرج.

ولأن هذه الآليات مرتبطة بنواة Linux، فإن تنفيذ Container Runtime من هذا النوع يحتاج إلى بيئة Linux. استخدام Docker على Windows أوmacOS يخفي جزءًا من ذلك التعقيد عبر بيئة Linux افتراضية، لكن مشروعك التعليمي الذي يتعامل مباشرة مع Namespaces وSystem Calls يحتاج الوصول إلى تلك الإمكانات.

لا تبدأ بنسخة Production

أكثر خطأ يقتل مشاريع Build Your Own هو اختيار Scope يساوي المنتج الحقيقي.

إذا كان المشروع Web Server فلا تبدأ بقائمة تشمل HTTP/3 وTLS وCompression وReverse Proxy وCaching وLoad Balancing وWebSockets في الوقت نفسه.

ابدأ بالحد الأدنى الذي يثبت الفكرة:

  1. اتصال واحد.
  2. Request واحدة.
  3. Parsing محدود.
  4. Response صحيحة.
  5. Tests.

ثم أضف ميزة واحدة في كل مرة. الطريقة نفسها تنطبق على Git وDatabase وShell وContainers.

استخدم Specification كمرجع للحقيقة

الـTutorial يشرح لك طريقة تنفيذ، لكنه ليس دائمًا تعريفًا نهائيًا للسلوك. قد يكون قديمًا أو يبسط بعض الحالات عمدًا.

عندما تبني شيئًا يعتمد على Standard أوFormat معروف، افصل بين ثلاثة أنواع من المصادر:

  • Tutorial: يساعدك على التعلم والتنفيذ.
  • Specification أوDocumentation: تحدد السلوك أوالتنسيق الحقيقي.
  • Source Code: يكشف كيف اختار مشروع حقيقي تنفيذ ذلك السلوك.

في HTTP ارجع إلى RFC المناسب، وفي Git استخدم Git Internals، وفي قاعدة بيانات مثل SQLite توجد وثائق للمعمارية وFile Format، وفي Containers توجد وثائق Linux وDocker للـNamespaces وcgroups.

حاول أولًا ثم اقرأ Source Code

قراءة Repository ضخم قبل محاولة حل المشكلة غالبًا تتحول إلى تصفح أسماء Classes وFunctions دون سياق.

الطريقة الأكثر فائدة هي:

  1. حدد السلوك المطلوب.
  2. اكتب تصورًا بسيطًا للتصميم.
  3. حاول تنفيذ النسخة الأولى.
  4. سجل أين تعثرت.
  5. اقرأ Documentation.
  6. عدّل تصميمك.
  7. بعد ذلك اقرأ Implementation حقيقية للمقارنة.

عندها ستعرف لماذا تبحث في Source Code. قد تريد معرفة كيف يتم تمثيل Tree في Git، أوكيف تدير SQLite صفحاتها، أوكيف يعالج مشروع حقيقي Partial Reads من Socket.

اختبر السلوك، لا مجرد Functions منفصلة

قيمة هذه المشاريع تزداد كثيرًا عندما تستطيع مقارنة برنامجك بسلوك أداة حقيقية.

إذا بنيت Git subset، أنشئ Repository ببرنامجك ثم حاول قراءته بأداة Git الأصلية عندما يكون Format الذي تنفذه متوافقًا معها. وإذا بنيت Web Server، اختبره باستخدام curl. وإذا بنيت Parser، مرر له Valid وInvalid Inputs. وإذا بنيت CLI، تحقق من Exit Codes وstdout وstderr.

أضف كذلك حالات حدودية مثل:

  • ملف فارغ.
  • Input كبير.
  • بيانات ناقصة.
  • Encoding غير متوقع.
  • ملف غير موجود.
  • Connection تنقطع مبكرًا.
  • عملية تعيد Exit Code غير صفري.

هذه الحالات هي التي تحول المشروع من Demo يعمل مرة واحدة إلى تمرين حقيقي في Software Engineering.

كيف تختار المشروع المناسب لمستواك؟

المستوى مشاريع مناسبة ما الذي تركز عليه؟
مبتدئ بعد أساسيات اللغة wc-like CLI، JSON Parser، Calculator، grep مبسط الملفات، Parsing، Functions، Tests، Error Handling
متوسط Web Server، Shell، DNS Client، Git subset Protocols، Processes، Data Structures، Networking
متوسط إلى متقدم Redis-like Server، Key-Value Database، BitTorrent Client Persistence، Concurrency، Protocol Design، Indexing
متقدم Container Runtime، Compiler، Network Stack، OS Components System Calls، Memory، Isolation، Binary Formats، Low-level I/O

لا تجعل اسم المشروع هو معيار المستوى الوحيد. Web Server يدعم Request واحدة مختلف تمامًا عن HTTP Server متزامن يدعم TLS وHTTP/2. المهم هو Scope الذي ستنفذه.

قالب عملي لتنفيذ أي Build Your Own Project

1. اكتب الهدف في جملة واحدة

مثال: «سأبني HTTP/1.1 Server تعليميًا يدعم GET وملفات Static واتصالات متعددة».

2. حدد ما لن تنفذه

مثل: لا TLS، لاHTTP/2، لاCaching، لاReverse Proxy. قائمة الأشياء المستبعدة تمنع Scope Creep.

3. حوّل المشروع إلى Milestones

اجعل كل مرحلة تنتج برنامجًا يمكن تشغيله واختباره بدل كتابة أجزاء كثيرة لا تعمل إلا عند نهاية المشروع.

4. اكتب Tests مبكرًا

لا تنتظر اكتمال النظام. كل سلوك جديد يجب أن يكون لديك مثال يثبت أنه يعمل وآخر يثبت أن Input الخاطئ يُرفض بطريقة صحيحة.

5. ارجع إلى المصدر الأصلي عند الغموض

إذا اختلف Tutorial مع Standard أوDocumentation الرسمية، فلا تفترض أن التبسيط الموجود في Tutorial هو السلوك الكامل للنظام الحقيقي.

6. قارن مع Implementation حقيقية

بعد الوصول إلى حل يعمل، اقرأ Source Code أوArchitecture Documentation لترى أين اتخذ المشروع الحقيقي قرارات مختلفة ولماذا.

7. وثق حدود نسختك

اكتب README يشرح التصميم، ما الذي تدعمه النسخة وما الذي لا تدعمه، القرارات التي اتخذتها، وكيف تشغل Tests.

مشروع مكتمل أفضل من عشرين Repository منسوخة

الهدف من Build Your Own X ليس زيادة عدد المشاريع في GitHub Profile. إذا تابعت عشرين Tutorial ونسخت Implementation كما هي، قد تنتهي بكمية Code أكبر لكن بفهم أقل.

المشروع الجيد هو الذي تستطيع بعد انتهائه أن تشرح:

  • كيف تتدفق البيانات داخله؟
  • ما Structures الأساسية؟
  • أين توجد State؟
  • ما أكثر Failure Modes أهمية؟
  • لماذا اخترت هذا التصميم؟
  • ما الذي سيتغير لو أردت جعله Production-ready؟
  • ما حدود Implementation الحالية؟

ويمكنك تحسينه أكثر بإضافة Benchmark بسيط، وTests، وError Handling، وDocumentation، ثم مقارنة تصميمك بالمشروع الحقيقي الذي استلهمت منه الفكرة.

يمكنك تطبيق الفكرة خارج أنظمة التشغيل وقواعد البيانات

منهج «ابنِ نسخة مصغرة أولًا» قابل للتطبيق على مجالات أخرى أيضًا. إذا كان اهتمامك بجمع بيانات الويب، مثلًا، قد تبدأ بكتابة Fetcher وHTML Parser بسيطين ثم تنتقل إلى دراسة Framework أكثر اكتمالًا مثل Scrapling لجمع البيانات من الويب لترى الفارق بين Request منفرد ونظام Crawling وإدارة Sessions وParsing أكثر تعقيدًا.

وفي الذكاء الاصطناعي يمكن أن يعني «من الصفر» بناء Neural Network صغيرة أوTokenizer أوAutomatic Differentiation Engine بدل محاولة إعادة بناء نموذج ضخم كامل.

من أين تبدأ؟

إذا كانت هذه أول تجربة لك، لا تبدأ بـOperating System ولاDocker clone. اختر JSON Parser أوCLI صغيرة وأكملها مع Tests. بعدها انتقل إلى Web Server أوShell. عندما تصبح مرتاحًا مع الملفات والشبكات والعمليات وهياكل البيانات، جرّب Git أوKey-Value Database. أما Container Runtime أوCompiler أوNetwork Stack فاجعلها مرحلة لاحقة.

استخدم Build Your Own X لاكتشاف Implementations ومسارات متنوعة، وCoding Challenges عندما تريد مشروعًا مقسمًا إلى مراحل واضحة.

ولا تقِس تقدمك بحجم البرنامج. إذا أصبحت بعد بناء 500 سطر تفهم لماذا يعمل Git أوHTTP أوContainer Runtime بالطريقة التي يعمل بها، فقد حقق المشروع هدفه حتى لو كانت نسختك بعيدة جدًا عن المنتج الحقيقي.

شارك برأيك

لديك إضافة، سؤال أو تجربة مرتبطة بالموضوع؟ اكتبها وشارك بها القراء.