مدونة المُظلي

كلام عن تطوير البرمجيات والمبرمجين وما حولهما

Sunday, November 27, 2016

رهوان: كيف طورنا مواقع أسرع استجابة

مقدمة:
في هذه التدوينة، أكتب عن المراحل التي مررت بها شخصياً في تطوير مواقع الويب الإخبارية اعتماداً على dot net stack خلال السنوات الماضية، وأكتب عن "رهوان" وهو ال Data Access Layer الذي نعتمد عليه حالياً، والذي  ساعدنا في تحسين وقت استجابة أحد المواقع من 250 ملي ثانية وصولاً إلى 10 ملي ثانية وفي نفس الوقت خفض الحمل على قاعدة البيانات من 800 patch request/second وصولاً إلى 150 patch request/second

الزيتونة:
في أبسط صوره، "رهوان" ليس أكثر من data caching layer تم إضافته كطبقة وسيطة بين قاعدة البيانات وبين صفحات الموقع، هدف هذه الطبقة الأساسي هو توفير ال  Data Model المطلوبة لأي صفحة ويب، الوضع المثالي -والذي يتم الوصول له في معظم الأحيان- أن تتم العملية ك direct key/value retrieve operation  بحيث تطلب أي صفحة ال Data Model الخاص بها فيأتي محمل "بكل" البيانات المطلوبة "فوراً" بدون النزول إلي قاعدة البيانات، وأي تغير يحدث في قاعدة البيانات يتم إعادة بناء ال Data Model التي تعتمد على هذه البيانات بالكامل، ويتم ذلك في background tasks  .. وهو ما سنحاول شرحه في هذه التدوينة
ملاحظة: المرحلة الأولى والثانية هي استعراض لكيفية تطور الحل، يمكنك تخطيهما إن أردت

المرحلة الأولى: كود ملخبط بطئ :)
مررت  كمعظم المطورين  على مرحلة كل الإشارات بها "خضراء" فأي فرد من الفريق يريد كتابة أي كود في أي مكان بأي طريقه، فهو موضع ترحاب طالما ستكون النتيجة كود "شغال" حيث العميل عادة في غاية التعجل لإطلاق موقعه على الانترنت، وهو ما يضغط بشدة على فريق التطوير وتتحول الأولوية إلي بناء موقع "شغال" ويتم تأجيل أي حديث عن "جودة" الكود أو "تنسيق" أفضل بين أفراد الفريق، وتكون في العادة صفحات الموقع هي المسؤولة عن جلب كل ما تحتاجه من بيانات، كمثال:


كما هو واضح، يبدو الكود في هذه المرحلة كأنه بداية جيدة لوجبة "مكرونة اسباجتي" تقنية، فليس هناك نسق واحد، بل أن مهمة جلب البيانات تقع على ال Controller نفسه، ثم يتم نقل البيانات من ال Controller إلي ال View بطريقتين مختلفتين (ViewModel and ViewBag) واثناء عرض هذه البيانات نفسها، تم استعمال Html.RenderAction  مرة وتم استعمال Html.Partial مرة

صعب أن يصمد هذا الكود امام طلبات التعديل المستمرة من العميل، أو من طلبات حل ال bugs التي يعمل عليها أكثر من مطور، في العادة يتم حل bug في منطقة، فتتوقف منطقة أخرى كانت تعمل بدون مشاكل، وإن تم حل ال bugs كلها تظهر مشكلة بطء الموقع الملاحظ وهو ما يستهلك وقت ومجهود كبير للوصول إلي استقرار نسبي للموقع، بعد فترة يقرر الفريق أنهم عليهم أخذ فرصة لالتقاط الأنفاس ووضع حل نهائي لهذه المشاكل .. وهو ما سيصل بنا إلي

المرحلة الثانية: كود منظم (بعض الشئ)
بعد مواجهة مشاكل عديدة في المرحلة السابقة يقر الفريق -وأنا أيضاً- أنه ليس كل الإشارات الخضراء خير، وأن علينا وضع بعض الإشارات "الحمراء" على الطرق المؤدية للمشاكل، ويبدأ الاتفاق على خطوط عريضة موحدة Design Guidelines في تصميم وكتابة الكود
ما يلي هي  أمثلة حقيقية لبعض الإشارات الحمراء التي اتفقنا عليها في الفريق الذي أعمل معه
  • لا تستعمل ViewBag or ViewData إلا للضرورة 
  • لا تستعمل Html.RenderAction إلا للضرورة
وهذا هو مثالنا بعد اجتيازه المرحلة الثانية

في هذه المرحلة تم تحسين وضع الكود عن طريق:
  1. استعمال ال Unit Of Work pattern كوسيط بين قاعدة البيانات وبين ال Controller وهو ما يفتح الباب لعمل optimization للطريقة التي يتم جلب البيانات بها من قاعدة البيانات بدون لمس أي Controller بعد ذلك
  2. الاعتماد على ال Dependency Injection لتقديم ال Unit Of Work المطلوبة لل Controller
  3. الاعتماد على ال ViewModel كطريقة وحيدة لنقل البيانات من ال Controller ل ال View والذي من المفترض أن يساعد أي مطور في الفريق على معرفة كل البيانات المطلوبة لرسم أي View بالقاء نظرة واحدة على ال ViewModel الخاص به، ما يعني أخطاء أقل
  4. تم الاستغناء عن RenderAction فهي تتطلب إنشاء نسخة جديدة من ال Controller المستهدف وتمشي في مسار أطول وأبطئ من RenderPartial فإن لم يكن هناك سبب وجيه فال RenderPartial هي الإختيار الأول لنا
  5. استعمال OutputCache والذي سيجعل ال asp.net process تحتفظ بالنتيجة التي خرجت من ال Index Action لمدة 60 ثانية، قبل إعادة طلب النتيجة من جديد من ال Controller وهو ما يساعدنا في تحسين وقت استجابة الموقع هنا

المرحلة الثالثة: رهوان
لفهم رهوان، دعونا نجري مقابلة معه

أنا: السلام عليكم
رهوان: وعليكم السلام

أنا: ممكن تعرف الناس بك
رهوان: أنا Data Access Layer مُحَسنّ، مسؤول عن جلب البيانات لل Presentation Layer

أنا: لماذا تقول أنك "مُحَسنّ" ماذا يميزك عن أي Data Access Layer آخر
رهوان: أنا مصمم بحيث يكون انسياب البيانات غالباً في اتجاه واحد

أنا: ماذا تقصد بانسياب البيانات عندك في اتجاه واحد
رهوان: قبل الإجابة، اسمحلي أشرح المشكلة التي جئت لحلها أولاً
  • في العادة عند طلب صفحة ويب معينة، تنزل الصفحة -أو ال data access layer الخاص بها- إلي قاعدة البيانات لجلب ما تحتاجه من بيانات، ويتم ذلك بمعزل عن أي صفحة أخرى، وهو ما يتسبب في تكرار جلب نفس البيانات -التي لم تتغير في قاعدة البيانات منذ مدة- بدون داعي
  • كمثال، لو أن هناك ثلاثة أخبار كتبهم نفس الكاتب، وتم تصفح الثلاث أخبار في نفس اللحظة، سيتم جلب بيانات الكاتب من قاعدة البيانات ثلاثة مرات في نفس اللحظة أيضاً، لأن الثلاث صفحات تحتاج إليها، وهذه المشكلة هي التي استدعت منا بناء خط Data Caching جديد وراء الصفحات لحفظ البيانات المطلوبة مرة واحدة فقط ثم تقديمها لأي عدد من الصفحات

أنا: هذا عن المشكلة، فماذا عن الحل الذي جئت انت به؟
رهوان: الحل هو نقل كل البيانات الهامة أولاً بأول من قاعدة البيانات إلي ال Data Caching Engine حتى لو لم يتم طلبها بعد في موقع الويب، بذلك نضمن جاهزية دائمة للبيانات وانسياب في اتجاه واحد، من قاعدة البيانات إلي الذاكرة إلي صفحة الويب

أنا: وكيف تم تحقيق ذلك؟
رهوان: عن طريق هذا التصميم
أنا: ماذا يعني هذا المخطط/التصميم
رهوان: يوضح المكونات التي اعتمد عليها لإنجاز مهمتي وهي:
  • Change Detector: مهمته التقاط أي تغير حصل في قاعدة البيانات وإعلام ال Cached Repository بذلك
  • Cached Repository: مهمتها توفير البيانات لأي طرف يطلبها، وتحاول توفيرها من ال Cache Engine مباشرة إن استطاعت أو جلبها من ال Repository أولاً ثم وضعها في ال Cache Engine ثم توفيرها لمن طلبها
  • Cache Engine: مهمته الاحتفاظ بالبيانات في الذاكرة in-memory
  • Repository: مهمتها النزول الفعلي لقاعدة البيانات لجلب البيانات المطلوبة
أنا: ولكن أي ORM مثل Entity Framework يمكنه أن يفعل كل ما ذكرته انت، فلم كل هذا؟
رهوان: شتان بين الطريقتين، ف Entity Framework مثلاً غير مصمم ك Thread Safe أي لا يمكن لأكثر من صفحة التعامل مع نفس ال Entity Framework Context بينما رهوان مصمم ليكون نقطة تواصل واحدة مع جميع صفحات الموقع

أنا: ممكن نتصرف في موضوع ال Thread Safe بطريقة أو بأخرى، ونعتمد على ال ORM بدلاً من كل هذا التعقيد
رهوان: بهذا الشكل تكون حللت نصف الأحجية فقط، فكيف ستحل النصف الآخر؟

أنا: وما هو النصف الآخر؟
رهوان: الاستعلامات البطئية على قاعدة البيانات، فتكفي خمس دقائق متابعة ب sp who is active لتكتشف أن ال ORMs عموماً و Entity Framework على سبيل المثال يتعامل مع الاستعلامات المعقدة complex queries بشكل غير كفء، ما ينتج عنه -عند الضغط على الموقع- time out errors كثيرة، بينما فصل ال Data Cache عن طريقة جلب البيانات سيعطي لنا حرية كبيرة في جلبها من أي طريق (مثل dapper) وإعادة كتابة استعلامات محددة بشكل يدوي لزيادة كفائتها بدون التأثير على طريقة ال Caching الخاصة بها

أنا: رجوعاً إلي المخطط الذي وضحته انت منذ قليل، ممكن مثال عن كيف تعمل الأربع مكونات التي تحدثت انت عنها مع بعضها البعض
رهوان: خذ هذا المثال -الحقيقي-
  1. مشرف في موقع إخباري نشر خبر جديد
  2. تم حفظ الخبر الجديد في قاعدة البيانات
  3. التقط ال Change Detector أن هناك خبر جديد في قاعدة البيانات تم نشره ، فنادى على Cached Repository لإحضاره قبل حتى أن يطلبه أي أحد
  4. ال Cached Repository تجلب الخبر من قاعدة البيانات وتحتفظ به في ال Cache Engine
  5. أحد ال Controllers يطلب الخبر، فيتم مناولته مباشرة من ال Cache Engine
لم يتحمل ال Controller في هذه العملية أي تكلفة من تكاليف جلب الخبر من قاعدة البيانات، مما حسن جداً من وقت استجابته على متصفحي الموقع

أنا: معنى ذلك انك ستنسخ قاعدة البيانات بالكامل في ال Cache Engine الخاص بك؟
رهوان: بالطبع لا، فلدي طريقة أحدد بها البيانات التي تستحق الاحتفاظ بها في ال Cache Engine والبيانات التي ستخرج منه

أنا: إذاً هل ممكن بعض التفاصيل عن طريقتك في تحديد البيانات التي ستظل في ال Cache Engine؟
رهوان: في المواقع الإخبارية مثلاً تكون الأهمية القصوى لأخبار آخر شهر، ثم تأتي الأولوية للأخبار ذات معدل التصفح العالي، أما غير ذلك فيمكن أن يظل خارج ال Cache Engine ويتم جلبه من قاعدة البيانات عند الطلب

أنا: إذاً لن يكون انسياب البيانات في اتجاه واحد دائماً
رهوان: لذلك قلت ذكرت كلمة "غالباً" وأنا أتحدث عن هذه الميزة، فنسبة كبيرة من طلبات البيانات ستكون في اتجاه واحد، ونسبة أقل سيتم جلبها من قاعدة البيانات أولاً قبل تقديمها لمن طلبها

أنا: رجوعاً إلي المكونات الأربعة التي تحقق ما تحدثت انت عنه، هل ممكن تفاصيل عن كيف تم بناء كل مكون من هذه المكونات
رهوان: بالتأكيد، مع ملاحظة ان طريقة البناء الداخلية لكل مكون يمكن أن تختلف مع الوقت، إلا أن هذه هي التفاصيل الحالية
  • Change Detector: البناء الحالي تم عن طريق تنفيذ استعلامات دورية sql queries على قاعدة البيانات لمعرفة أي بيانات تم تحديثها وذلك باستخدام تاريخ تعديل البيان، وتم الإعتمادعلى Hangfire لجدولة وتنفيذ هذه الاستعلامات الدورية، لإنه ينفذها في Background Threads داخل موقع الويب نفسه
  • Cached Repository: وهي طبقة رقيقة مهمتها تنسيق العمل بين ال Repository وال Cache Engine لكن أهميتها أنها نقطة التواصل الوحيدة مع ال Presentation Layer 
  • Repository: وهي المكان الذي ينفذ عمليات جلب البيانات من قاعدة البيانات فعلياً، ونعتمد فيه على Dapper بصفة أساسية لسرعته الكبيرة ، ونعتمد أيضاً على Entity Framework في الاستعلامات غيرالمعقدة، وهناك ملاحظة هامة هنا:
    • أحد القوانين الحاكمة هنا هو التقليل من ال sql joins إلي أقل قدر ممكن فمثلاً عملية جلب خبر من قاعدة البيانات لن تجلب معه بيانات كاتب الخبر، بل ستكتفي بجلب رقم كاتب الخبر فقط author id ثم يتم طلب بيانات الكاتب من ال Cached Repository الخاص بالكتاب، فالاحتمال الأكبر أن بياناته موجودة بالفعل في ال Caching Engine فنكسب مرتين، مرة بتقليل ال sql joins ومرة بعدم جلب بيانات الكاتب من قاعدة البيانات بدون داعي
  • Cache Engine: تم بنائه باستخدام static ConcurrentDictionary لبساطته وقدر التحكم الذي نحصل عليه في البيانات الموجودة داخله
أنا: ماذا عن النتائج
رهوان: على مستوى ال Server Side فقد تم قياس النتائج باستخدام Mini Profiler وهذا مثال على الفرق


رهوان: وعلى مستوى قاعدة البيانات فهذا هو الفرق قبل وبعد استعمال رهوان


في الختام:
رهوان ليس الرصاصة الفضية للقضاء على مشاكل البطء لأي موقع ويب، بل أنه ولد من رحم مشكلات المواقع الإخبارية، أما المواقع/التطبيقات التي تعمل بشكل مختلف، ستحتاج حل مناسب أكثر لاحتياجاتها، قد يكون رهوان أو تعديل له أو حتى غيره

تحدثت في هذا المقال عن "فكرة" رهوان، ولم أتطرق لرحلة تنفيذ رهوان نفسها، فقد كانت مليئة بالتفاصيل، أكثر من أن يتحملها مقال واحد، سواء في تفاصيل ال Implementation ، أو في تفاصيل المشاكل التي واجهتنا أثناء التطوير مثل Memory Leaks و Sudden Process Termination  لنكتشف بعد رحلة تشخيص عميقة أنه Unhandled Stackoverflow Exception، إن يسر الله لي، يمكن أن أكتب جزءً آخر من المقال يتحدث بشئ من التفصيل والأمثلة عن كيف نفذنا الفكرة نفسها وكيف صنعت التفاصيل الصغيرة الفارق

وهناك أيضاً تفاصيل في كيفية تطويره مستقبلاً فعلى سبيل المثال نخطط لإعادة بناء ال Change Detector ليعتمد على  Publish/Subscribe pattern بدل الاستعلامات الدورية على قاعدة البيانات مباشرة، ونحتاج تجربة ال Caching Engine إذا تم تشغيله ب Redis فماذا سيكون الفارق

إلا أني حاولت قدر الإمكان الإلمام بالصورة الكاملة مع أهم تفاصيل الحل
أسأل الله أن يكون مقالاً نافعاً

في انتظار تعليقاتكم على الحل واقتراحتكم
والحمد لله رب العالمين

Monday, May 16, 2016

Flux: الإتجاه إجباري

الزيتونه :)
خلاصة ما فهمته حتى الآن هو أن مطوري فيسبوك يرون أن التطبيقات المبنية بنظام MVC ستصبح أكثر تعقيداً وتكويناً للأخطاء غير المتوقعة مع الوقت
وجذر المشكلة من وجهة نظرهم يرجع إلي ال Model وخاصة إمكانية التعديل فيه من أي اتجاه، لذلك قرروا أن يكون انسياب البيانات في التطبيق بالكامل ذا اتجاه واحد إجباري وأن يتم تحويل ال Model إلي Read-Only Model مع إضافة بعض الإمكانيات عليه، وتم إعاده تسمية ال Model إلي Store، إذا أردت أن تعرف لماذا أخذوا هذا القرار وكيف سيتم تعديل ال Read-Only Model فتابع القراءة :)




البداية من Angular2

بعد إصدار Angular2 beta-0 تحمست له كثيراً فقد كنت متابع لأخباره ومعجب بما وصل إليه، وكنا على وشك إعادة بناء إحدى التطبيقات داخل الشركة من جديد، بهدف تقديم أداء وتجربة أفضل لمستخدميه، بعد مناقشات داخل الفريق اتفقنا على الاعتماد على Angular2 وهو -حتى الآن- قرار نراه موفق وسعداء بما حصلنا عليه من تحسن في تجربة تطوير تطبيقات ال JavaScript وجودة الكود نفسه

اثناء التجهيز لإعادة بناء أحد أجزاء التطبيق والذي نعلم انه يحتاج إلي أداء استثنائي، أردنا التعرف على ما يمكن ل Angular2 أن يقدمه لنا، وهو ما وصل بنا إلي شاطئ  Angular2 "OnPush" Change Detection Strategy والذي بدوره ساقنا إلي القراءة أكثر عن الفرق بين تعامل Angular2 مع البيانات القابلة للتعديل والبيانات الصماء Mutable data & Immutable data

ثم جاء الدور للتعرف على React & Flux وما الذي يمكنهما تقديمه لتحسين الأداء بشكل استثنائي -كما يسوق React لنفسه- وعلى الرغم اني دخلت في الأصل للتعمق في React وبحث إمكانية استعماله جنباً إلي جنب مع Angular2 إلا أن الحديث عن Flux والمشكلة التي استدعت ابتكاره كان شيقاً جداً لي،  وبعد جولة في المقالات والفيديوهات أحببت تلخيص مع وصلت إليه حتى الآن


1- ما هي المشكلة التي استدعت ابتكار Flux ؟

قبل Flux كانت معظم إطارات العمل (MVC Frameworks) المشهورة، ك Angular, Ember وغيرها، تتنافس من أجل تقديم دعم أفضل للربط التلقائي بين ما يحدث في عالم الكود (Controller) وبين ما يحدث في عالم الواجهة الرسومية (View) وذلك عن طريق توسيط البيانات (Model) بين العالمين وأي تغير في البيانات من ناحية يصل إلي الناحية الأخرى تلقائياً وهو ما يعرف ب Two way data binding

وأصبح من الطبيعي أن تجد أن تعديل صغير في ال Model ينتج عنه عدة تحديثات في أكثر من منطقة في ال View، وعلى فائدة هذه الميزة في الشاشات غير المعقدة، ستجد ان نفس الميزة أصبحت عبء على المطور في الشاشات المعقدة، وستجده يشد شعره متسائلا عن سبب بطئ التطبيق قبل أن يكتشف أن تغيير لون خبر واحد تسبب في إعادة رسم قائمة الأخبار بالكامل والذي بدوره تواصل مع ال server للحصول على بيانات محدثة عن كل خبر، فيبدأ زميلنا المطور بمعالجة الأمر قبل أن يتكرر مرة هنا ومرة هناك ويظل في حالة معالجة دائمة لآثار ال Two way data binding

المشكلة هي نفس مشكلة "الفوضى المرورية" التي تواجهها كل مدن العالم،  تخيل مثلا طريق صلاح سالم في مصر -أعاذك الله من وقفته:)- بدون جزيرة في النصف ويمكن لأي سيارة السير في أي اتجاه والدخول والخروج من أي مخرج يمينا أو يسارا، تخيلت؟ احمد الله أن الوضع ليس كذلك :)

صياغتي للمشكلة التي جاء Flux لحلها هي:
مشاركة وتعديل نفس البيانات بين أكثر من منطقة/مكون 
 State sharing & management between multiple view-parts/components


2- ما هو الحل الذي جاء به Flux ؟
هو إلغاء فكرة ال Two way data binding وأصبح هناك إتجاه واحد إجباري للتواصل بين مكونات التطبيق وبعضها البعض، مما استدعى إعادة تنظيم المكونات نفسها لتعمل بسلاسة مع فكرة الإتجاه الواحد الإجباري، ومن أجل ذلك تم تصميم أربع مكونات جوهرية، تساعدها أخرى، لكنها تظل أهم أربع مكون لا يمكن أن يطلق على التطبيق انه متوافق مع Flux بدونها

  • Store هو الأسم الجديد لل Model سابقاً وأصبح للقراءة فقط، وظيفته الوحيدة هي إستقبال بلاغات من ال Dispatcher المركزي بأن إجراء ما، يتم في التطبيق، وهو داخلياً -ال Store- يقرر إذا كان يحتاج إلي تحديث بياناته -بنفسه- أم لا، ويرمي Event إن احتاج بأنه حدث بياناته الداخلية، يمكن أن يكون هناك أكثر من Store في التطبيق الواحد
  • Dispatcher وظيفته الوحيدة توصيل أي إجراء (Action) يتم تنفيذه  في التطبيق إلي جميع ال Stores، لا يكون في التطبيق إلا Dispatcher واحد فقط
  • Action هو كائن (Object) يحتوي على وصف لإجراء ما، يتم داخل التطبيق ويحتوي على كل ما يلزم من بيانات لاتمام هذا الإجراء 
  •  View يتابع أي تغير حصل في ال Store ويعيد رسم نفسه -إن احتاج- بناء على ذلك، ويبلغ ما يحدث بداخله عن طريق رمي Events
هناك مكونات أخرى مكملة يكاد لا يستغني عنها أي تطبيق Flux، وهي:
  • View-Controller وظيفته الاستماع إلي أي Events يتم رميها من ال View وبناء ال Action المطلوب وترحيله إلي ال Dispatcher المركزي
  • Action-Creator وظيفته بناء ال Action فعلياً وفعل ما يلزم قبل وبعد بناء ال Action، عادة ما يعتمد ال ViewController عليه لبناء أي Action مطلوب


3- مثال
لو تصورنا أن هناك شاشة تعرض قائمة بالأخبار الحالية في موقع ما، ومطلوب عند الضغط على أي خبر، أن يتم تغيير لون خلفية الصف الخاص به إلي اللون الأحمر، إذا أردنا فعل هذا وفقاً ل Flux فسيكون هذا مثال مبسط جداً للكود
ملاحظة: إذا أردت رؤية الكود وهو يعمل يمكنك تجربته من هذه الوصلة https://embed.plnkr.co/B43YS3


Monday, October 12, 2015

تجربتي مع يوسي ماس UC MAS


إن كنت مشغولاً جداً توجه إلي آخر المقال "الملخص" لكني أنصح بشدة قراءة التجربة كاملة

سمعت عن يوسي ماس قبل زواجي بفترة ووضعته في قائمة اهتمامتي إن رزقني الله بأطفال،
وبعد أن رزقني الله بزوجتي ثم بالأولاد (أكبرهم خمس سنوات الآن) لم يستغرق الأمر طويلاً حتى اتفقنا على إلحاقه بأحد مراكز التدريب على اليوسي ماس


ولمن لا يعرف ما هو اليوسي ماس، هو طريقة تعليم الحساب (جمع، طرح، ضرب، قسمة) باستخدام العداد، هناك أكثر من شكل للعداد لكنها تشترك في المضمون، وهو أن هناك آلة بسيطة يتم تدريب الأطفال عليها لإتمام العمليات الحسابية، نقطة القوة التي يتم مشاركتها بين الناس -خاصة فيديوهات اليوتيوب- عن اليوسي ماس، هو السرعة الكبيرة للأطفال في إتمام العمليات الحسابية

وصلنا لأحد مراكز التدريب على اليوسي ماس في مصر، وله فروع كثيرة خاصة في القاهرة، وسألناهم عن نظام التدريب الخاص بهم، فكان عبارة عن حصة أسبوعية حوالي ساعة ونصف، غالباً تكون يوم الجمعة أو يوم السبت، أي أن الشهر الواحد يكفي أربع حصص، اجتياز المستوى الواحد يحتاج إلي 12 حصة أي ثلاثة أشهر من الانتظام، إتمام البرنامج بالكامل يحتاج من سنتين إلي ثلاث سنوات، متوسط التكلفة الشهرية هي 250 جنيها

انتظم ابننا الأكبر وبنت أختي أيضاً في أول مستوى في اليوسي ماس، وقد أتما أول مستوى (استغرق حوالي ثلاث أشهر) وعلى مشارف الانتهاء من المستوى الثاني حالياً، مجموع فترة تجربتنا حوالي خمسة أشهر حتى الآن، وكانت لنا الملاحظات التالية

أولاً الملاحظات الشكلية:
  • فصل اليوسي ماس هو فصل تقليدي، بمعنى أنه منظم كصفوف من الدكاك (جمع دكة) تقف المعلمة في مواجهة هذه الصفوف وخلفها السبورة والحصة معظمها تلقين من المعلمة إلي الأطفال
  • متوسط عدد الطلاب في الفصل حوالي 15 طفل، قد يزيد أو يقل، تتولى تعليمهم معلمة واحدة
  • الايقاع سريع داخل الفصل، ويتطلب مجهود شبه يومي من أولياء الأمور في البيوت للتأكد من استيعاب أولادهم لما درسوه في الحصة


ثانياً ملاحظات على المنهج وتجربتي:
  • لو أتم ابننا كامل البرنامج التدريبي بنجاح يمكنه حل المسائل "الحسابية" بسرعة كبيرة جداً، لكنها لن تفيده في حل المسائل "الكلامية" التي تعتمد على استنتاج وبناء العلاقة بين الأرقام

  • لو أن هناك كلمة واحدة تلخص تجربتنا مع ابننا ومع بنت اختي فهي "الضغط" حيث يبذل الأطفال كثيراً من المجهود حتى يصبحوا مدربين على ما أخذوه، فيحتاج الأمر إلي تدريب حوالي نصف ساعة بشكل يومي وإلا قلت نتائجهم بشكل كبير

  • ثاني نقطة هي أيضاً "الضغط" لكن على أولياء الأمور، فمتابعة المستجدات ودعم الأولاد في التدريب عليها ثم متابعة الوقت المطلوب لإنهاء 20 مسألة (أي صفحة من المسائل) هي عملية أخرى من الضغط على ولي الأمر نفسه

  • يبدأ المنهج بسيط جداً، ولكن بعد عدة حصص تبدأ الحاجة إلي حفظ بعض المعادلات وهو ما رجع بنا إلي الخانة صفر من وجهة نظري، فنحن حريصون على ألا نكرر تجربة التعليم المعتمدة على الحفظ بشكل كبير

  • مع الوقت، أصبحت كلمة يوسي ماس هي كلمة ثقيلة جداً على ابننا وعلى بنت اختي، فالانطباع الذي ترسخ عندهم حتى الآن، انها صعبة عليهم، وهو ما أخشى -إن استمر- أن يتحول لقناعة سلبية ضد الرياضيات عموماً



ثالثاً مقارنة رياضيات يوسي ماس مع رياضيات المونتيسوري (من سن 3 سنوات إلي 6 سنوات):
  • من وجهة نظرنا، أهم نقطة في رياضيات مونتيسوري انها قائمة على الانشطة التعليمية، والتدرج المنظم فحتى لو لم يحصلّ الطفل المادة العلمية، فانطباعه عن الرياضيات سيكون إيجابي، حيث ارتبطت دائماً باللعب والانشطة

  • في العادة، لا يفهم الطفل ماذا تعني 4x5 يمكنه أن يقول لك انها تساوي 20 لكن لا يستطيع أن يعرف "لماذا؟" لماذا 4x5 تساوي 20 وماذا تعني أصلاً كلمة (ضرب) في الرياضيات .. لا تجاوب اليوسي ماس على هذا السؤال ، بينما تقدم المونتيسري إجابة منطقية للطفل .. فهو يستطيع أن يرى العلاقة بين 4 صفوف وخمس أعمدة بنفسه ويلمسها بيديه

  • اليوسي ماس لم ينجح من وجهة نظرنا في بناء العلاقة بين الأرقام في ذهن الطفل، فكل الأرقام هي حلقة في العداد، وتكون قيمتها 1 أو 10 بناء على مكانها في العداد، بينما في رياضيات مونتيسوري الواحد هو خرزة واحدة بينما العدد 10 هو صف من عشر خرزات مربوط في بعضه، مما يمكن الطفل من بناء العلاقة بين الأرقام مع الوقت



رابعاً مقارنة رياضيات يوسي ماس مع رياضيات سنغافورة (من سن 6 إلي أعلى)

توضيح: رياضيات سنغافورة ليس لها علاقة بأي طريقة من طرق الحساب الذهني (لا يوسي ماس ولا IMA ولا أمثلتهما) ويمكن أن أفرد تدوينة لشرح ما هي رياضيات سنغافورة قريباً لكثرة السؤال عنها
خذ هذه المسألة الكلامية: اشترى عمر 4 علب زبادي أكثر من أمل، فإذا علمت أن أمل اشترت 12 علبة زبادي .. احسب كم علبة زبادي اشتروها جميعاً
رياضيات سنغافورة تدرب الطفل على 7 خطوات مرتبة لحل أي مسألة كلامية
  1. اقرأ المسألة جيداً
  2. استخرج المتغيرات
  3. ارسم شريط الأعداد
  4. قسم المشكلة وظبط شريط الأعداد
  5. ضع علامة الاستفاهم
  6. نفذ العملية الحسابية
  7. اكتب الإجابة بصيغة كلامية


لمشاهدة فيديو شرح المسألة:

خطوة 6 في رياضيات سنغافورة ستصل إلي هذه العملية الحسابية 12+16 ، ستوجه الطالب إلي تقسيم العملية إلي التالي 10+10+6+2 وستكون النتيجة 28

بينما طريقة يوسي ماس لم تستطيع أن تقدم طريقة منظمة لحل المسألة الكلامية وإن وصل الطالب إلي العملية الحاسبية 16+12 سينفذها في ذهنه بسرعة جداً وهي ميزه طبعاً


لكني أفضل أن يتعلم الطفل تجزئة المشكلة وتبسيطها كما حدث مع رياضيات سنغافورة، فرأيي أنه حتى في هذه المرحلة تفوقت رياضيات سنغاورة على يوسي ماس أيضاً


الملخص:
قررنا التوقف عن الاستمرار في برنامج اليوسي ماس، لما لمسناه من ضغط كبير يمارس على  ابننا وانطباع سلبي بدأ يترسخ عنده تجاه الرياضيات، ولأن البرنامج قائم على الحاجة إلي التدريب المستمر أكثر من الحاجة لفهم سلس وعميق للرياضيات
حيث تعلمنا أن سرعة الحساب ليست هي الفيصل، بل بناء العلاقات بين الأرقام وسهول استنتاج روابط جديدة هي ما تميز بين التعليم العادي والتعليم الجيد

في رأيي جودة التعليم المنتظرة من يوسي ماس أفضل بالطبع من جودة التعليم المصري الحكومي (أو اللاتعليم إن صح) ولكنها دون طرق التعليم الجيد (أعني بجيد الذي يترك أثراً عميقاً في طريقة تفكير الفرد وأثراً نفسياً إيجابياً) مثل مونتيسوري ورياضيات سنغافورة، قررنا أن نركز الآن على طريقة المونتيسوري في تعليم الرياضيات فهي أفضل من وجهة نظرنا وقد أفرد تدوينة أخرى عن كيف سنبدأ أنا وزوجتي

Saturday, November 20, 2010

تشيلي الواحة الفتـيّة لرواد الأعمال التقنية

أنشر هذه المقالة المترجمة للعربية بعد إعلان الأخ عماد المسعودي فوز هذه المقالة ضمن مسابقة ترجم للريادة، سعدت بهذه المسابقة سعادة خاصة، وذلك لانها تهتم بنشر ثقافة ريادة الأعمال والتي نفتقدها بشدة في مجتمعاتنا وتشجع المحتوى العربي التقني على الانترنت، وسعد بالجائزة لأنها أول 200 دولار يدرها علي حبي للغة العربية :) والآن أترككم مع المقالة

 

هذه المقالة مترجمة عن فيفيك وادهاوا، رائد أعمال حالياً وأكاديمي سابق، محاضر غير متفرع في جامعة كاليفورنيا في بيركلي، باحث محترف في كلية الحقوق بجامعة هارفارد وإداري مقيم في جامعة ديوك

هل أنت مهاجر أرهقتك سنين الانتظار الطوال أملاً في البطاقة الخضراء (جرين كارد) والتي يمكن ألا تحصل عليها أبداً، أم أنك رائد أعمال تتطلع لخفض تكاليفك بشكل جدي، سواء كنت هذا أم ذاك نصيحتي لك، تحرك جنوباً. لا، لست أعني لوس أنجلوس أو سان ديجو، أتحدث عن أقصى الجنوب حيث شيلي. ستجد في انتظارك أزرع مفتوحة وحوافز من شأنها خفض تكاليفك إلي أكثر من النصف، ناهيك عن أنك ستحيا في أرض ستحول كاليفورنيا إلي أرض قاحلة في نظرك.

رجعت لتوي من رحلة رائعة إلي شيلي، حيث كنت مدعواً من قبل حكومتها لإلقاء نظرة على على ما حققوه من إنجاز في التحول إلي مركز تعهيد خارجي. ذهلت حقاً من قدرتهم على النمو بدأً من لا شئ وصولاً إلي مليار دولار من العائدات خلال سبع سنوات أو يزيد.  وتعجبت كيف لهم أن يحققوا مثل هذا الإنجاز في مجال متعطش للكفاءات مثل التعهيد الخارجي بدون خنق الصناعات المحلية بامتصاص المهندسين والعلماء الأكفّاء إلي وظائف ذات رواتب مغرية. أخبرتهم بأن أمامهم فرصة سانحة لمنافسة الهند في مجال التعهيد الخارجي كمثل التي للهند في منافستهم في تصدير النحاس. الهند شعبها تخطى المليار. بينما شيلي 16 مليون نسمة، أقل من تعداد بعض المدن الهندية. لكن شيلي تستحوذ على 40% من احتياطي النحاس العالمي، فرق هائل حقاً.

250px-South_America_location_CHIشيلي يمكن ألا تكون الحصان الأسود في التعهيد الخارجي. لكنها يمكن أن تكون درّة أمريكا الجنوبية بقدرتها على التحول إلي الواحة الجديدة للمهاجرين بشكل عام ورواد الأعمال التقنية الذي يشكل التصدير محور أعمالهم. وضعت الحكومة الشيلية تشكيلة من الحوافز الخرافية للشركات التي تشكل التقنية عمودها الفقري والتي تصدر منتجاتها. الحكومة تريدك أن تستثمر 500,000 دولار خلال خمس سنوات لكنها مرنة جداً في آلية تحقيقك لذلك.

ماذا بعد استثمارك 500,000 دولار، ما الذي ستحصل عليه بالمقابل؟ كبداية، سيمنحوك تأشيرة دخول. يمكنك البقاء كيفما يحلو لك – حتى بشكل دائم. عليك أن تقدم خطة عمل لكنك تتمتع بحرية كبيرة في الاختيار من باقة الأعمال التي يدعمونها. أي عمل يقدم منتجات عالية التقنية، منتجات طبية، منتجات تكنولوجيا حيوية، منتجات تكنولوجيا خضراء غير مضرة تحصل على ختم الموافقة، وكذلك صناعات تطوير البرمجيات أو حتى تطوير ألعاب الويب أو تطوير شبكات التواصل الاجتماعية. حتى لو كنت ستنشأ مركز اتصالات أو مركز دعم فني يبيع خدماته للشركات الأجنبية ويظنون أنك مؤهل، ستحصل على التأشيرة.

لكن قبل ذلك، تريد التحري عن البلد أليس كذلك؟ ستمنحك الحكومة 60% من تكاليف التحري أو ما قد يصل إلي 30,000 دولار لزيارة واستكشاف شيلي. وسيضمنون لك 30,000 دولار أخرى لبدء شركتك في شيلي. إن قررت العمل داخل أحد المراكز التقنية الخاصة بهم، ستتكفل الحكومة بدفع الإيجار لمدة خمس سنوات (قد يصل إلي مليون دولار) نيابة عنك أو ستقتسم معك التكاليف إن أردت أن تستقر في أي مكان آخر في هذا البلد الرائع.

ماذا عن حوافز القوى العاملة؟ شيلي قد أمّنت ظهرك بالفعل. فستدفع الحكومة لك (كرائد أعمال تم قبوله) ما قد يصل إلي 25,000 دولار للسنة الأولى "كمصاريف تدريب" لأي مواطن شيلي تعيّنه. بالمناسبة شيلي تملك بعض مدارس الهندسة المتميزة لذا فانتقاء مبرمج جافا أو C# لن يكون عملاً شاقاً، الواحد منهم يتقاضى من 15,000 إلي 30,000 دولار في السنة، أمازلت لا تجد أي مواطن موهوب؟ ستدعم شيلي مجهوداتك لاستقدام من تريد من سانيفيل في مومباي أو من أي مكان قد تجدهم فيه. ويمكنك تدريب هؤلاء الناس على حساب شيلي أيضاً. وإن قررت شراء بعض الأراضي وبناء معاملك أو مكاتبك الخاصة، سيدفعون لك 40% من تكاليفك حتى 2 مليون دولار. ماذا عن المهاجرين المؤقتين أو الموهوبون الذين يرغبون في الانتقال إلي شيلي؟ بسيطة. وفر وظيفة تقنية مناسبة وستحصل على التأشيرات، بدون طرح أي أسئلة. هل بدأت تشعر بما أشعر به؟ (ملاحظة: إن حصلت شيلي على ربع المهاجرون المؤقتون العاملون بوظائف تقنية في أمريكا الآن، فستكون قريبة من مضاعفة القوى العاملة في التقنية داخلها)

لكن مهلاً، مؤكد الموضوع فيه إنّ. بحثت عن تلك الإنّ لكني لم أجدها قط، حتى أني زرت فينا ديل مار وهو منتجع خلاب يبعد ساعة عن سانتياغو. الطقس والمناظر الطبيعة تذكرك بكاليفورنيا (باستثناء أن فصول شيلي المناخية معكوسة – عندما يحل الصيف في الولايات المتحدة، يكون الشتاء مستقراً في الجنوب) يضم منتجع فينا ديل مار شواطئ رائعة ويبدو كأنه النسخة الحديثة من ميامي، وتخيل كم تكلف شقة غرفتين مفروشة بالكامل ومواجهة للشاطئ؟ 500 دولار في الشهر. حتى عاصمتها سانتياغو بمجرد أن تطئها قدمك تشعر كما لو أنك في أحد البلاد الأوروبية الحديثة لكن بمعدل جرائم منخفض للغاية، طقس رائع، مواطنين ودودين. فضلاً عن ركوب الأمواج الرائع في شيلي

ويعلو كل هذا، شيلي دولة ديمقراطية مزدهرة وواحدة من أكثر الاقتصادات انفتاحا في أمريكا الجنوبية. في الحقيقة، لو عزمت على إنشاء شركة ولم يكن هناك حاجة للتواجد في مكان بعينه، سأبدأها في شيلي بدون تردد. ما أدهشنى حقاً هو أن العديد من الشيليين الذين اللتقيت بهم يفاخرون بأن بلادهم أصبحت "أرض المهاجرين". الكل يحكي قصص عن كيف قامت شيلي على أكتاف المهاجرين وكيف رحبت بالمهرة المهضموي الحقوق. هذا يذكرني كيف كانت أمريكا قبل أن تبدأ حركات مناهضة الأجانب بإلقاء اللوم على المهاجرين لأنهم مصدر كل تقصير وسبب كل بؤس. يبدو هذا أكثر من معقول ليكون صحيحا، أليس كذلك؟ هناك بعض الجوانب السلبية. شيلي تبعد 15 ساعة عن الساحل الغربي. وإن أردت البقاء فترة طويلة، ستحتاج لتعلم الاسبانية. هذا ليس ثمناً  كبيراً مقابل كل تلك المميزات.

أتتوق لتتحرر من التكاليف والقيود التي تفرضها طبيعة التكنولوجيا في أمريكا الشمالية؟ عليك بالجنوب أيها الفتى التقنيّ

Saturday, July 10, 2010

مرحلة المراهقة البرمجية – التمرد على المشاريع

هل خطر في بالك مرة أسئلة من هذه النوعية :

- سئمت هذا المشروع وهذا العميل

- المبرمجون في الخارج يبرمجون بطريقة متقدمة عنا بسنين ضوئية

- أنا مبرمج غير كفء

هذه الأسئلة يمكن أن تدور بخلد كثيراً منّا وقليل من يتحدث بها طلباً للنصيحة، بل كثيرا من هذه الاسئلة وأخواتها افسدت عليه الاستمتاع بسنوات عمره الماضية

مررت شخصياً بهذه المرحلة، وهي مرحلة المراهقة البرمجية كما أسميها

كنت أعتقد في هذه المرحلة أن المشروع الذي أعمل به هو المشروع الوحيد الذي به مشاكل، فهو لم يسلم في الميعاد وتكاليفه تخطت المخطط لها ولم يخرج بالجودة التي صممناه بها في البداية

وبعد تكرار عملي في أكثر من مشروع، بدأت اعتقد ان المشكلة في أنا فليس من الطبيعي ان كل مشروع اعمل فيه يكون فيه هذا القدر من المشاكل المتكررة،

فكل المشاريع التي اعمل فيها تبدأ ولا أراها تنتهي أبداً

وكل مشروع أعمل فيه هو متأخر تكنولوجياً عن أحدث ما نزل من تكنولوجيا تطوير البرمجيات

وكل مشروع أعمل فيه تكثر في التعديلات لدرجة أرهقت شيفرة المصدر فأصبحت مهلهلة، ولا استطيع النظر إليها وأفتخر أنها من صنع يدي

وكنت سأظل في هذه المرحلة لو أن من الله علي بحضور جلسة من جلسات التعريف بال Agile Development  أو البرمجة المرنة

ولشرح فوائد البرمجة المرنة  Agile Development  بدأ المحاضر بشرح المشاكل التي استدعت اللجوء إليها

ولأول مرة في تاريخي رأيت مشاكلي التي أعاصرها في مشاريعي يوم بيوم يشرحها فرد آخر أمامي بنقاط واضحة

بل الأهم من ذلك أني شعرت أني لست وحدي في صحراء مشاكل تطوير البرمجيات

وزادت قناعتي بأني لست وحدي عندما بدأت متابعة اللقاءات المسموعة على الانترنت Podcasts  والتي يتحدث فيها المطورون الأجانب عن متاعبهم في تطوير البرمجيات

وبعد فترة من الزمن بدأت انتقل لمرحلة أخرى في اثناء عملي في أي مشروع

وهي مرحلة قبول التحدي كما أسميتها

وأول شئ بدأت بتصححيه في هذه المرحلة هو فهمي لمشاكل المشاريع، فلم أعد أطلق عليها مشاكل بل استبدلتها بتحديات

وثاني شئ مميز حدث لي في هذه المرحلة هو بدء مصالحة مع نفسي بأن أرضى بوجود هذه التحديات، لانه لولا وجودها لما احتاجت الشركات لمثلي ولا تمايز المتميزون في إيجاد حلول مبدعة لتخطي هذة التحديات

كتبت هذه التدوينة عسى أن ينتفع بها من مازال في مرحلة المراهقة البرمجية لأدعوه أن يتركها بلا رجعة وينتقل إلي مرحلة قبول التحدي، فمازلت اتذكر دوما نصيحة أخي مصطفى جمال: كن جزءاً من الحل ولا تكن جزءاً من المشكلة

ال .NET Framework عود على بدء

ال .NET Framework هي المحطة الأولى التي ينطلق منها أي مطور تطبيقات دوت نت لذلك فهو من أكثر الموضوعات التي يتم الاستفاضة في شرحها ألا أنه بطبيعة الحال فإن غالبية من يشرح لهم ال .NET Framework يكونوا من المبتدئين فبالتالي يحتاج فهم ال .NET Framework عندهم إلي وقت وممارسة فالصورة عندهم غير مكتملة وهناك بعض المعاني التي يحفظونها كما هي إلي أن يشاء الله ويفهمون هذه المعاني فهماً عميقاً وتضح عندهم الصورة، ولأني لست استثناء من هذه القاعدة أكتب هذا المقال بعد أن شاء الله وفهمت كثيراً من المعاني التي كان أقصى صدى لها في بداية تعلمي إياها هو نطقها فقط لذا كان من الأهمية بمكان كتابة مثل هذا المقال والمقسم كالآتي :
· الحياة قبل ال .NET Framework
· الحياة بعد ال .NET Framework
1- الحياة قبل ال .NET Framework
في هذه الأزمان كان على المبرمج أن يكون من نوعية – الكل في واحد - وأن يؤدي بمهارة أربعة أدوار وهي

  • البنّاء
  • المؤرخ
  • النصوح
  • المفتش
  • وهي بالطبع بجانب دوره كمبرمج ، ودعنا نفصل كل دور من الأربعة السابقة

    1- يحتاج المبرمج أيامها أن يكون بنّاء لأنه سيبني بنفسه طريقة لإدارة الذاكرة وأخرى لإدارة الأخطاء بالإضافة لبناء كل سطر كود سيحتاجه البرنامج فلو قررت مثلاً بناء لعبة فعليك أن تبني نظام يتأكد من أن الذاكرة ليس فيها كائنات Objects غير مستعملة ونظام آخر لإدارة الأخطاء التي يمكن أن تنتج من اللعبة بالإضافة إلي بنائك لمحرك اللعبة ونظام الرسم على الشاشة وغير ذلك من مهام .

    2- ولن يستقيم دوره كبناء بدون أن يكون مفتش جيد يعرف كيف يفتش عن خصائص نظام التشغيل الذي سيعمل عليه ونظام بناء نظام التشغيل فمثلاً إن كان 32-bitأم 64-bit وإن كان البرنامج سيعمل على أكثر من نظام تشغيل فيجب عليه أن يحيط علماً بكل الفروقات بين نظم التشغيل المختلفة فما يمكن عمله في Windows ME لا يمكن عمله في Windows NT فأبسط شئ يمكن ذكره هو عبارة عن اسماء مكتبات النظام System DLL التي يمكن ان يتغير اسمها من نظام تشغيل إلي نظام تشغيل آخر فبالتالي عليك أن تكون ملم بكل أسم لكل نظام تشغيل

    3- يجب عليه دائما أن يكون ناصحا لزملائه بإتباع أساليب قياسية لتنفيذ برامجهم حتى يتسنى له التكامل مع برامجهم فاختلاف لغات البرمجة واختلاف طريقة بناء البرامج سببت مشكلة وهي عدم وجود اسلوب قياسي تستطيع من خلاله البرامج أن تتكامل مع بعضها البعض والأسلوب الأكثر شهرة هو ما يعرف بال COM (Component Object Model)

    4- أخيراً لزاماً عليه أن يكون مؤرخاً لكل إصدارة من برنامجه ومكتبات النظام System DLL التي استعملها وتواريخ إصدار هذه المكتبات DLL حتى يمكنه نسخها إلي كل نظام تشغيل سيعمل عليه لأنه ياويل برنامجه إن بدل أحد المبرمجين غيره ملف من ملفات مكتبات النظام System DLL بملف آخر مختلف في تاريخ إصداره عن تاريخ إصدار ملف صاحبنا – هذه العملية عرفت بجحيم المكتبات DLL Hell -

    أي أن ملخص هذا الكلام في أنه كان هناك عبء كبير ملقى على عاتق أي مبرمج نظراً لتوليه إنجاز كل هذه الأمور وأكثر بنفسه
    - الحياة بعد ال .NET Framework
    جاء ال .NET Framework حاملاً هدايا إلي ثلاث
    1- إلي المبرمج فصدق أو لا تصدق فقد حمل عن كاهل المبرمج الأدوار الأربع هل تذكرهم أنهم:
        · البناء : فقد أعتمد ال .NET Framework في إراحة المبرمج من هذا الدور على مكونين أساسين

    أ - نظام جديد لإدارة الذاكرة هو ال CRL (Common Language Runtime) وليس هذا فقط فقد تعدى هذه المرحلة إلي مرحلة أكبر وهي إدارة التشغيل بالكامل أي أنه منذ بداية تشغيل برنامجك وحتى إغلاقه فقد تولى ال CLR جميع مهام التشغيل من إدارة للذاكرة وإدارة للأخطاء وترجمة إلي لغة الآلة وغير ذلك.

    ب - مكتبة جاهزة فيها تقريباً كل ما يحتاجه المبرمج لإنجاز مهامه وهي تعرف باسم FCL (Framework Class Library) أو BCL (Base Class Library) كلاهما صحيح ففي هذه المكتبة بنت مايكروسوفت فئات Classes جاهزة للاستعمال تتولى هي تنفيذ المهام التي كان على المبرمج أن يبنها بنفسه سابقاً مثل إدارة الاتصال مع قاعدة البيانات والرسم على الشاشة وغير ذلك من المهام

    · أما عن دور المفتش فلم يعد له حاجة بعد ظهور أداة جديدة داخل ال CLR وهي ال JIT Compiler (Just In Time Compiler) ،

    ودعنا نستوضح قليلاً دور المفتش هذا فقد كان ذا أهمية كبيرة سابقاً لأنه كان لزاماً علي أن أخرج البرنامج من تحت يدي وهو جاهز للتشغيل المباشر على أي نظام تشغيل يدعمه البرنامج أي أن ترجمة البرنامج من لغة البرمجة التي أعمل بها إلي لغة الآلة Machine Language تتم على جهاز المبرمج ثم توزع هذه النسخة المترجمة إلي لغة الآلة على الأجهزة المستهدف لتعمل عليه

    ا أما بعد ال .NET Framework فقد اختلف الأمر حيث مازال يتم ترجمة البرنامج من لغة البرمجة إلي لغة أخرى على جهاز المبرمج ولكن هذه المرة لا يُترجم إلي لغة الآلة بل إلي لغة جديدة وهي ال MSIL(Microsoft Intermediate Language)

    وهي لغة وسيطة يمكن لأي لغة برمجة تدعم ال .NET Framework أن يتم ترجمتها إلي MSIL ثم يتم توزيع البرنامج بعد ترجمته إلي MSIL لكن ال MSIL هي لغة لا يمكن تشغيلها بشكل مباشر على الحواسيب لذا يأتي دور ال JIT Compiler حيث يستطيع أن يترجم أي برنامج مكتوب بال MSIL إلي ال Machine Language

    وفي هذه النقطة سؤال وهو طالما سيتم التحويل في النهاية إلي Machine Language فلماذا لم يتم هذا على جهاز المبرمج والأجابة هي "لرفع حمل دور المفتش" لأن من روائع ال JIT Compiler أن الترجمة التي تخرج منه بلغة ال Machine Language هي ترجمة تناسب نظام التشغيل الذي يعمل عليه ال JIT Compiler

    أي أني لو بنيت برنامج وترجمته إلي MSIL ووزعته على ثلاثة من أصحابي أحدهم يشغل Windows XP والآخر Millennium ً Windows والثالث Windows Server 2003 وكل واحد منهم قد ركب .NET Framework على جهازه فإن ال JIT Compiler سيترجم لكل واحد منهم Machine Language تناسبه وبالتالي لن أحمل هم الإصدارات المختلفة من نظام التشغيل بعد الآن -

    أما عن دور النصوح

    فلن يعود صديقنا المبرمج بعد الآن إلي حمل هم نصح أصدقائه فقد جمعهم ال .NET Framework على منصة واحدة لها نفس المقاييس ويعود الفضل في توحيد أسلوب العمل بين كل المبرمجين الذين يبنون تطبيقاتهم باستخدام

    ال .NET Framework إلي أن ال .NET Framework يخضع لمعايير تسمى

    ال(Common Language Infrastructure) CLI وهذه المعايير وضعتها مايكروسوفت بنفسها وتم نشرها على www.ecma-international.org بحيث يجب على أي طرف يريد تطوير لغة تدعم الدوت نت أن يتبعها حيث لم تضيق مايكروسوفت نطاق تطوير لغات تدعم بيئية الدوت نت عليها وحدها بل فتحته لأي طرف يريد تطوير لغة يمكنها العمل على .NET Framework وبعد أن وضعت مايكروسوفت هذه الاشتراطات بدأت هي نفسها بتباعها لتبني أول نظام إدارة تشغيل متوافق مع معايير ال CLI وهو نظام إدارة التشغيل الذي يعرف باسم ال CLR ومن ضمن المعايير التي وضعها ال CLI معيار اسمه ال CLS (Common Type System) يخدم في المقام الأول معيار بناء لغة برمجة يمكن أن تعمل على .NET Framework وعكفت مايكروسوفت على بناء أول لغة يمكن أن تعمل على .NET Framework ومتوافقة مع معيار ال CLS وكانت C#.NET ثم اتبعتها مايكروسوفت بشقيقتها ال VB.NET وهما الاثنتين يمكن ترجمتها إلي MSIL

    · ودور صديقنا المبرمج كمؤرخ

    لم يعد يحتاجه بعد أن ظهر مكون من أهم مكونات ال .NET Framework تحدثنا عنه سابقا وهو ال (Base Class Library) BCL فكل ما ستحتاجه بعد الآن أن يستعمل الفئة Class التي تناسب عمله وعند توزيع البرنامج على أي عميل سيجد نفس الفئة Class موجوده على ال .NET Framework المركب عن العميل.

    · كانت هذه الهدايا التي حملها ال .NET Framework إلي المبرمج فماذا في جعبته أيضاً

    2- هدايا إلي أي مستخدم عادي لبرنامج تم بناءه بأي لغة تعمل على .NET Framework وهي كالتالي :

    · ضمان مستوى أمنى محترم فالبرامج سابقاً كان مسموحاً لها أن تدير ذاكر الحاسوب بنفسها فماذا لو أن أحد المخربين استطاع أن يركب برنامج على جهاز مستخدم عادي وبدلاً من أن يدير الذاكرة بدء يملئها بما لا يفيد مما سينعكس بالطبع على سرعة الجهاز بالسلب، هذه المشاكل تم حلها تماماً لأن من تولى زمام إدارة الذاكرة الآن هو ال .NET Framework بنفسه وتحديداً ال CLR داخل ال .NET Framework

    · لن يقع المستخدم في حيرة من أمره إن ظهر له رسالة تحذير من أن هناك برنامج يحاول تبديل واحدة أو أكثر من مكتبات النظام System DLL بواحدة أخرى أقدم ، فجميع برامج الدوت نت تستعمل ال BCL وهي موحدة على جميع الأجهزة ولا تختلف من جهاز لآخر

    3- الهدية الثالثة حملها إلي البرنامج نفسه فلم يعد البرنامج يخزن بداخله جميع مكوناته فهو يحمل فقط الكود الذي كتبه المبرمج بيديه فقط أما كود إدارة الذاكرة فسيجده أينما يتم تركيبه موجود في ال .NET Framework وكود الفئات Classes التي يستخدمها من ال BCL سيجده أيضاً أينما تم تركيبه موجودا في ال .NET Framework

    أبسط طريقة لإجبار مستخدم موقعك على تصفحه من نافذة واحدة فقط

    السلام عليكم ورحمة الله وبركاته

    احتجت في تطبيق ويب أبنيه أن اتأكد من ان المستخدم لن يستخدمه من أكثر من نافذة واحدة فقط حتى لا تتضارب ال Sessions ids

    وكان هذا أبسط كود وصلت له

     1: public partial class _Default : System.Web.UI.Page


     2: {


     3: protected void Page_Load(object sender, EventArgs e)


     4: {


     5: // without this step asp.net 2.0 will always generates new session id


     6: if (Session["ActiveSessionID"] == null)


     7: {


     8: Session["ActiveSessionID"] = Session.SessionID;


     9: }


     10:  


     11: HttpCookie activSessionCookie = Request.Cookies["ActiveSessionID"];


     12: if (activSessionCookie == null)


     13: {


     14: HttpCookie cookie = new HttpCookie("ActiveSessionID", Session.SessionID);


     15: cookie.Expires = DateTime.Now.AddDays(1);


     16: Response.Cookies.Add(cookie);


     17: }


     18: else if (activSessionCookie.Value != Session.SessionID)


     19: {


     20: Response.Write("this is new window");


     21: }


     22: }


     23: }


    أسهل طريقة لمنع المستخدم من تشغيل أكثر من نسخة من البرنامج

     1: static class Program


     2: {


     3: private const string concurrencyMtxNameM = @"onlyOne"; 


     4: static bool firstInstance = false;


     5: static Mutex concurrencyMtxM;


     6:  


     7: [STAThread]


     8: static void Main()


     9: {


     10: concurrencyMtxM = new Mutex(true, concurrencyMtxNameM, out firstInstance);


     11:  


     12: if (!firstInstance)


     13: {


     14: MessageBox.Show("Only one instance allowed");


     15: return;


     16: }


     17: Application.EnableVisualStyles();


     18: Application.SetCompatibleTextRenderingDefault(false);


     19: Application.Run(new Form1());


     20: }


     21: }




    المصدر : . NET - How to prevent running multiple instances of the same application


    ملاحظة: الوصلة باللغة الإيطالية يمكنك استخدام مترجم جوجل لقراءتها باللغة الانجليزية

    يوم في حياة صفحة ASP.NET

    كم من صفحة ASP.NET بنيتُها ثم تركتاها ولم أعلم عنها شئ بعد ذلك، ياترى ماذا تفعل الآن وإن طلبها المستخدم أمازلت تلبي النداء أم أن شئ ما في يومها تكدر فلم تعد تجيب النداء وبدلاً من أن أفكر في كل صفحة بعد بنائها قررت أن أعرف كيف تقضي أي صفحة ASP.NET يومها حتى لا أكدره عليها بالخطأ أثناء بنائي إياها وأليكم مذكرات يوم في حياة صفحة ASP.NET

    لا تبادر أي صفحة ASP.NET ببدء يومها من نفسها بل يعتمد بداية يومها على طلب المستخدم لها وعلى الرغم من عدم قدرتها على التنبؤ بالوقت الذي ستبدأ فيها يومها – أو قل وقت استيقاظها – إلا إنها تعرف تمام المعرفة الأماكن التي عليها أن تمر عليها كل يوم، واستحييت أن أكون أنا مبرمجها ولست على نفس درايتها بالأماكن التي تمر فيها والغرف التي تقضي فيها وقتها ففضلت البدء بمعرفة الغرف التي تقضي الصفحة فيها وقتها ثم استطلع كل غرفة جيدا ثم بعد ذلك أعطي لها أمر بالاستيقاظ وأراقبها أثناء مرورها على كل هذه الأماكن  لأتعرف بالتفصيل على رحلتها اليومية وسأبدأ بسرد ما علمته عن الغرف التي تقضي فيها وقتها وهي كالتي : [MORE]

    1- غرفة ال IIS

            وعزمت في هذه الغرفة إلا أخرج إلا بعد أن أفهم الآتي :

            - نظرة عامة

            - ماذا يحدث تحت الغطاء

    أما عن النظرة العامة

    فهذه الغرفة هي المكان المختص باستقبال طلبات تشغيل صفحة ويب معينة والمسئول عن خدمة هذه الطلبات هو خادم   Internet Information Services (IIS) وهو يعتبر الوسيط الذي لا غنى عنه بين المستخدم وبين موقع الانترنت وذلك لأنه يستطيع التعامل مع المستخدم وطلباته ويعرف كيفية الرد عليه بالأسلوب الذي يفهمه المستخدم وفي نفس الوقت قادر على التعامل مع ملفات موقع الانترنت بما يناسبها ونقل نتيجة تشغيلها إلي المستخدم ، ولا تقتصر خدماته على صفحات ASP.NET فقط بل تمتد إلي Classic ASP و HTML وأي تقنيه تدعم IIS وأولى ملاحظاتي على هذه الغرفة كانت كما يلي :

    -    لن يتمكن أي طلب لصفحة ويب من المرور إلا عن طريق توجيه طلبه إلي IIS  وإلا فلا يمكن خدمته.

    -    ليس هناك إلا طريق واحد فقط لطلب تشغيل صفحة عن طريق IIS وهو ما يطلق عليه ال HTTP Request يكون محدد فيه عنوان الصفحة المستهدفة بالإضافة إلي معلومات أخرى.

    -    أي نتيجة تخرج من IIS إلي المستخدم يجب أن تخرج في HTTP Response يحتوى نتيجة طلب المستخدم

    -    تعمل جميع إصدارات IIS التي تسبق IIS 6.0 تحت اسم inetinfo.exe أما في حالة IIS 6.0 فأنه يعمل تحت اسم w3wp.exe

    أما عن ما يجدث تحت الغطاء فكان كالتالي

    يستطيع ال IIS تمييز الصفحات عن طريق الامتداد الخاص بها مثل .html  .asp .aspx وبالتالي تغيير طريقة تعامله مع الصفحة بما يناسب التقنية المبنية بها، وتغيير طريقة تعامله هي أكثر من مجرد ثلاث كلمات لذا استوقفني قليلاً فقد سألت نفسي أربع أسئلة وهم كالتالي

         1-    ماذا لو ظهرت لغة جديدة ولتكن XSP لتطوير صفحات ويب فكيف سيغير IIS طريقة تعامله مع الصفحات المبنية بهذه اللغة وهو لم يكن يعرف بها من قبل

    2-     ما هي الخطوات التي يتبعها IIS لمعالجة طلبات تشغيل الصفحات المختلفة ؟

    3- هل يستطيع IIS حجب بعض الصفحات أو الملفات عن المستخدم حتى وإن كانت موجودة عنده  ؟ وهل يمكنني أن أضبطه بحيث يحجب ملفات خاص بي لا أرغب في أن يطلع عليها المستخدم ؟

          4- كيف سيتصرف IIS إذا تعرف على امتداد صفحة وكان .aspx وعرف أنها ستعمل على ASP.NET وكان هناك نسختين مركبتين منها وهما ASP.NET 1.1 & ASP.NET 2.0

    وإجابة السؤال الأول "ماذا لو ظهرت لغة جديدة " كانت كالتالي

    علمت مايكروسوفت أنها لن تستطيع أن توفر كل الدعم المطلوب لجميع لغات البرمجة الموجودة والمستحدثة لذا فقد طورت مايكروسوفت نظام Internet Server Application Programming Interface (ISAPI) Extension وهو نظام يهدف إلي إكساب IIS القدرة على توسعة إمكانياته ، بحيث يمكن لأي مبرمج تطوير ISAPI Extension جديد والحاقة بال IIS بحيث يكسب IIS القدرة على التعامل مع أنواع ملفات جديدة لم يكن ال IIS يعلم عنها شيئاً قبل ذلك، وأوضح الأمثلة العملية على ذلك هي ال ASP.NET نفسها فال.NET Framework أثناء تركيبه يلحق ISAPI Extension خاص بال ASP.NETوهو aspnet_isapi.dll بحيث يكسب ال IIS القدرة على معالجة الصفحات المبنية بتقنية ال .NET ويمكن توضيح الفرق قبل تركيب aspnet_isapi وبعد تركيبه وأثر تركيبه على IIS عن طريق الشكلين التاليين :

    IIS_Without_ISAPI_Extentsion_2
    ------------------------------------------------------------------------------------------------
    IIS_With_ISAPI_Extentsion_2

    لعل وظيفة ISAPI Extension تكون قد اتضحت الآن فهو من أكسب IIS القدرة على التعامل مع ملفات ASP.NET والوافد الجديد علينا في الشكل الثاني هو aspnet_wp وهو عبارة عن المحرك الرئيسي لتشغيل ASP.NET فكل ما يفعله aspnet_isapi بعد استلامه أمر تشغيل صفحة معينة أن يناول هذا الأمر إلي العملية المسماة ASP.NET Worker Process (aspnet_wp ) بحيث تتولى هي كل ما يلزم فعله حتى يتم خدمة هذا الطلب وسنتعرض لها بالتفصيل في المقالة القادمة إن شاء الله لأنها هي الغرفة الثانية التي تدخلها أي صفحة ASP.NET

    أما عن "ما هي الخطوات التي يتبعها IIS لمعالجة طلبات تشغيل الصفحات المختلفة ؟" فإجابته كالتالي :

    1- عن طريق HTTP Request يحدد IIS امتداد الصفحة المطلوبة سواء كان aspx , asp , html ويحدد أيضاً اسم الموقع الموجود به هذه الصفحة

    2- يُعلم IIS جميع ال ISAPI Filters الملحقة به بوصول HTTP Request جديد ويمرر هذا الطلب على جميع المرشحات ISAPI Filters

    3- يذهب IIS إلي ScriptMaps خاصة بالموقع المطلوب ويعرف من هذه الخرائط ال ISAPI Extension المناسب لتشغيل هذا الامتداد داخل هذا الموقع

    4- يوجه IIS طلباً مباشراً إلي ISAPI Extension المستهدف بتشغيل الصفحة المرادة عن طريق أمر مثل هذا Http://Server_Name/MyISAPIExtension.dll?TargetURL

    5- بعد استقبال نتيجة تشغيل الصفحة من ال ISAPI Extension يُعلم IIS جميع ال ISAPI Filters بأن هناك HTTP Response على وشك الإرسال إلي المستخدم ويمرره عليهم جميعاً

    6- يرسل IIS نتيجة تشغيل الصفحة في HTTP Response إلي المستخدم

    ولعل هناك تساؤل عن كلمتين جديدتين وهما ISAPI Filters و ScriptMaps وكل واحدة من منهما هي إجابة للسؤالين الثالث والرابع ، لذا لنستعرض كل سؤال

    فالسؤال الثالث كان "هل يستطيع IIS حجب بعض الصفحات أو الملفات عن المستخدم حتى وإن كانت موجودة عنده  ؟ وهل يمكنني أن أضبطه بحيث يحجب ملفات خاص بي لا أرغب في أن يطلع عليها المستخدم ؟"

    فإجابة هذا السؤال هي نعم يستطيع IIS حجب ما يشاء من صفحات وملفات عن مستخدم بعينه أو حتى كل المستخدمين وذلك عن طريق ISAPI Filters فكما سبق توضيحه فإن أي HTTP Request & HTTP Response  داخل أو خارج يمر على جميع ال HTTP Filters الملحقة ب IIS وإن قرر أحد تلك المرشحات أن يحجب النتيجة عن المستخدم فلن يتم إرسال أي نتيجة إليه ولا يمرر IIS طلب المستخدم دفعة واحدة على كل المرشحات بل يمرر الطلب على مرشح تلو الآخر على حسب الأولوية المسجل بها هذا المرشح وإن تساووا في في الأولوية فأنه يمرر على  على حسب ترتيب تسجيل هذا المرشح داخل IIS  وإن كان هناك حاجة لحجب محتويات معينة عن المستخدمين يمكن بسهولة أن نطور ISAPI Filter خاص بنا يتولى ترشيح الطلبات قبل وصولها إلي موقعنا ويمكن إضافة وحذف وتعديل ترتيب التسجيل لأي ISAPI Filter عن طريق هذه الشاشة 
    ISAPI_Filters_2
    والتي يمكن الحصول عليها بإتباع المسار التالي

    Control Panel >Administrative Tools > Internet Information Services > [Server Name] > Default Websites > Mouse Right Click > Properties > ISAPI Filters Tab

    [Server Name] هو اسم الحاسوب المركب عليه IIS

    وهذه المرشحات لا تستطيع تشغيل أي صفحة بل كل حدودها في حجب الطلبات أو إعادة كتابة عنوان الصفحة سواء القادم من المستخدم أو المرسل إليه ويمكن التوضيح بالمثالين التاليين

    *** عنوان قادم من المستخدم مكتوب فيه HTTP://www.MySite.com/MyPage.aspx/UserName/Ahmed يمكن للمرشحات أن تعيد كتابة العنوان بالشكل التالي

    HTTP://www.MySite.com/MyPage.aspx?UserName=Ahmed وبالتالي سيأخذ IIS هذا العنوان الجديد ويناوله إلي ال ISAPI Extension المناسب لمعالجة هذا العنوان

    *** المثال الآخر هو في حالة إرسال عنوان صفحة في HTTP Response فالطبيعي أن يكون العنوان المرسل إلي المستخدم كالتالي HTTP://www.MySite.com/YourPage.aspx وقد نحتاج إن لا نعلم المستخدم بالتقنية المستخدمة في تطوير الموقع فيمكننا عن طريق ISAPI Filter أن نعيد كتابة العنوان قبل إرساله إلي المستخدم ليصبح HTTP://www.MySite.com

    ويمكن تلخيص وظيفة ISAPI Filters في هذ الشكل

    IIS_Without_ISAPI_Extentsion_And_Filters_2

    ننتقل الآن لتوضيح ال ScriptMaps وفي نفس الوقت الإجابة على السؤال الرابع والأخير والذي كان  "كيف سيتصرف IIS إذا تعرف على امتداد صفحة وكان .aspx وعرف أنها ستعمل على ASP.NET وكان هناك نسختين مركبتين منها وهما ASP.NET 1.1 & ASP.NET "

    قبل أن يوجه IIS طلب المستخدم للتشغيل عليه أن يقرأ أولاً ال ScriptMaps الخاصة بالموقع الذي تعمل بداخله الصفحة المرادة لأن كل موقع له ScriptMaps توضح امتدادات الملفات المدعمة من قبله وال ISAPI Extension المناسب لتشغيل كل امتداد لذا فلو كان هناك موقعين يعملان ب ASP.NETولكن لكل موقع إصدارة مختلفة من إصدارات ال ASP.NET فهذا يعني أن لكل موقع ScriptMaps مختلفة عن الآخر وهذا ما سيمنع تضارب تشغيل الصفحات بين الموقعين وعملية تسجيل هذه البيانات في ال ScriptMaps تسمى Script Mapping أو Application Mapping أيهما صحيح ويمكنك الإطلاع على ScriptsMaps الخاصة بكل موقع عن طريق هذه الشاشة 
    Application_Mapping_2

    والتي يمكن الحصول عليها بإتباع المسار التالي

    Control Panel >Administrative Tools > Internet Information Services > [Server Name] > Default Websites > [Any Web Site] > Mouse Right Click > Properties > Virtual Directory Tab > Configuration Button

    أما عن ماذا يحدث بعد أن يوجه IIS أمر تشغيل مباشر إلي  aspnet_isapi Extension وكيف يناوله aspnet_isapi إلي aspnet_wp.exe وماذا يحدث داخل aspnet_wp فهذا ما سنتعرف عليه في المقالة القادمة إن شاء الله "داخل غرفة aspnet_wp"

    --------------------------------------------------------------------------------------------------

    ملاحظة

    على الرغم من الكلام في المقال أنصب على IIS فقط إلا أنه ينطبق على أي خادم ويب يدعم ASP.NET

    مصادر للاستزادة عن IIS (كل وصلة مربوطة بمقال عن IIS و علاقته ASP.NET)

    نظرة عامة على IIS 6.0 ، صفحة IIS الرئيسية على مايكروسوفت ، www.iis-resources.com، msdn.microsoft.com