يقوم موقع
Daily WTF بجمع قصص مضحكة ووحشية و / أو حزينة من عالم تكنولوجيا المعلومات لمدة 14 عامًا. قمت بترجمة العديد من القصص التي بدت مثيرة للاهتمام بالنسبة لي. تم تغيير جميع أسماء الشركات والأسماء. الجزء الأول
هنا .
القصة الأولى. على الرغم من الجدة ...
[ الأصل ]قارن
كلايف بين محتويات حسابه المصرفي والسعر اليومي المقدم له ، كما يفعل العديد من المستقلين ، وقرر أنه في مثل هذه الظروف ستلائمه
أي وظيفة. بدا أحد الشواغر مقبولًا تقريبًا: احتاجت شركة التأمين إلى حزمة برامج جديدة تسمح لها بالامتثال لبعض المتطلبات القانونية. بالإضافة إلى ذلك ، احتجت الإدارة إلى شخص ما لتعليم المطورين الأدوات والتقنيات الحديثة ... على سبيل المثال ، إصدار الكود.
ذهب كلايف ببراعة خلال المقابلة وبعد أسبوع ذهب إلى العمل. كانت رسالة من شخص يدعى براندون في انتظاره في صندوق البريد. تقول: "يجب أن نلتقي".
كان براندون يجلس في مكتبه ، ملتصقًا بالكرسي المريح في منتصف تسعينيات القرن الماضي ، كما لو أنه أصبح واحداً معه. نظر إلى أعلى من الشاشة ونظر إلى كلايف. "أنت تعمل من أجلي."
في عبارات موجزة تتكون من أحاديات المقطع ، أوضح براندون أن أيا من أولئك الذين اتخذوا قرار التوظيف سيجتمع مع كلايف. كلايف هو المسؤول الوحيد أمامه.
"حسنًا ... إذن ، عندما تم تعييني ، قالوا إنهم بحاجة إلى تكوين" التخريب ". يجب أن أبدأ مع هذا؟ "طلب كلايف.
"لا"
"هل يمكنني معرفة السبب؟" هل تفضل شيئًا آخر؟ هل تريد مناقشة الخيارات؟ "
"لا"
انتظر كليف. كان براندون في عجلة من أمره ليستكشف فكره. لقد نظر إلى كليف. واصلت لمشاهدة ومشاهدة.
عاد كليف ببطء إلى مكعبه وبدأ بدراسة قاعدة الكود. كان موجودًا على مشاركة عبر شبكة ، وكان التحكم في الإصدار هو "file.pl.old" ، "file.pl.old.old". اتضح أن الكود مكتوب بلغة بيرل ، وأنه غير قابل للقراءة حتى بمعايير بيرل. نشأ وترعرع في ثقافة "إذا كانت توزع ، ستبدأ" ، ولم تحتوي على تعليقات ولم تكن لديها أي اختبارات على الإطلاق. كان حليف كليف الوحيد لي ، وهو متخصص آخر تم تعيينه
أيضًا ، وأبلغ براندون
أيضًا ، لكن كان لديه عائق لمدة أسبوعين في تحليل الشفرة. عندما علق كليف في مكان ما ، نظر من وراء جدار مكعبه وسألني.
مثل الجبل الجليدي المنحدر من الجبل ، شق Clive ببطء طريقه عبر الكود. أسبوع بعد أسبوع ، وقال انه اكتسب تدريجيا التفاهم. ثم جاءت رسالة من براندون: "نحن بحاجة للقاء".
"أنت تتداخل مع فريق التطوير" ، قال.
"ماذا؟"
"أنت ولي صاخبة للغاية. هذا مكتب وليس نادي اهتمامات ".
"هذا مجنون. أنا فقط سألته أسئلة عن العمل! "هل تريد منا أن نرتب اجتماعات في قاعة المؤتمرات فقط لطرح الأسئلة؟"
"نعم"
براندون صامت وبدأ مرة أخرى التحديق في كليف. نظر ، ونظر ... فهم كلايف التلميح وهرب إلى مكعبه.
كانت المتطلبات مربكة ومتغيرة باستمرار ، وهو ما لم يكن مفاجئًا. المستخدم الوحيد الذي عرفهم بالضبط كان كارول ، وهو ما لم يكن مفاجئًا أيضًا. أرسلها كلايف رسالة مع الأسئلة ، وحاول القيام بعمله. انتظر بضعة أيام لإجابتها ، ثم كان لديه أسئلة جديدة ، وأرسل خطابات جديدة.
في غضون أسبوع ، أرسل حوالي عشرة رسائل ، لكنه لم يتلق أي رد. بعث بأخرى جديدة لمعرفة معلومات جديدة. خلال هذا الوقت ، تراكمت المزيد من الأسئلة. حاول كلايف الاتصال بها ، لكنه صادف بريدًا صوتيًا. حاول جدولة اجتماع ، لكن كارول لم تقبل دعواته أبدًا.
ثم جاءت رسالة من براندون: "نحن بحاجة للقاء".
قالت كارول: "تقول كارول إنك تضغط عليها".
"ماذا؟"
"ترسل رسائلها ، حتى بعد إجابتها على الأسئلة. قالت إنك عقدت اجتماعًا ، لكنك لم تحضره. يجب أن يتوقف هذا. "
"هذا مجنون. لم تجب أبدًا ، يمكنني عرض صندوق الوارد الخاص بي وإثبات ذلك ".
"لا تستخدم كارول البريد الإلكتروني" ، أوضح براندون. "تقوم المتدربة بطباعة رسائل البريد الإلكتروني الخاصة بها ، وهي تجيب بالبريد الداخلي للمكتب. هي مشغول جدا. لديك مهمة فنية. اتبع ذلك ، وتوقف عن إزعاجها ".
"ماذا؟ "هل تريد مني تطبيق الحل حتى دون التحدث إلى مستخدم يعرف كل المتطلبات؟"
نظر براندون إليه. واصل لمشاهدة و ...
بمساعدة لي خلال الأشهر القليلة المقبلة ، أحرز كلايف تقدماً ملحوظاً. لقد تعلم التعامل مع تنسيق التاريخ السخيف (تم حساب التواريخ كعدد الأيام من 3 أبريل 1974 وأيضًا عدد
الأشهر من الاثنين السابق وأيضًا عدد
الأسابيع من الأحد القادم). لقد تعاملوا مع حقيقة أنه لا ينبغي لأحد أن يكون قادرًا على تحديث Firefox إلى إصدارات أعلى من 3 ، وحقيقة أنه كان من المستحيل العمل الإضافي ، لأن جميع الخوادم تم قطع الاتصال في تمام الساعة 6 مساءً. لم تكن كارول على اتصال ، نظرت براندون إليهم ، وعاملهم بقية الموظفين مثل مرضى الجذام.
قبل بضعة أسابيع من إكمال عقدهم لمدة ستة أشهر ، درس كلايف محتويات محرك أقراص الشبكة الخاص بالشركة بحثًا عن جدول بيانات يحتوي على بيانات نموذجية. وجد جدولًا يحمل اسم شركة التوظيف التي استأجرته وأمل أن يكون ذلك مفيدًا. بطريقة ما ، كان عليه.
كان جدول البيانات عبارة عن تقرير يوضح المبلغ الذي تتلقاه شركة التوظيف لـ Clive و Lee. كانت المبالغ مخجلة لدرجة أنها ستجعل حتى أحمر الخدود تاجر سيارات مستعملة. تضمن المستند تتبع التغيير والتحرير التعاوني ، لذلك يمكن لـ Clive قراءة التعليقات التي أدلى بها مستخدمون مختلفون.
من مستوى الإدارة العليا ، تم تلقي التعليقات بروح "بغض النظر عن المبلغ الذي عليك إنفاقه". حذر المحاسبين: "إذا ذهبنا لذلك ، فلن يتبقى لدينا أموال لتغطية أقساط التأمين في نهاية العام!"
ترك براندون ملاحظته الخاصة: "أعمالنا محددة للغاية. لن يتغلبوا. هدر المال.
لا يمكنهم القيام بذلك . "
كل شيء سقط في مكانه. براندون لم يتنبأ بل
وعد . وسيحقق ذلك - خلال الأسابيع القليلة المقبلة ، لن يتمكن كليف ولي من فعل ما وعد به في الأصل.
قريبا تلقى رسالة من المجند له. "لا تزال هذه الشركة بحاجة إلى موظفين إضافيين. هل ترغب في تمديد العقد لمدة ستة أشهر أخرى؟ "
تدرس من قبل براندون ، أجاب كلايف قريبا: "لا"
القصة الثانية. إسقاط كل شيء مستحيل ...
[ الأصل ]إسقاط كل شيء مستحيل ...... وما تبقى هو XML ، مهما كان لا يصدق.وليام هوغارث ، وجهة نظر سخيفةيعاني المطورون من العديد من نقاط الضعف ، وأحدها هو: لا يحبون أن يقولوا إنه لا يمكن القيام بشيء ما. لهذا السبب عندما سأل أحد عملاء شركة
Glenn M ، TelCo ، عما إذا كانت مهمتها ستكون مستحيلة
حقًا ، بدلاً من الاعتذار وتهز رأسه بشكل حاسم ، أجاب: "حسنًا ،
نظريًا ..."
نتيجة لذلك ، كتب Glenn هذا:
<value> <mult> <op> <mult> <op> <add> <op> <div> <op> <bitwise_and> <op> <baseNToInt base="16"> <regex> <op>(?:0x)?([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])</op> <op><getRowOid>.1.3.6.1.4.1.2011.2.217.1.4.1.1.6</getRowOid></op> <op>%4$s%3$s%2$s%1$s</op> </regex> </baseNToInt> </op> <op>8388607</op> </bitwise_and> </op> <op>8388608</op> </div> </op> <op>1</op> </add> </op> <op> <left_shift> <op>1</op> <op> <sub> <op> <bitwise_and> <op> <right_shift> <op> <baseNToInt base="16"> <regex> <op>(?:0x)?([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])</op> <op><getRowOid>.1.3.6.1.4.1.2011.2.217.1.4.1.1.6</getRowOid></op> <op>%4$s%3$s%2$s%1$s</op> </regex> </baseNToInt> </op> <op>23</op> </right_shift> </op> <op>255</op> </bitwise_and> </op> <op>127</op> </sub> </op> </left_shift> </op> </mult> </op> <op> <if> <op> <eq> <op> <bitwise_and> <op> <right_shift> <op> <baseNToInt base="16"> <regex> <op>(?:0x)?([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])\s*([0-9a-fA-F][0-9a-fA-F])</op> <op><getRowOid>.1.3.6.1.4.1.2011.2.217.1.4.1.1.6</getRowOid></op> <op>%4$s%3$s%2$s%1$s</op> </regex> </baseNToInt> </op> <op>31</op> </right_shift> </op> <op>1</op> </bitwise_and> </op> <op>1</op> </eq> </op> <op>-1</op> <op>1</op> </if> </op> </mult> </value>
هذا هو XML DDF ، ملف تعريف البيانات لتطبيق مراقبة النظام الذي دعمه جلين. كما ترى ، يمكن للنظام قراءة البيانات من أي جهاز يدعم بروتوكولات Modbus / TCP أو SNMP إذا كان لديه ملف DDF يحدد نقاط البيانات وكيف يتم عرضها. يحتوي مخطط DDF على العوامل الحسابية والمنطقية والعادية والشرطية الموضحة أعلاه ، اللازمة للنظام لمعرفة كيفية مسح البيانات.
منطق XML؟ نعم ، هذا هو WTF في حد ذاته. لكن WTF
الحقيقي هو ما يفعله الكود أعلاه. راقبت الشركة جهازًا يعرض قيم درجة الحرارة (هذا حل بسيط للغاية) ، لكنه مثلها كسلسلة من ثمانية أحرف تشير إلى القيمة السداسية العشرية لرقم الفاصلة العائمة 32 بت بتنسيق IEEE-754. كانت المهمة التي اضطر غلين إلى إدراكها على الفور مستحيلة تتمثل في تحويل هذه القيمة المجنونة إلى شكل رقمي. في DDF ، على الرغم من قوتها التعبيرية ، لم يكن هناك مشغل نوع cast.
لذلك ، كتب Glenn DDF الموضح أعلاه ، والذي قام بما يلي:
- منذ أن تم عكس ترتيب البايت ، استخدم
<regex>
لإعادتهم إلى الترتيب الذي يمكنك التعامل معه - استخدم
<baseNtoInt>
للتحويل من octetString إلى uint_32 - استخدم
<bitwise_and>
و <right_shift>
لفصل بت الإشارة ، الأس والأساس - تحويل البت الموقعة إلى +/– 1
- نحن
<left_shift>
الإزاحة الأسية ، ثم ننفذ <left_shift>
1 بهذه القيمة - اقسم المانتيسا على 2 23
- اضرب العناصر الثلاثة الأخيرة للحصول على النتيجة النهائية. نظرًا لأن
<mult>
والمشغلين الآخرين يقبلون عاملين فقط ، يجب أن تكون الإجراءات متداخلة
في المرة التالية ، قرر جلين اتباع نفس التكتيك ، لأنه سمع مؤخرًا أن TelCo يعدل الجهاز بحيث يعرض درجة الحرارة في عدد صحيح.
القصة الثالثة. فريق A (nti)
[ الأصل ]في الثمانينيات ، تم تصوير مسلسل تلفزيوني يسمى Team A. كان هناك تسلل داخله ، قادر على خداع أي شخص. للحصول على ما يحتاج إليه ، قدم وعوداً صادقة (مثل التسويق؟). كان هناك رجل رائع في الفريق يمكنه تخويف أي شخص من أجل تحقيق هدفه. كان يعرف كيف يحقق الهدف ، لكن في أعماقه كان رجلاً طيباً. كان لدى الفريق قائد يمكنه دائمًا وضع خطة وإنقاذ الموقف. ثم كان هناك رجل مجنون قليلاً (ولكن بطريقة جيدة) يمكنك الاعتماد عليه دائمًا في المعركة. من وقت لآخر ، ظهر مساعد في الفريق ، شارك في التدخل والذكاء. عملت هذه المجموعة من الرجال مثل معدات مزيت جيدا. لم يتمكنوا من الفشل! كانوا فريق!
لم يكتب فريق "A" مطلقًا وثائق حول منهجية إدارة المشروع. ليس من المستغرب ، أنهم جميعا مجرمون مطلوبون.حصل
أليكس على وظيفة في مشروع جديد ليحل محل نظام قديم وغير مدعوم. بطبيعة الحال ، قيل أن الشركة "تسعى إلى فعل كل شيء بشكل صحيح!" المشروع ممول بالكامل. سيكون لدى الفريق المعدات اللازمة والموظفين اللازمين لإنجاز العمل. هناك دعم كامل لستة مستويات من القيادة بالإضافة إلى جميع المستخدمين. أليكس كان متفائلا.
أول شيء فعلته الشركة هو قضاء عدة أشهر في التنسيق بين جميع مستويات القيادة هذه والمستخدمين النهائيين ودعم الأفراد والمحاربين القدامى الذين دعموا المشروع (حتى يتمكنوا من شرح المشكلات التي جعلت النظام القديم أسوأ) والمهندسين المعماريين الثلاثة للنظام الجديد. تم توثيق الهيكل الجديد على نطاق واسع واعتماده وتوقيعه من قبل كل ما سبق. تم إجراء مراجعة نقدية من قبل وكالة تدقيق تنظيمية مستقلة تابعة لجهة خارجية لضمان ثقة السلطات التنظيمية في اتباع النهج الصحيح.
في وثيقة من ثماني صفحات ، تم وصف التوصيات الخاصة بتطوير الكود بالتفصيل (مثل: خيارات تنسيق الكود ، اصطلاحات التسمية ، اختبارات الوحدة ، تغطية الكود ، والجوانب المماثلة الأخرى المهمة للفريق). تمت مراجعة المستند ويجب أن يتبعه كل شخص يعمل في المشروع.
كانت بداية المشروع جيدة.
كانت المهمة الأولى لتوظيف مطورين للفريق. للقيام بذلك ، كانت الشركة تبحث (بعيدًا جدًا) عن متخصصين في الخارج لإيجاد أرخص المواهب الممكنة. بعد كل شيء ، يمكن تدريب الجميع ، أليس كذلك؟ يمتلك فريق من 11 مطورًا ما مجموعه 13 عامًا من الخبرة ، وتم تعيين عميل متقدم يتمتع بخمس سنوات من الخبرة لإدارتها.
كان القرار المهم التالي هو اختيار قاعدة البيانات للاستخدام. وقد استخدمت الشركة بنشاط ثلاثة. نظرًا لأنه تم تخزين جميع قواعد البيانات على خوادم مركزية ، فقد تم استبعاد واحد منها على الفور: كانت معدات خوادم قواعد البيانات قوية جدًا للتعامل مع الحمل المتوقع خلال فترة زمنية معقولة. من اثنين المتبقية ، واحد من أعضاء الفريق تستخدم بنشاط واحد. كانوا يعرفون بناء الجملة والشذوذ والقيود. تم تعيين الثالث بشكل غير صحيح ، وبالتالي كان له سمعة لكونه غير موثوق بها. ومع ذلك ، كانت أيضا معيار الشركات. على الرغم من اعتراضات الفريق ، تم اختيار الثلث.
قررت إدارة المشروع أنه يمكن تعيين ضمان الجودة في وقت لاحق.
أخيرًا ، لقد حان الوقت لتنفيذ بنية مفصلة. قرر قائد الفريق الخارجي أنه يمكنك توفير الكثير من الوقت إذا قمت بإنشاء التصميم أثناء التنقل ، وفقًا للطلبات. بالطبع ، كان المهندسون المعماريون ضدها ، لكن وافق مدير المشروع.
لقد بدأ المهندسون المعماريون في بناء محرك التحكم والمبادئ الأساسية الأخرى للمشروع. قرر فريق المبتدئين ، الذي كان من المفترض أن ينشئ قائمة انتظار من العديد من الأنظمة البعيدة لإدخال البيانات والجمع والتصفية والمعالجة المسبقة ، أن يفعل ما هو أفضل من ما هو مكتوب في الوثائق المعمارية ، وبدأ في تطوير طريقته الخاصة في أداء العمليات. دون أن يقول هذا إما للمهندسين المعماريين أو الإدارة.
لقد حان الوقت للتحقق من السباق الأول ، وخلال مراجعة الكود تم اكتشاف الكثير من أنواع "الأعلام الحمراء". قال جونيور ليد أن الوثائق المعمارية كانت مجرد توصية تجاهلها لتناسب رغبات المطورين. بطبيعة الحال ، أثار هذا رد فعل مثل "هل أنت حقا هناك ...؟" وحفنة من الرسائل تصل سلسلة القيادة. لكن يبدو أن مدير المشروع والقيادة المذكورة أعلاه غير مهتمين بهذا الأمر: لقد قالوا إن الصغار يجب ألا يفعلوا هذا ، لكنهم وثقوا بهم.
استمر العمل. واصل المهندسون المعماريون الإشارة إلى العيوب وعيوب التنفيذ التي كانت تتعارض مع المتطلبات. تم تجاهل جميع العروض لأن قائد الفريق الخارجي قال: "غوغل تعزز جو الابتكار والإبداع. نحن بحاجة إلى القيام بذلك أيضًا! " تم تذكيره بأن Google هي (في الغالب) "مركز الأبحاث" وأن الرائد يعمل مع مشروع موحد بشكل صارم في صناعة منظمة بشكل صارم. هذه البنية ، التي تمت الموافقة عليها من قبل أكثر من أربعين مديراً ، ليست خيارًا أو توصية ، ولكنها شرط. أن هذه ليست روضة أطفال ، حيث يتم تشجيع الإبداع - تحتاج إلى الالتزام بالخطة المعتمدة! نحن لا نتحدث عن كيفية كتابة إجراء فرعي أو تغليف كائن بشكل صحيح ، ولكن تم استخدام معالجة مؤشر الترابط بشكل غير صحيح وفي الأماكن الخطأ ، ولن يكون الوصول إلى قواعد البيانات واتصالات المعالجة المشتركة قابلاً للتطوير. ما تحتاجه ليس إنشاء عمليات متعددة ، ولكن فقط استخدام مؤشرات الترابط. يجب عدم استخدام الملفات كإشارات لأنهم فعلوا ذلك في المدرسة. وستظل القائمة طويلة.
ولكن لم يلاحظ أي شيء من هذا. اشتكى مطورو يونيو من أنه عند إنشاء البنية لم يأخذوا آرائهم في الاعتبار ، لذلك سيستمرون في تجاهلها (بمباركة من يؤدي بهم). واصل مدير المشروع القول إنه كان على دراية بالمشكلات ، لكنه لم يفعل شيئًا معها. تم الإبلاغ عن وجود مشاكل في السلسلة ، لكن لم يفعل أحد أي شيء. بعد كل شيء ، كل شخص في الفريق لديه الحق المتساوي في التصويت.
في العالم الواقعي ، إذا كان الطالب يعتقد أن المعلم مخطئ ، فإنهم لا يغيرون درجته. المتدرب يقطع الجراح حيث يظهر له ، وليس العكس. العام لا يناقش الإستراتيجية مع الرتبة والملف. إذا انضممت إلى نقابة ، وكمبتدئ ، فإنك تطالب بنفس الصلاحيات التي يتمتع بها قادة النقابات ، فأنت ستستريح بجوار جيمي هوف
[زعيم نقابي أمريكي اختفى فجأة في ظروف غامضة] . تتحدث التجربة مع علامات التعجب. قلة الخبرة تتحدث إلى المحققين.
ولكن ليس في هذا "الفريق".
واصل جونيورز القيام بما اعتقدوا أنه الأفضل ، متجاهلين جميع طلبات المهندسين المعماريين. تمت كتابة معظم التعليمات البرمجية الخاصة بهم ونسخها عدة مرات ، نظرًا لأن jones لم تتمكن من مراعاة كل شيء في المرة الأولى. أن المطورين ذوي الخبرة أكثر معرفة ما يمكن الاعتماد عليه. بعد 8 أشهر ، عانى المشروع من ضرر لدرجة أنه كان من المستحيل تحقيق أكثر المتطلبات تعقيدًا ، وفي مشروع تطوير بدأ من الصفر ، كان من الضروري التراجع قبل شهر.
في هذا الوقت تقريبًا ، استسلمت الإدارة للطلبات وطلبت من العديد من المستخدمين التجاريين كتابة اختبارات على المستوى التجاري (على سبيل المثال ، جدول بيانات يمكن إرساله إلى JBehave لاختبار JUnit). قدم المطورون رمزًا وبعض الأمثلة البسيطة في جداول البيانات. قال المهندسون المعماريون إنهم يحتاجون إلى تعيين موظفي ضمان الجودة لأن المستخدمين نادراً ما يعرفون كيفية التعامل مع حالات الحدود ، ومشكلات الدقة ، إلخ. لكن المال لا يمكن إنفاقه. بعد ستة أشهر من التشغيل ، قال المستخدمون التجاريون إن جميع اختبارات التطبيق بالكامل (أي المهمة الفنية بأكملها) جاهزة. بمجرد النظر إلى الأمر ، كان من الممكن أن نفهم أنهم لم يأخذوا في الاعتبار حالات الحدود ، والأمثلة الفارغة ، ومشاكل الدقة ومعظم الجوانب الأخرى التي تتطلب الاختبار عادةً. في الواقع ، وضعوا جميع السجلات التي يمكن أن توجد من الناحية النظرية (من وجهة نظرهم) في اختبار واحد ناجح. بالطبع ، عندما يتغير شيء ما ويحدث الفشل حتماً ، لا توجد طريقة لمعرفة مكان حدوثه.
أخيرًا ، ذهبت الأمور إلى حد بعيد حيث بنى المهندسون المعماريون جدارًا فعليًا بين أجزاء التطبيق برمز الإعداد (مكتوب من قبل فريق خارجي) والمحرك الرئيسي (تم إنشاؤه بواسطة المهندسين المعماريين). مباشرة بعد أن بدأ المحرك الرئيسي في طحن البيانات ، تمت إعادة تعيين كل متغير في النظام إلى جدول حالة في قاعدة البيانات ، بحيث في حالة حدوث مشاكل لا مفر منها ، يتم عرض بيانات الإدخال ويمكن إرسال المطورين الخارجيين طلب تصحيح. على الأقل بهذه الطريقة يمكنهم عزل المحرك الرئيسي عن القمامة.
وفرت الوزارة الكثير من المال من خلال استخدام اليد العاملة الرخيصة ، والافتقار إلى إدارة ضمان الجودة واستخدام قاعدة بيانات "سليمة سياسيا". بالطبع ، كل رمز التهيئة الذي كتبه الفريق الخارجي كان فظيعًا. كان معظمها من الصعب تعلمها وصيانتها وتصحيحها وتحسينها.
لم يتم إطلاق المنتج بعد ، ويشكو المستخدمون بالفعل من تشخيص المشكلات وحلها لفترة طويلة جدًا (كان هذا أحد الأسباب الرئيسية لإعادة كتابة مشروع قديم). وإذا لم تحل إعادة كتابة المهمة الرئيسية لإعادة الكتابة ، فربما حدث خطأ ما ...
القصة الرابعة. تمر عبر مؤشر فارغة
[
الأصل ]
كان Maxine يواجه مشكلة في عرض موقع الويب في مستعرض مع وظيفة NoScript الإضافية. هذا ليس مفاجئًا - قد لا تعمل بعض المتصفحات بشكل صحيح مع NoScript ، لكن كان من المفاجئ أن يكون المتصفح قد ألقى استثناءات Java. عند تمكين JavaScript ، تختفي صفحة الخطأ ، ولكن كيف يتم ذلك؟ عدم وجود جافا سكريبت يؤدي إلى استثناءات جافا!
فتحت رمز الصفحة ووجدت أن الخادم كان يتوقع معلمة "innerCHK" ؛ ربما نوع من جلسة العمل أو رمز الأمان الذي يجب تمريره في سلسلة استعلام URL. إذا لم يكن كذلك ، يعرض الخادم صفحة خطأ تعرض java.lang.NullPointerException. لحسن الحظ ، توصل مطورو الواجهة الأمامية إلى الجزء
الكبير التالي من JavaScript لحل المشكلة:
// خطأ في التحقق
if (document.body.innerHTML.indexOf ('java.lang' + '. NullPointerException')! = -1) {
if (document.location.href.indexOf ('innerCHK =') == -1) {
document.location.href = document.location.href + "& innerCHK =" + Math.random () * 10000؛
}
}
// نهاية الاختيار
لكن هذه ليست سوى قمة جبل الجليد. كانت الصفحة محملة بمضادات التآكل والعجلات التي تم اختراعها والعجلات الاحتياطية والإطارات المسطحة. كل هذا عقد على
الشريط . للتعرف على نمط بعض تحويلات السلسلة الغريبة ومضاد الألوان المفضل للمطورين - إغلاق البرامج النصية فقط لفتح واحدة جديدة على السطر التالي ، دعنا نلقي نظرة على كيفية استيراد Dojo. يرجى ملاحظة أنه يتم استيراد ملف تعريف الارتباط Dojo.
<script type = "text / javascript">
if (typeof dojo == "undefined") {
document.writeln ('<scr' + 'ipt src = "' + '/wps/themes/./dojo/portal_dojo/dojo/dojo.js' + '"> </ scr' + 'ipt>')؛
}
if (typeof dijit == "undefined") {
document.writeln ('<scr' + 'ipt src = "' + '/wps/themes/./dojo/portal_dojo/dijit/dijit.js' + '"> </ scr' + 'ipt>')؛
}
</script>
<script type = "text / javascript">
dojo.require ("dijit.form.Button")؛
dojo.require ("dojo.cookie") ؛
//dojo.require("dijit.form.DropDownButton ")؛
dojo.require ("dijit.Dialog") ؛
dojo.require ("dijit.form.TextBox") ؛
dojo.require ("dijit.form.CheckBox") ؛
dojo.require ("dijit.form.ComboBox")؛
</script>
يتم التعامل مع بعض ، إن لم يكن كل روابط CSS بهذه الطريقة. لقد وجدت في شفرة المصدر ما لا يقل عن ثلاثة حوادث (متطابقة). كرر Dojo.cookie يتم استيرادها.
<script name = "DojoEnable_script" language = "JavaScript"> if (typeof dojo == "undefined") {
dojo.require ("dojo.cookie") ؛
dojo.require ("dojo.parser")؛
djConfig = {parseOnLoad: false، isDebug: false}؛
document.write ("<script src = 'http: //www.****************.com: 80 / ps / PA_WPF / factory / dojo / dojo / dojo.js '> </ "+" script> ") ؛
document.write ("<link rel = 'stylesheet' type = 'text / css' href = 'http: //www.****************.com: 80 / ps /PA_WPF/factory/dojo/dojo/resources/dojo.css '/> ")؛
document.write ('<link rel = "stylesheet" type = "text / css" href = "http: //www.****************.com: 80 / ps /PA_WPF/factory/dojo/dijit/themes/tundra/tundra.css "/> ')؛
document.write ('<link rel = "stylesheet" type = "text / css" href = "http: //www.****************.com: 80 / ps /PA_WPF/factory/dojo/dijit/themes/tundra/tundra_rtl.css "/> ')؛
dojo.addOnLoad (function () {if (! document.body.className) document.body.className = 'tundra'})؛
}
قال أحدهم ذات مرة إنه إذا كنت ترغب في حل مشكلة باستخدام التعبيرات المعتادة ، فأنت تواجه مشكلتين. أعتقد أنه قال "اثنين" ، قلل من أهمية الموقف.
var locale = 'en'.replace (/ _ /،' - '). استبدال (/ iw /،' he '). toLowerCase ()؛
تذكر أن الأطفال يستخدمون دائمًا أسماء مدروسة للثوابت! الأرقام السحرية سيئة. باستثناء عام 2008 ، كل شيء على ما يرام معه.
if (typeof (MONTHS_IN_YEAR) == 'undefined')
{
MONTHS_IN_YEAR = 12 ؛
}
if (typeof (isDisableDate) == 'undefined') {
var isDisableDate = function (التاريخ ، السنة ، الشهر ، الهوية)
{
إذا (date.getFullYear () == 2008)
{
العودة الحقيقية ؛
}
عودة كاذبة ؛
}
} ؛
لن يكتمل أي تطبيق تم تنفيذه بشكل سيء بدون مكتبة DateTime التي تم تنفيذها بشكل سيء. يجب أن يكون هناك نوع من القانون العلمي حول هذا الموضوع.
var month = new Array (12)؛
الشهر [0] = "1" ؛
الشهر [1] = "2" ؛
الشهر [2] = "3" ؛
الشهر [3] = "4" ؛
الشهر [4] = "5" ؛
الشهر [5] = "6" ؛
الشهر [6] = "7" ؛
الشهر [7] = "8" ؛
الشهر [8] = "9" ؛
الشهر [9] = "10" ؛
الشهر [10] = "11" ؛
الشهر [11] = "12" ؛
if (typeof (MONVALUE) == 'undefined')
{
MONVALUE = صفيف جديد
("يناير" ،
"فبراير" ،
"مار" ،
"أبريل" ،
"مايو" ،
"يونيو" ،
"يوليو" ،
"أغسطس" ،
"سبتمبر" ،
"أكتوبر" ،
"نوفمبر" ،
"ديسمبر") ؛
}
// دالة تحول التاريخ من str إلى Num
وظيفة شهر 2 عدد (شهر)
{
إذا كان (month == "JAN") يُرجع "01" ، وإذا كان (month == "FEB") بإرجاع "02" ، وإذا كان (month == "MAR") بإرجاع "03" ؛ إذا كان (month == "APR" ) إرجاع "04" ؛ إذا كان (الشهر == "MAY") بإرجاع "05" ؛
إذا كان (month == "JUN") يُرجع "06" ، وإذا كان (month == "JUL") يُرجع "07" ، وإذا كان (month == "AUG") فيُرجع "08" ؛ إذا كان (month == "SEP" ) إرجاع "09" ؛ إذا كان (الشهر == "OCT") بإرجاع "10" ؛
إذا كان (month == "NOV") بإرجاع "11" ، وإذا كان (month == "DEC") بإرجاع "12" ؛
}
يحتوي الرمز على العديد من أنماط CSS (غالبًا ما تكون مكررة) ، على سبيل المثال ، هذا ليس نمطًا أزرق جدًا.
div.wpfThemeBlueBackgroundPanelTable
{
الخلفية: # F6F9FC ؛
الحشو: 10px.
}
/ * ---- Blue panel ---- * /
table.wpfThemeBlueBackgroundPanelTable
{
الخلفية: # F6F9FC ؛
الحشو: 10px.
}
فيما يلي صفيفان متطابقان ، يتم استخدام واحدة منها فقط.
var arr_location_001 = new Array () ؛
var arr_location_002 = new Array () ؛
arr_location_001 ['AU'] = {value: 'AU' ، title: 'australia' ، text: 'Australia'}؛
arr_location_002 ['0'] = {value: 'AU' ، title: 'australia' ، text: 'Australia'}؛
arr_location_001 ['CA'] = {value: 'CA' ، title: 'canada' ، text: 'Canada'}؛
arr_location_002 ['1'] = {value: 'CA' ، title: 'canada' ، text: 'Canada'}؛
arr_location_001 ['CN'] = {value: 'CN' ، title: 'china' ، text: 'China'}؛
arr_location_002 ['2'] = {value: 'CN' ، title: 'china' ، text: 'China'}؛
arr_location_001 ['FR'] = {value: 'FR' ، title: 'france' ، text: 'France'}؛
arr_location_002 ['3'] = {value: 'FR' ، title: 'france' ، text: 'France'}؛
arr_location_001 ['HK'] = {value: 'HK' ، title: 'hong_kong' ، text: 'Hong Kong'}؛
arr_location_002 ['4'] = {value: 'HK'، title: 'hong_kong'، text: 'Hong Kong'}؛
/ * جزء من العديد من أسطر الكود المشابه * /
إليك نصًا صغيرًا جميلًا آخر نجح في تجنب الكثير بما في ذلك علامات البرامج النصية الخاصة به! يحصل المطور على نقاط إضافية إذا كتبه في سترة واقية ، صعد في تابوت مليء بالعقارب ، معلقة من طائرة هليكوبتر فوق هدسون. (في الواقع ، قد يكون هذا هو التفسير الأكثر منطقية لمعظم الشفرة.)
<SPAN name = "onloadScript"> <input type = "hidden"> وظيفة onSelectInfo (التقويم ، التاريخ ، elem_date) {
elem_date = document.getElementById (& quot؛ Day_NArr & quot؛)؛
elem_mon_year = document.getElementById (& quot؛ Month_NArr & quot؛)؛
hidden_elem = document.getElementById (& quot؛ temp_date_NArr & quot؛)؛
doOnSelect (التقويم ، التاريخ ، elem_date ، elem_mon_year ، hidden_elem) ؛
}
مجموعة التقويم (
{
inputField: & quot؛ temp_date_NArr & quot ؛، // معرف حقل الإدخال
ifFormat: & quot؛٪ b،٪ e،٪ Y & quot؛،
onSelect: onSelectInfo ،
النطاق: [الحاليالعام ، التاليالعام] ،
dateStatusFunc: dateStatusHandler،
الزر: & quot؛ cal_dep & quot؛ // معرف الزر
}
) ؛
var _InfoVerAccurateFunc = استنساخ (دقيقة) ؛
initializeDate (صفيف جديد ('Month_NArr' ، 'Day_NArr') ، _InfoVerAccurateFunc) ؛ ">
<script type = "text / javascript">
تذكر كل dojo.cookie المستوردة أعلاه؟ أضاف شخص ما وظيفة مكتبة لقراءة ملفات تعريف الارتباط.
ومع ذلك ، اعتبر شخص آخر أنه من الضروري كتابة وظيفة نسخ ولصق Get_Cookie من الإنترنت ، ولكن ليس مرة واحدة ، ولكن أربع مرات! وظيفة Get_Cookie (check_name) {
/ / أولاً سنقوم بتقسيم ملف تعريف الارتباط هذا إلى أزواج اسم / قيمة
// note: document.cookie تقوم فقط بإرجاع الاسم = القيمة ، وليس المكونات الأخرى
var a_all_cookies = document.cookie.split ('؛')؛
var a_temp_cookie = ''؛
var cookie_name = ''؛
var cookie_value = ''؛
var b_cookie_found = false ؛
لـ (i = 0 ؛ أنا <a_all_cookies.length ؛ i ++) {
/ / الآن سنقوم بتقسيم كل اسم = زوج القيمة
a_temp_cookie = a_all_cookies [i] .split ('=')؛
/ / وقم بقطع مسافة بيضاء / يسرى بينما نحن في ذلك
cookie_name = a_temp_cookie [0] .replace (/ ^ \ s + | \ s + $ / g، '')؛
// if the extracted name matches passed check_name
if (cookie_name == check_name) {
b_cookie_found = true;
// we need to handle case where cookie has no value but exists (no = sign, that is):
if ( a_temp_cookie.length > 1 ) {
cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, ''));
}
// note that in cases where cookie is initialized but no value, null is returned
return cookie_value;
break;
}
a_temp_cookie = null;
cookie_name = '';
}
if (!b_cookie_found) {
return null;
}
}
أعتقد أن طريقة تطوير البرنامج المستخدمة من قبل هذا الفريق هي نظام تم إنشاؤه حديثًا باسم "Dolby على مفاتيح CTRL-C و CTRL-V !!!!!! 11 !!!! 11! 11". أنا متأكد من أنه في المستقبل القريب سيحل محل Agile.القصة الخامسة. الروبوتات البشرية
[ الأصل ]خلال تشكيل SuperbServices ، وشركة ، ازدهرت أعمالها. كانت نعمة ونقمة. كما هو الحال في أي بدء التشغيل ، كان هناك عمل أكثر من الأيدي. لم يستطع قسم المبيعات التخلي عن نجاحهم ، لذلك كان على التقنيين التكيف.الرئيس التنفيذي لشركة SuperbServices، Inc أعطى Roland مهمة جدية يمكن أن تنقذ الشركة ، أو على الأقل الصحة العقلية للموظفين. قال الرئيس التنفيذي: "نحتاج إلى أتمتة جميع العمليات حتى نتمكن من التركيز على توفير الخدمات". "الشيء الأكثر قيمة معنا هو خدماتنا ، وكل شيء آخر هو ضجة لا لزوم لها. تحتاج إلى تشغيله تلقائيًا ، وهذا ما ستفعله. ستتعاون مع الروبوتات البشرية لأتمتة كل شيء: تأكيد العمليات والمشتريات ومعاملات الأموال والبريد الإلكتروني للعميل - هذا كل شيء! ""مع ... الإنسان الآلي؟"رولاند لديه رهاب جديد. كان قسم خادم الشركة غريب الأطوار بشكل غير عادي ، حتى بمعايير الصناعة. لم ير سوى عدد قليل من موظفيه ، وجاءت فقط شائعات غريبة إلى رولاند.عندما طرق رولاند باب غرفة الخادم ، ظهرت كاميرا المراقبة فوق رأسه وسأله صوت الروبوت الهش: "ما الذي تبحث عنه؟""أه ، مرحبا ... أنا رولاند ، مدير المشروع. يبدو أننا نحن الرجال ، أو من أنت هناك ، يجب علينا أتمتة المهام؟ ""ماذا تقدم لنا؟" أجاب صوت المعدن المشؤومة."حسنًا ، أه ... الروبوتات تحب الكعك؟" لدي معي. هذا كل ما في الأمر "."تمرير". فتح القفل الإلكتروني على الباب بنقرة واحدة. سحب رولاند الباب نحو نفسه ، وانفجر الهواء الجليدي من الخلف. آلاف الأنوار والرفوف مومضة بالداخل ، في مكان قريب كانت هناك طاولة صغيرة. وميض ضوء فوق الطاولة. قال المدفع الرشاش من الظلال: "ضع هنا".وضع رولاند صندوق الكعك على الطاولة ومشى ببطء. صرخة "شكرا!" جاء من خلفه. قفز رولاند. الرجل الضيق مع المغير صوت ضحك وأمسك دونات."مرحبا رولاند ، أنا روي" ، وقال جانبا المغير. "ليس لدينا الكثير من الزوار ، لذلك نود الاستهزاء بهم. حسنًا ، هل تحتاج إلى أتمتة شيء ما؟ "فوجئ رولاند بكيفية روى روي العادي ، وليس أنه إنسان حقًا. "آه ، نعم ، قال الرئيس التنفيذي أنك تعمل كثيرًا مع الروبوتات ، وأنه يمكننا استخدامها لأتمتة كل ما نستطيع" ، أوضح رولاند المتطلبات والمواصفات.تنهد روي. "من المؤسف أن نخيب ظنك ، لكننا في الواقع لا علاقة لنا بالروبوتات ، بصرف النظر عما يفكر فيه الجنس. يصر على أن روبي هو اسم الروبوت ، على الرغم من أنها مجرد لغة برمجة. ولكن معظم هذه العمليات يمكننا أتمتة. امنحنا أسبوعين ، بأكبر عدد ممكن من الكعك ومشروبات الطاقة التي يمكننا استهلاكها ، ويمكننا تناولها ".خلال الأسبوعين القادمين ، أحضر رولان العروض المطلوبة وتلقى في تبادل المعلومات حول التقدم والعروض التوضيحية للوظائف. كتب روي وغيره من الروبوتات البشرية الرمز ، وسرعان ما انتقل جبل الورق الذي كان يقوم به الجميع في القمة إلى الخوادم الموجودة في الطابق السفلي. أوضح رولاند أن معظم العمل تم بواسطة "روبوتات بشرية" ، لكن الرئيس التنفيذي أشاد بجهوده."إن رولاند ، تم إنجاز الأعمال الفنية ، والآن هذه الآلات تسحب الرافعات التي تضع أعمالنا في الحركة ،" وضعه المدير العام على ظهره. "ستكون مكافأتك مشروعًا جديدًا - مشروعًا آخر ذا أولوية قصوى. لا يتعامل قسمنا المالي مع حجم المعاملات. لقد تحدثت مع المدير المالي وتريد منك أنت والناس الآليين أتمتة المنتج الجديد الذي اشتريناه - MoneyWorx. لا تخذلني! "عاد رولاند إلى غرفة الخادم. إذا كان مشروع الأتمتة السابق في غاية البساطة ، فكل شيء سيكون هو نفسه ، أليس كذلك؟ وأظهر روي المطالب.أصبح جلد روي المدبوغ في ضوء الشاشات أكثر شحوبًا. "هذا سيء ، سيء للغاية! خطر! "بكى روي. ولوح يديه في رعب. هذا ليس MoneyWorx ، ولكن MoneyDoesntWorx. حتى عند تشغيل الخدمات ، فإنها تتطلب الرموز المميزة RSA-SecurID. يجب على شخص ما إدخال الرمز يدويًا. ""يدويا؟" أي لكي يعمل النظام ، يجب أن يكون شخص ما على الخط؟ "نعم نستخدم ثلاثة رموز SecurID ، لذلك عادة عندما يطلب MoneyWorx رمزًا جديدًا ، يجب أن يكون هناك ثلاثة أشخاص على الخط. ""لذلك لن ينجح. إذا كان على الأشخاص إجراء مكالمات ليلية ، فسيكون المدير التنفيذي غاضبًا. وقد وقع بالفعل اتفاقية - يجب علينا التأكد من أن النظام يعمل دون الاتصال بالناس. "افتتح روي رجل الطاقة وارتجف. "أعطني عطلة نهاية الأسبوع ، سأفكر في ذلك. وسأحتاج إلى المزيد من هذا ، "هز الجرة. "وهذا واحد" ، وأشار إلى مربع من الكعك.ظهر رولاند في نهاية الأسبوع وألقى عروضه. قبلهم روي ، لكن لم يقل شيئًا. الروبوتات البشرية كانت مشغولة جدًا بالدردشة. عندما وصل الاثنين ، عاد رولاند مع الكعك والمشروبات الطاقة الجديدة. "يوريكا!" صرخ روي عندما دخل رولاند. "دعني أريك تحفة بلدي!"كانت "التحفة" عبارة عن صندوق دونات فارغ تم ضبطه على جانب واحد. تم لصق الرموز المميزة RSA-SecurID على الصندوق. تم تثبيت النظام بأكمله أمام كاميرا ويب رخيصة. "عندما يتطلب MoneyJerks رمزًا جديدًا يتكون من عاملين ، يمكن لأي شخص الوصول إلى هذا الجهاز عن بُعد والتحقق من الرموز وإدخال الرمز الصحيح.""ألا تعتقد أن هذا المربع يحتاج إلى حماية بكلمة مرور؟" اقترح رولاند."هل تعتقد أن المستخدمين سيتذكرون كيفية تسجيل الدخول؟" اعترض روي.ربما كانت أغبى فكرة سمعها رولاند ، لكنه أبلغ عنها بالطابق العلوي وأظهر عرضًا تجريبيًا للحل في مكتب الرئيس التنفيذي. بعد أن انفصل عن السيارة بكاميرا ويب ، تعثر وهو ينتظر نوبة غضب."هذا رائع! لقد حولوا أعينهم الآلية إلى هذه الخراء ، والآن لا يحتاج أي شخص في الشركة إلى إخبار MoneyWorx بما يجب فعله! عمل عظيم ، رولاند. تهنئني من الشعب الآلي. روبوتهم هو مجرد معجزة ".كان رولاند سعيدًا بإنجاز العمل ، لكنه لم يستطع التخلص من الشعور بأنه ارتكب خطأً فادحًا. كان الأمن المالي للشركة في أيدي كاميرا ويب رخيصة دون أي حماية ، باستثناء عدم وجود عنوان IP عام.عندما اندلعت الكارثة أخيرًا ، لم تأخذ شكل معاملة احتيالية. سقط صندوق الدونات مساء الأربعاء. كان على رولاند الاتصال بروي ، الذي قاد إلى المكتب ووضع الصندوق في مكانه. بعد تحليل أسباب الفشل ، علق روي الصندوق على حامل الخادم بشريط كهربائي ، وبالتالي ضمان وقت تشغيل ثابت.