
تتناول هذه المقالة كيف قررنا مرة واحدة تحسين الأداة الداخلية SelfTester قليلاً ، والتي تستخدم للتحقق من جودة محلل PVS-Studio. كان التحسن بسيطًا وبدا مفيدًا ، لكنه خلق الكثير من المشكلات بالنسبة لنا ، وبعد ذلك اتضح أنه سيكون من الأفضل إذا لم نفعل ذلك.
SelfTester
نحن نقوم بتطوير وتعزيز محلل الشفرة الثابتة PVS-Studio لنظام C و C ++ و C # و Java. للتحقق من جودة المحلل ، نستخدم الأدوات الداخلية التي تسمى مجتمعة SelfTester. كل لغة من اللغات المدعومة لها نسختها الخاصة من SelfTester. يرجع ذلك إلى ميزات الاختبار ، وهو أكثر ملاءمة. وبالتالي ، في الوقت الحالي ، تستخدم شركتنا ثلاث أدوات SelfTester داخلية لـ C \ C ++ و C # و Java ، على التوالي. بعد ذلك ، سأتحدث عن إصدار Windows من SelfTester لمشاريع Visual Studio C \ C ++ ، وسميته ببساطة SelfTester. كان هذا الاختبار هو الأول في خط هذه الأدوات الداخلية ، فهو الأكثر تقدماً والأكثر تعقيدًا على الإطلاق.
كيف يعمل SelfTester؟ الفكرة بسيطة: خذ مجموعة من مشاريع الاختبار (نستخدم مشاريع حقيقية مع شفرة مفتوحة المصدر) وتحليلها باستخدام PVS-Studio. نتيجة لذلك ، يتم إنشاء سجل تحذير محلل لكل مشروع. تتم مقارنة هذا السجل مع السجل
المرجعي للمشروع نفسه. عند مقارنة السجلات ، يقوم SelfTester بإنشاء
سجل مقارنة للسجلات في نموذج مناسب للمطورين لإدراكه.
بعد دراسة دفتر السجل ، يقوم المطور بإجراء استنتاج حول التغييرات في سلوك المحلل: عدد وطبيعة التحذيرات ، وسرعة التشغيل ، وهناك أخطاء محلل داخلي ، إلخ. كل هذه المعلومات مهمة للغاية ، فهي تتيح لك فهم مدى أداء المحلل لوظائفه.
استنادًا إلى سجل مقارنة السجل ، يقوم المطور بإجراء تغييرات على جوهر المحلل (على سبيل المثال ، عند إنشاء قاعدة تشخيص جديدة) ، والتحكم فورًا في تأثير تعديلاته. إذا لم يعد لدى المطور أسئلة حول المقارنة التالية للسجلات ، فيجعله سجل التحذير
الحالي للمشروع
مرجعًا . خلاف ذلك ، يستمر العمل.
لذلك ، تتمثل مهمة SelfTester في العمل مع مجموعة من مشاريع الاختبار (بالمناسبة ، يوجد بالفعل أكثر من 120 منها لـ C / C ++). يتم اختيار مشاريع التجمع كحلول Visual Studio. يتم ذلك من أجل اختبار المحلل بالإضافة إلى ذلك على إصدارات مختلفة من Visual Studio التي يدعمها المحلل (من Visual Studio 2010 إلى Visual Studio 2019 في الوقت الحالي).
ملاحظة : سأفصل بين مفاهيم
الحل والمشروع ، وفهم المشروع كجزء من الحل ، كما هو معتاد في Visual Studio.
واجهة SelfTester تشبه:
على اليسار قائمة من الحلول ، على اليمين توجد نتائج الاختبار لكل إصدار من Visual Studio.
تشير علامات "غير مدعومة" الرمادية إلى أن الحل لا يدعم الإصدار المحدد من Visual Studio أو أنه لم يتم تحويله لهذا الإصدار. تحتوي بعض الحلول في التجمع على إعداد يشير إلى إصدار محدد من Visual Studio للتحقق. إذا لم يتم تحديد الإصدار ، فسيتم تحديث الحل لجميع الإصدارات اللاحقة من Visual Studio. مثال على هذا الحل في لقطة الشاشة هو "smart_ptr_check.sln" (تم إجراء التحقق لجميع إصدارات Visual Studio).
تشير علامة "موافق" الخضراء إلى أن الفحص التالي لم يكشف عن أي اختلافات في السجل المرجعي. تشير علامة Diff الحمراء إلى الاختلافات. يجب على المطور الاهتمام بهذه التسميات. للقيام بذلك ، يحتاج إلى النقر نقرًا مزدوجًا على الملصق المطلوب. سيتم فتح الحل المحدد في الإصدار المرغوب من Visual Studio ، وسيتم أيضًا فتح نافذة بها سجل تحذير. تتيح لك أزرار التحكم الموجودة أدناه إعادة تشغيل تحليل القرارات المحددة أو جميع القرارات ، وتعيين السجل المحدد (أو الكل في آن واحد) للأخرى القياسية ، إلخ.
يتم تكرار النتائج المقدمة لعمل SelfTester دائمًا في تقرير html (سجل الفرق).
بالإضافة إلى واجهة المستخدم الرسومية ، يحتوي SelfTester أيضًا على أوضاع تلقائية للتشغيل أثناء عمليات الإنشاء الليلية. ومع ذلك ، يتم تكرار نمط الاستخدام المعتاد من قبل المطور خلال يوم العمل. لذلك ، واحدة من الخصائص الهامة ل SelfTester هي
سرعته .
لماذا السرعة مهمة:
- للتشغيل أثناء الاختبارات الليلية ، يعد الوقت المستغرق لإكمال كل خطوة أمرًا بالغ الأهمية. من الواضح أنه كلما كانت الاختبارات أسرع ، كان ذلك أفضل. ومتوسط وقت تشغيل SelfTester يتجاوز حاليا ساعتين ؛
- عند إطلاق SelfTester خلال اليوم ، يتعين على المطور الانتظار أقل للنتيجة ، مما يزيد من إنتاجية العمل.
كانت الرغبة في تسريع عمل SelfTester هي التي تسببت في التحسينات هذه المرة.
multithreading في SelfTester
تم إنشاء SelfTester في الأصل كتطبيق متعدد الخيوط مع إمكانية التحقق من حلول متعددة بشكل متوازٍ. كان القيد الوحيد هو أنه لا يمكنك التحقق من نفس الحل في وقت واحد لإصدارات مختلفة من Visual Studio ، لأن العديد من الحلول تحتاج إلى تحديث لإصدارات معينة من Visual Studio قبل التدقيق. خلال هذا ، يتم إجراء التغييرات مباشرةً على
ملفات مشروع
.vcxproj ، مما يؤدي إلى حدوث أخطاء عند التشغيل بالتوازي.
لجعل العمل أكثر كفاءة ، يستخدم SelfTester جدولة مهمة ذكية ، والتي تتيح لك تعيين قيمة محدودة للغاية للخيوط المتوازية والحفاظ عليه.
يتم استخدام المجدول على مستويين. الأول هو مستوى
الحل ، والذي يُستخدم لبدء التحقق من الحل
.sln باستخدام
الأداة المساعدة PVS-Studio_Cmd.exe . داخل
PVS-Studio_Cmd.exe (على مستوى التحقق من
ملفات التعليمات البرمجية المصدر) يتم استخدام نفس المجدول ، ولكن مع
درجة مختلفة
من إعداد
التوازي .
درجة التوازي هي معلمة تشير فعليًا إلى عدد مؤشرات الترابط المتوازية التي يجب تشغيلها في وقت واحد. لقيم درجة التوازي على مستوى القرار والملفات ، تم اختيار القيم الافتراضية
لأربعة وثمانية ، على التوالي. وبالتالي ، يجب أن يكون عدد مؤشرات الترابط الموازية لهذا التطبيق مساوياً لـ 32 (أربعة حلول تم اختبارها في وقت واحد وثمانية ملفات). هذا الإعداد يبدو لنا هو الأمثل للمحلل للعمل على معالج ثمانية النواة.
يمكن للمطور تعيين قيم أخرى لدرجة التوازي بشكل مستقل ، مع التركيز على أداء جهاز الكمبيوتر الخاص به أو المهام الحالية. إذا لم يقم بتعيين هذه المعلمة ، فسيتم اختيار عدد المعالجات المنطقية للنظام افتراضيًا.
ملاحظة : علاوة على ذلك ، سنعتبر أن العمل يتم وفق الدرجة الافتراضية لقيم التوازي.
يتم
جدولة LimitedConcurrencyLevelTaskScheduler جدولة من
System.Threading.Tasks.TaskScheduler وتنقيحها لتوفير الحد الأقصى من مستوى التوازي عند العمل على أعلى
ThreadPool . التسلسل الهرمي الميراث:
LimitedConcurrencyLevelTaskScheduler : PausableTaskScheduler { .... } PausableTaskScheduler: TaskScheduler { .... }
PausableTaskScheduler يسمح
لك بإيقاف المهام مؤقتًا ، و
LimitedConcurrencyLevelTaskScheduler ، بالإضافة إلى ذلك ، يوفر تحكمًا ذكيًا في قائمة انتظار المهام وجدولة تنفيذها ، مع مراعاة درجة التوازي وكمية المهام المجدولة وعوامل أخرى. يتم استخدام المجدول عند بدء تشغيل مهام
System.Threading.Tasks.Task .
متطلبات التحسين
تنفيذ العمل الموصوف أعلاه له عيب: إنه ليس الأمثل عند العمل مع حلول من مختلف الأحجام. وحجم الحلول في تجمع الاختبار مختلف تمامًا: من 8 كيلو بايت إلى 4 جيجابايت لحجم المجلد مع الحل ، ومن واحد إلى عدة آلاف من ملفات التعليمات البرمجية المصدر في كل منها.
يصطف المجدول القرارات ببساطة بالترتيب ، دون أي مكون فكري. اسمحوا لي أن أذكرك أنه افتراضيًا ، لا يمكن التحقق من أكثر من أربعة حلول في نفس الوقت. إذا تم فحص أربعة حلول كبيرة في الوقت الحالي (عدد الملفات في كل منها أكثر من ثمانية) ، فمن المفترض أننا نعمل بكفاءة ، حيث أننا نستخدم الحد الأقصى لعدد الخيوط الممكنة (32).
لكن تخيل موقفًا شائعًا إلى حد ما عند اختبار العديد من الحلول الصغيرة. على سبيل المثال ، أحد الحلول كبير ويحتوي على 50 ملفًا (سيتم تضمين ثمانية مؤشرات ترابط كحد أقصى) ، ويحتوي الثلاثة الآخر على ثلاثة وأربعة وخمسة ملفات لكل منها. في هذه الحالة ، نستخدم فقط 20 مؤشر ترابط (8 + 3 + 4 + 5). نحصل على قلة استخدام وقت المعالج وانخفاض الأداء الكلي.
ملاحظة : في الواقع ، لا يزال عنق الزجاجة ، كقاعدة عامة ، هو النظام الفرعي للقرص ، وليس المعالج.
التحسينات
أحد التحسينات التي تقترح نفسها في هذه الحالة هو ترتيب قائمة الحلول المقدمة للتحقق منها. من الضروري تحقيق الاستخدام الأمثل لعدد معين من سلاسل العمليات المنفذة في وقت واحد (32) من خلال تقديم مشاريع تحتوي على العدد "الصحيح" من الملفات للتحقق.
دعونا نلقي نظرة على مثالنا مرة أخرى ، عندما يتم فحص أربعة حلول بعدد الملفات التالية في كل: 50 و 3 و 4 و 5. من المحتمل أن تنجح المهمة التي تتحقق من حل من
ثلاثة ملفات قريبًا. وبدلاً من ذلك ، سيكون من الأفضل إضافة حل به ثمانية ملفات أو أكثر (من أجل استخدام ثمانية تدفقات متاحة كحد أقصى لهذا الحل). ثم في المجموع سنستخدم بالفعل 25 موضوع (8 +
8 + 4 + 5). ليس سيئا ومع ذلك ، لا تزال هناك سبعة خيوط غير مستخدمة. وهنا تنشأ فكرة تحسين آخر ، تتعلق بإزالة القيود المفروضة على أربعة خيوط للتحقق من الحلول. في الواقع ، في المثال أعلاه ، يمكنك إضافة واحد ، ولكن العديد من الحلول ، باستخدام أكبر عدد ممكن من المواضيع 32. دعونا نتخيل أن لدينا حلين آخرين ، ثلاثة وأربعة ملفات لكل منهما. تؤدي إضافة هذه المهام إلى إغلاق "الفجوة" تمامًا في سلاسل العمليات غير المستخدمة ، وسيكون هناك 32 (8 + 8 + 4 + 5 +
3 +
4 ).
أعتقد أن الفكرة واضحة. في الواقع ، فإن تنفيذ هذه التحسينات لم يتطلب الكثير من الجهد. تم كل شيء في يوم واحد.
كان من الضروري تحسين فئة المهمة: الميراث من
System.Threading.Tasks.Task وإضافة حقل "الوزن". لتعيين وزن الحل ، يتم استخدام خوارزمية بسيطة: إذا كان عدد الملفات في الحل أقل من ثمانية ، فسيتم تعيين الوزن مساوًا لهذه القيمة (على سبيل المثال ، 5) ، إذا كان عدد الملفات أكبر من ثمانية أو يساويها ، فسيتم اختيار الوزن يساوي ثمانية.
كان من الضروري أيضًا صقل برنامج الجدولة: لتعليمه اختيار الحلول بالوزن المناسب لتحقيق أقصى قيمة لـ 32 سلسلة. كان من الضروري أيضًا السماح بتخصيص أكثر من أربعة خيوط للتحقق في وقت واحد من الحلول.
أخيرًا ، استغرق الأمر خطوة أولية لتحليل جميع حلول البلياردو (التقييم باستخدام MSBuild API) لحساب وضبط أوزان الحلول (احصل على عدد الملفات مع الكود المصدري).
يؤدي
أعتقد ، بعد هذه المقدمة الطويلة ، لقد خمنت بالفعل أن النتيجة كانت صفر.
من الجيد أن التحسينات كانت بسيطة وسريعة.
حسنًا ، الآن ، في الواقع ، يبدأ الجزء من المقالة حول "خلق الكثير من المشكلات لنا" ، وهذا كل شيء.
آثار جانبية
لذلك ، نتيجة سلبية هي أيضا نتيجة. اتضح أن عدد الحلول الكبيرة في المجموعة يتجاوز
بشكل كبير عدد الحلول الصغيرة (أقل من ثمانية ملفات). في ظل هذه الظروف ، لا يكون للتحسينات التي تم إجراؤها تأثير ملحوظ ، نظرًا لأنها غير مرئية من الناحية العملية: يستغرق التحقق منها وقتًا مجهريًا مقارنة بالمشاريع الكبيرة.
ومع ذلك ، فقد تقرر ترك المراجعة كـ "لا تتدخل" وربما تكون مفيدة. بالإضافة إلى ذلك ، يتم تجديد مجموعة حلول الاختبار باستمرار ، لذلك في المستقبل ، ربما ، سيتغير الوضع.
وبعد ذلك ...
أحد المطورين اشتكى من "سقوط" SelfTester. حسنا ، هذا يحدث. لمنع فقدان هذا الخطأ ، تم إطلاق حادث داخلي (تذكرة) باسم "استثناء عند العمل مع SelfTester". حدث الخطأ أثناء تقييم المشروع. صحيح أن مثل هذه الوفرة من النوافذ تشهد على المشكلة أيضًا في معالج الأخطاء. لكن سرعان ما تم القضاء على هذا الأمر ، وعلى مدار الأسبوع المقبل ، لم يتم كسر أي شيء. فجأة ، اشتكى مستخدم آخر من SelfTester. ومرة أخرى إلى خطأ تقييم المشروع:
يحتوي المكدس هذه المرة على مزيد من المعلومات المفيدة - خطأ في تنسيق XML. ربما ، أثناء معالجة ملف المشروع
Proto_IRC.vcxproj (تمثيل xml الخاص به) ، حدث شيء ما للملف نفسه ، لذلك تعذر على
XmlTextReader معالجته .
إن وجود خطأين في فترة زمنية قصيرة إلى حد ما جعلنا نلقي نظرة فاحصة على المشكلة. بالإضافة إلى ذلك ، كما قلت أعلاه ، يستخدم SelfTester بنشاط كبير من قبل المطورين.
بادئ ذي بدء ، تم إجراء تحليل لآخر مكان للسقوط. لسوء الحظ ، لا يمكن تحديد أي شيء مشبوه. فقط في حالة طلبوا من المطورين (مستخدمي SelfTester) أن يكونوا في حالة تأهب وأن يبلغوا عن الأخطاء المحتملة.
نقطة مهمة: تم إعادة استخدام الكود الذي حدث فيه الخطأ في SelfTester. في البداية ، يتم استخدامه لتقييم المشاريع في المحلل نفسه (
PVS-Studio_Cmd.exe ). هذا هو السبب في تزايد الاهتمام بالمشكلة. ومع ذلك ، لم تحدث قطرات مماثلة في محلل.
وفي الوقت نفسه ، تم تجديد تذكرة حول مشاكل SelfTester بأخطاء جديدة:
ومرة أخرى
XmlException . من الواضح ، في مكان ما ، توجد مؤشرات ترابط متنافسة تعمل على قراءة وكتابة ملفات المشروع. يعمل SelfTester مع المشاريع في الحالات التالية:
- تقييم المشروعات أثناء الحساب الأولي لأوزان القرار: خطوة جديدة أثارت الشك في البداية ؛
- ترقية المشروعات إلى الإصدارات الضرورية من Visual Studio: يتم تنفيذها مباشرة قبل التحقق (لا تتقاطع المشروعات بأي طريقة) ويجب ألا تؤثر على العمل ؛
- تقييم المشروعات أثناء التحقق: آلية أمان مؤشر الترابط التي تم تصحيحها ، والتي تم إعادة استخدامها من PVS-Studio_Cmd.exe ؛
- استرداد ملفات المشروع (استبدال ملفات .vcxproj المعدلة بالملفات المرجعية الأصلية) عند الخروج من SelfTester ، حيث يمكن تحديث ملفات المشروع إلى الإصدارات الضرورية من Visual Studio في العملية: الخطوة الأخيرة ، والتي لا تؤثر أيضًا على الآليات الأخرى.
وقع الشك في الكود الجديد المضاف للتحسين (حساب الأوزان). لكن أظهرت دراسة هذا الكود أنه إذا بدأ المستخدم التحليل فور بدء SelfTester ، فإن المختبر كان دائمًا ينتظر بشكل صحيح نهاية التقييم الأولي. هذا المكان بدا آمنا.
مرة أخرى ، لم نتمكن من تحديد مصدر المشكلة.
ألم
خلال الشهر المقبل ، واصلت SelfTester في الانخفاض من وقت لآخر. تمت تعبئة البطاقة بالبيانات ، لكن لم يكن من الواضح ما يجب فعله بهذه البيانات. كانت معظم الأعطال كلها مع نفس
XmlException . من حين لآخر كان هناك شيء آخر ، ولكن على نفس الرمز المعاد استخدامه من
PVS-Studio_Cmd.exe .
وفقًا للتقاليد ، لا يتم فرض متطلبات عالية على الأدوات الداخلية ، لذلك تم إجراء أخطاء SelfTester على أساس متبقي. من وقت لآخر ، قام أشخاص مختلفون بالاتصال (طوال فترة الحادث ، عمل ستة أشخاص على المشكلة ، بما في ذلك متدربان متدربان). ومع ذلك ، يجب أن يصرف المهمة.
خطأنا الأول. في الواقع ، هنا كان من الممكن بالفعل حل المشكلة مرة واحدة وإلى الأبد. كيف؟ كان من الواضح أن الخطأ نتج عن تحسين جديد. بعد كل شيء ، وقبل ذلك ، كان كل شيء يعمل بشكل جيد ، ومن الواضح أن إعادة استخدام الرمز لا يمكن أن يكون سيئًا للغاية. علاوة على ذلك ، لم يحقق هذا التحسين أي فوائد. إذن ما الذي يجب عمله؟
إزالة هذا التحسين . كما تعلمون ، لم يتم ذلك. واصلنا العمل على مشكلة خلقتها نحن أنفسنا. استمر البحث عن إجابة السؤال: "كيف ؟؟؟" كيف تسقط؟ ومع ذلك يبدو أن تكون مكتوبة بشكل صحيح.
خطأنا الثاني. تم
ربط أشخاص آخرين بحل المشكلة. خطأ كبير جدا جدا. لسوء الحظ ، لم يحل هذا المشكلة فحسب ، بل تم إنفاق موارد إضافية. نعم ، جلب أشخاص جدد أفكارًا جديدة ، ولكن لتنفيذها استغرق الأمر الكثير من وقت العمل. في مرحلة معينة ، تمت كتابة برامج الاختبار (بواسطة نفس المتدربين) التي تحاكي تقييم المشروع نفسه في مؤشرات ترابط مختلفة مع التعديل الموازي للمشروع في سلسلة رسائل أخرى. لم يساعد. بالإضافة إلى ما كنا نعرفه من قبل ، فإن واجهة برمجة تطبيقات MSBuild آمنة داخل الخيط ، ولم تكتشف أي شيء جديد. وفي SelfTester ، تمت إضافة تفريغ صغير عند طرح
XmlException . ثم كل هذا شخص مشوش ، رعب. عقدت مناقشات ، تم القيام بالعديد من الأشياء الأخرى غير الضرورية.
وأخيرا ، خطأنا الثالث . هل تعرف كم من الوقت مضى منذ نشأت مشكلة SelfTester حتى تم حلها؟ على الرغم من لا ، عد نفسك. تم إنشاء الحادث في 09/17/2018 وأغلق في 02/20/2019 ، وهناك أكثر من 40 (أربعين!) رسائل هناك. يا شباب ، هذا كثير من الوقت!
سمحنا لأنفسنا أن نفعل ذلك
لمدة خمسة أشهر. في الوقت نفسه (بالتوازي) ، شاركنا في دعم Visual Studio 2019 ، بإضافة لغة Java ، وبدأنا في تطبيق معيار MISRA C / C ++ ، وحللنا محلل C # ، وشاركنا بنشاط في المؤتمرات ، وكتبنا مجموعة من المقالات ، إلخ. ولم تحصل كل هذه الأعمال على وقت المطورين بسبب الخطأ الغبي SelfTester.
أيها المواطنون ، نتعلم من أخطائنا ولا نفعل ذلك أبدًا. ونحن لن نفعل ذلك.
لدي كل شيء.
بالطبع ، هذه مزحة ، وسأخبرك ما هي مشكلة SelfTester :)
البنغو!
لحسن الحظ ، كان بيننا شخص أقل وعياً غائمًا (زميلي سيرجي فاسيلييف) ، الذي نظر إلى المشكلة من زاوية مختلفة تمامًا (وكان محظوظًا أيضًا). ماذا لو كان داخل SelfTester حقًا ، والمشاريع تقطع شيئًا من الخارج؟ بالتوازي مع SelfTester ، عادةً لا يبدأ أي شيء ، وفي بعض الحالات نسيطر بشدة على وقت التشغيل. في هذه الحالة ، يمكن أن يكون هذا "الشيء" فقط SelfTester نفسه ، ولكن مثال آخر منه.
عند الخروج من SelfTester ، يستمر تدفق ملفات مشروع الاستعادة من المعايير في العمل لبعض الوقت. في هذه المرحلة ، يمكنك إعادة تشغيل الاختبار. تمت إضافة الحماية ضد تشغيل مثيلات متعددة من SelfTester في نفس الوقت
لاحقًا ويبدو الآن كما يلي:
ولكن بعد ذلك ذهبت.
لا يصدق ، ما يقرب من نصف عام من العذاب لا أحد الاهتمام بها. تعد استعادة المشروعات من المعايير إجراءً سريعًا بما يكفي من الخلفية ، لكن لسوء الحظ ، ليست سريعة بما يكفي حتى لا تتداخل مع إعادة تشغيل SelfTester. وما يحدث عند بدء التشغيل؟ هذا صحيح ، حساب الأوزان القرار. تقوم إحدى العمليات بالكتابة فوق ملفات
.vcxproj ، بينما تحاول عملية أخرى قراءتها. مرحبًا ،
XmlException .
اكتشف سيرجي كل هذا عندما أضاف إلى المختبر القدرة على التبديل إلى وضع العمل مع مجموعة أخرى من السجلات القياسية. نشأت الحاجة إلى ذلك بعد إضافة قاعدة MISRA إلى المحلل. يمكنك التبديل مباشرة في الواجهة ، بينما يرى المستخدم النافذة:
بعد ذلك
إعادة تشغيل SelfTester. حسنًا ، في وقت سابق ، على ما يبدو ، قام المستخدمون بمضاهاة المشكلة بأنفسهم ، وبدءوا الاختبار مرةً أخرى.
استخلاص المعلومات والاستنتاجات
بالطبع ، قمنا بحذف ، أو بالأحرى ، قمنا بتعطيل التحسين الذي تم إنشاؤه مسبقًا. بالإضافة إلى ذلك ، كان الأمر أسهل بكثير من إجراء نوع من التزامن بين بقية المختبر نفسه. وبدأ كل شيء على ما يرام ، كما كان من قبل. وكإجراء إضافي ، تمت إضافة الحماية الموضحة أعلاه ضد الإطلاق المتزامن للاختبار.
لقد سبق أن كتبت أعلاه عن أخطائنا الرئيسية أثناء البحث عن المشكلة ، لذا فإن التبطين الذاتي يكفي. نحن أناس أيضًا ، وبالتالي نحن مخطئون. من المهم أن تتعلم من أخطائك وأن تستخلص النتائج. الاستنتاجات هنا بسيطة للغاية:
- من الضروري تتبع وتقييم نمو تعقيد المهام ؛
- توقف في الوقت المناسب ؛
- حاول أن تنظر إلى المشكلة على نطاق أوسع ، حيث إن الرؤية "غير واضحة" بمرور الوقت ، وتضييق زاوية الرؤية ؛
- لا تخف من حذف الشفرة القديمة أو غير الضرورية.
الآن بالتأكيد - هذا كل شيء. شكرا لك على القراءة لجميع رمز ميؤوس منها!

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