اذهب إلى المحتوى

شرف الدين حفني

الأعضاء
  • المساهمات

    1690
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    2

إجابات الأسئلة

  1. إجابة شرف الدين حفني سؤال في كيفية استخدام دالة getline في لغة ++C كانت الإجابة المقبولة   
    المشكلة أنك لم تحدد للدالة getline المصدر الذي ستتلقى منه البيانات
    حيث أن تلك الدالة ليست مصممة فقط لقراءة البيانات من شاشة الإدخال القياسية (standard input) بل أنها تستقبل المدخلات من أي مصدر تحدده مثلاً من ملف نصي
    لجعل الشفرة البرمجية خاصتك تعمل يجب إعطاء مصدر البيانات كparameter للدالة
    string s; std::getline(cin,s);  
  2. إجابة شرف الدين حفني سؤال في كيفية تشغيل redux devtools في next js كانت الإجابة المقبولة   
    سبب هذا الخطأ هو أن مجموعة أدوات تطوير ريدكس(redux dev-tools) تعمل على المتصفح بينما الnext js تعمل على الخادم مما يسبب مشاكل, فعندما نقوم بإستخدام React. js كنا نقوم بكتابة شفرة برمجية كتلك 
    const store = createStore(reducer , window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) ولكن عند كتابة تلك الشفرة في Next.js سيتسبب ذلك بمشكلة لأن كما أخبرتك أن الnext js تعمل على الخادم أولاً حتى تحقق ال static-site-generating أو ال server-side rendering و الكائن window هو أحد الكائنات الخاصة بالمتصفح وبما أن الشفرة البرمجية تعمل عند الخادم أولاً فبالتالي لن يمكنها الوصول إلى الكائنات الخاصة بالمتصفح.
    الحل: أن نقوم بالتأكد أولاً من كون الشفرة البرمجية يتم تنفيذها على المتصفح وليس على الخادم حتى ﻻ تتسبب بأخطاء, ويمكننا التحقق من ذلك عن طريق التحقق من توفر الكائن window , ويمكن كتابة الشفرة البرمجية على النحو التالي:
    const enhancer = (typeof window !== 'undefined' && window.devToolsExtension) ? window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() : f => f const store = createStore(reducer ,enhancer); هكذا نقوم بالتأكد أولاً أن الشفرة البرمجية تعمل بالمتصفح وأن مجموعة الأدوات تعمل بنجاح
  3. إجابة شرف الدين حفني سؤال في هل يمكن تمرير البيانات بالمرجعية في الجافاسكريبت (passing by reference) كانت الإجابة المقبولة   
    ليس تماماً , فإن الجافاسكريبت على عكس اللغات التي تعمل في المستوي المنخفض (low level languages)  التي مكنك بإستخدامها إختيار ماإن كنت تريد إرسال البيانات بالمرجعية أم بالقيمة, فإن الأمر في الجافا سكريبت مختلف قليلاً, حيث يتم تلقائياً إرسال البيانات البدائية (primitive data types) بالقيمة , وأما الكائنات فيتم إرسال نسخة من المرجعية(copy of reference).
     حيث ﻻ يمكنك تغيير الكائن الذي يتم تمريره إلى الدالة ولكن يمكنك تغيير قيمته, لنأخذ مثالاً لتوضيح الأمر:
    function test(obj){ obj={}; } هذا السطر لن يؤثر على الكائن obj خارج الدالة حيث أنك تحاول تغيير مرجعية الكائن نفسه والذي هو غير مقبول في الجافا سكريبت
    function test(obj){ obj.a="hello khaled"; } بينما هذا السطر سيقوم بتغيير قيمة الخاصية a لدي الكائن obj حيث أنك تحاول فقط تغيير خواص الكائن والذي يُعد مقبولاً في الجافاسكريبت
    فلو قمنا بكتابة شفرة برمجية لتجربة الدوال بالأعلى سنجد قيمة الطباعة كما في الشكل بالأدنى
    function test(obj){ obj={}; } let a={ name:"sharaf" } test(a) console.log(a)/////////سنﻻحظ أن قيمة الكائن لن تتغير على الإطﻻق //////////////////////////////////// function test(obj){ obj.a="test" } let a={ name:"sharaf } test(a) console.log(a)///////////سنﻻحظ هنا تغيير في قيم الكائن  
  4. إجابة شرف الدين حفني سؤال في كيفية إيجاد إول خانة من رقم في لغة java كانت الإجابة المقبولة   
    لإيجاد أول خانة في الرقم نحتاج إلى القيام بالخطوات التالية
    أولاً العثور على عدد الخانات وذلك يمكن فعله عن طريق إيجاد لوغاريتم الرقم للأساس 10 من المعادلة السابقة سنحصل على عدد الخانات -1 الأن نقوم برفع العشرة لأس الناتج الذي عثرنا عليه فمثلاً  العدد 989 عدد خاناته 3 , المعادلة السابقة ناتجها 2 , نقوم إذا برفع 10 للأس 2 والذي يعطينا 100 نقوم بقسمة العدد على ناتج رفع العشرة للأس, أي نقوم بقسمة ال989 في مثالنا على 100 ونقم بتقريب الناتج , سنعثر على أول خانة في الرقم ويمكن تمثيل ذلك برمجياً عن طريق الشفرة التالية بلغة الجافا
    int number = scan.nextInt(); int firstDigit; int totalDigits = (int) Math.log10(number); firstDigit = (int) (number/ (int) Math.pow(10,totalDigits));  
  5. إجابة شرف الدين حفني سؤال في خطأ عند استخدام getStaticPaths في nextjs كانت الإجابة المقبولة   
    الخطأ في أنك تقوم بإرجاع ناتج الدالة بشكل خاطئ حيث تقوم بإرجاعه على هذ الشكل
    [ [ { params: {} }, { params: {} } ], [ { params: {} } ] ] بينما الصحيح أن تقوم بإرجاعه على هذا النحو
    [ { params: {} }, { params: {} }, { params: {} } ] مما يعني أن بدلاً من كتابة
    return { paths: [ blogPosts, authorPaths, ], fallback: false, } } قم بكتابة
    return { paths: [ params:{ blogPosts, authorPaths } ], fallback: false, } }  
  6. إجابة شرف الدين حفني سؤال في ﻻ أستطيع تثبيت react-facebook-login كانت الإجابة المقبولة   
    من بعد إصدار React 17 أصبحت الdependencies التي ﻻ تقوم بعمل import ل React 17 تقوم بعمل خطأ عند التثبيت , لحل تلك المشكلة يرجى تثبيتها عن طريق الأمر التالي
    npm install react-facebook-login --legacy-peer-deps هذا الأمر سيجعل الnpm يتغاضي عن تثبيت الإعتماديات الخاصة ب react-facebook-login
  7. إجابة شرف الدين حفني سؤال في كتابة معادلة رياضية بلغة ++C كانت الإجابة المقبولة   
    يمكنك إنشاء متغير لكل عنصر في المعادلة , وحساب الأُسُس عن طريق الدالة pow المستدعاة من المكتبةcmath 
    ويمكن التعبير عن ماسبق عن طريق الشفرة البرمجية التالية
    #include <iostream> #include <cmath> using namespace std; int findValueOfZ(int x, int y, int n, int m){ return pow(x,2)+pow(y,3)*n*m //Z=x2+y3nm } int main(){ int x, y, n, m; cin>>x>>y>>n>>m cout<<findValueOfZ(x,y,n,m); }  
  8. إجابة شرف الدين حفني سؤال في كيفية دمج قيم عددية مع سلسلة نصية في لغة برمجة ++C كانت الإجابة المقبولة   
    سبب الخطأ أن الدالة abs تقوم بأخذ قيمة عددية وترجع القيمة المطلقة لها, والتي بدورها أيضا قيمة عددية كما أن المتغير في المصفوفة arr[3] يُعد أيضاً قيمة عددية, وال" " عبارة عن سلسلة نصية, ﻻ يمكنك جمع سلسلة نصية وقيمة عددية في الوقت ذاته, الحل أن تقوم بتحويل القيم العددية إلى سلسلة نصية عن طريق الدالة to_string كما عملت في عﻻمة الجمع رقم إثنين فتصبح الشفرة البرمجية خاصتك على الصيغة التالية
    string findTrees(int arr[],int n){ string position; int a; if(arr[0]==arr[2]){ a=abs(arr[3]-arr[1]); position=to_string(abs(arr[0]-a))+" " +to_string(arr[1])+' '+to_string(abs(arr[0]-a))+' '+ to_string(arr[3]); }  
  9. إجابة شرف الدين حفني سؤال في ما الفرق بين مفهوم الbuffer pools وال cache كانت الإجابة المقبولة   
    ال cacheاو ال (query cache) في قواعد البيانات تعبر عن تخزين النتائج للجملة الإستعﻻمية الواحدة(query) ,فمثلاً لو قمنا بتنفيذ تلك الإستعﻻمة
    select * from users where rating between(10,100) سيتم تخزين الناتج في الcache وهو مكان في الذاكرة يكون الوصول إليه أسهل من الوصول إلى القرص الصلب, أو يكون مكان بين المعالج وبين الذاكرة, فعند تنفيذ نفس الإستعﻻمة في المرة القادمة يتم تنفيذها في وقت أقل حيث لا يحتاج نظام قواعد البيانات إلى البحث عبر جميع الجداول , فقد تم تخزين الناتج بالفعل ولكن إن قمنا بتنفيذ إستعﻻمة أخرى حتى وإن كانت تحتاج بعضاً من البيانات التي حصلنا عليها من الإستعﻻمة السابقة , فسيقوم نظام قواعد البيانات بتنفيذ الإستعﻻمة بدلاً من جلب البيانات المشتركة من الcache
    بينما ال buffer pools ﻻ يعتمد على إستعﻻمة معينة, ففي قواعد البيانات عندما تبحث عن بيانات معينة يتم التساؤل أولاً إن كانت تلك البيانات موجودة في الbuffer pools (والذي هو بالمناسبة جزءاً في الذاكرة يتم تخصيصه من أجل قواعد البيانات) , لو كانت الإجابة بنعم يتم جلبها إلى المستخدم, لو كانت الإجابة ب"لا" يتم نقلها من القرص الصلب إلى الbuffer pool ومن ثم جلبها للمستخدم, في المرة القادمة إن قمنا بتنفيذ إستعﻻمة مختلفة ولكن تحتاج إلى نفس البيانات ﻻ نحتاج إلى الذهاب إلى القرص الصلب, حيث يتم جلب البيانات بشكل تلقائي من الbuffer pool ,وذلك يُعد أسرع وأفضل للأداء, ومن المُستحسن أن يكون حجم الbuffer pool مناسب للبيانات, ولكن قاعدة الإبهام أن يكون مساحته بمقدار 80% من الذاكرة, إن أصبح مساحة الbuffer poolأقل من المطلوب سيؤدي ذلك إلى مشاكل في الأداء بسبب كثرة عمليات الswapping المُكلفة للموارد والمؤثرة على الأداء بشكلٍ ملحوظ
  10. إجابة شرف الدين حفني سؤال في تغيير قيمة الswap في نظام التشغيل أوبنتو كانت الإجابة المقبولة   
    يجب عليك أولاً أ تتأكد من أنك فعﻻً تحتاج أن تغير من قيمة الswap , ويمكنك التحقق من ذلك الأمر عن طريق الشفرة الأتية
    cat /proc/sys/vm/swappiness عند كتابة هذا الأمر في الterminal ستخرج لك قيمة الswap والتي تتراوح من بين 0 إلى 100 حيث 0 تعني أنه ﻻ يتم حدوث عملية الswap على الإطﻻق إلى في الحالات القصوى مثل أن تكون الذاكرة في كامل إستخدامها وﻻ يوجد مكان أخر في الذاكرة
    ال60(والتي بالمناسبة هي القيمة الإفتراضية) تعني أن الswap سيحدث بشكل شائع ومتوازن بين إستهﻻكه وإستهﻻك الذاكرة
    ال100 تعني أن الswap سيكون هو الخيار الإفتراضي دائماً,
    ولتغيير قيمة الswap يمكنك كتابة الأمر التالي
    sudo sysctl vm.swappiness=10 بالطبع يمكنك إستبدال 10 بالقيمة التي تريدها من أجل الswap
  11. إجابة شرف الدين حفني سؤال في خطأ في php mailer يظهر SMTP Error: Could not authenticate كانت الإجابة المقبولة   
    في حالة أنك كتبت البريد الإلكتروني وكلمة السر بشكل صحيح فغالباً يكون الخطأ من إعدادات البريد الإلكتروني , إن كنت تستخدم gmail
    إذهب إلى إعدادات الحماية قم بتفعيل " السماح بالوصول للتطبيقات الأقل أماناً" والسبب في تلك المشكلة أن جوجل يضيف طبقة من الحماية حتى يتأكد أنه لم يتم إختراق بريدك الإلكتروني من مصدر خارجي أو شئ من هذا القبيل.
  12. إجابة شرف الدين حفني سؤال في ﻻ يمكنني تغيير حجم صور svg في CSS كانت الإجابة المقبولة   
    ايقونات الsvg تعمل بشكل مختلف عن الصور مثل ال.png, .jpg , حيث عند تغيير خواص الحجم مايحدث فقط أنك تقوم بتغيير حجم المربع الحامل للأيقون, عند الحاجة لتغيير الحجم يجب عليك تغيير ملف الsvg نفسه, إفتحه في محرر الأكواد الخاص بك ستجده عبارة عن كود xml كما في هذا الشكل
    <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="309.000000pt" height="275.000000pt" viewBox="0 0 309.000000 275.000000" preserveAspectRatio="xMidYMid meet"> <g transform="translate(0.000000,275.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none"> <path d="M1275 2565 c-273 -37 -507 -162 -707 -373 -150 -160 -245 -344 -294 -567 -24 -111 -24 -360 0 -470 59 -268 181 -477 386 -660 307 -273 770 -366 1165 -233 346 116 632 398 748 738 46 135 62 233 62 390 0 357 -135 653 -406 895 -252 225 -606 329 -954 280z m400 -60 c112 -23 185 -50 297 -107 499 -254 738 -843 556 -1373 -132 -387 -448 -664 -858 -752 -116 -25 -334 -25 -450 0 -116 25 -189 51 -301 108 -629 321 -813 1135 -383 1699 55 73 195 206 264 251 137 91 309 158 470 184 106 18 296 13 405 -10z"/> <path d="M1695 1440 l-390 -390 -201 201 c-165 165 -205 200 -225 197 -17 -2 -25 -10 -27 -28 -2 -21 35 -62 222 -248 193 -193 226 -222 242 -214 11 6 203 195 428 420 375 376 407 411 397 431 -26 48 -44 33 -446 -369z"/> </g> </svg> سنركز الأن على الجزأ العلوي في الملف
    <svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="309.000000pt" height="275.000000pt" viewBox="0 0 309.000000 275.000000" preserveAspectRatio="xMidYMid meet"> تﻻحظ وجود خاصيتين width و height, قم بتغييرهم للقيمة التي تريد الحصول عليها.
    وأريد الإضافة أن نفس المشكلة ستقابلك إن حاولت تغيير لون الأيقونة, حيث يجب عليك تعديل لون الأيقونة أيضاً من نفس الملف, حيث ستﻻحظ وجود وسم إسمه path 
    <path d="M1275 2565 c-273 -37 -507 -162 -707 -373 -150 -160 -245 -344 -294 -567 -24 -111 -24 -360 0 -470 59 -268 181 -477 386 -660 307 -273 770 -366 1165 -233 346 116 632 398 748 738 46 135 62 233 62 390 0 357 -135 653 -406 895 -252 225 -606 329 -954 280z m400 -60 c112 -23 185 -50 297 -107 499 -254 738 -843 556 -1373 -132 -387 -448 -664 -858 -752 -116 -25 -334 -25 -450 0 -116 25 -189 51 -301 108 -629 321 -813 1135 -383 1699 55 73 195 206 264 251 137 91 309 158 470 184 106 18 296 13 405 -10z"/> ستقوم بإضافة خاصية تسمى fill وتضع فيها إسم اللون الذي تريده ولكن بصيغة السادس عشر hexa code 
    <path fill="#fff" d="M1275 2565 c-273 -37 -507 -162 -707 -373 -150 -160 -245 -344 -294 -567 -24 -111 -24 -360 0 -470 59 -268 181 -477 386 -660 307 -273 770 -366 1165 -233 346 116 632 398 748 738 46 135 62 233 62 390 0 357 -135 653 -406 895 -252 225 -606 329 -954 280z m400 -60 c112 -23 185 -50 297 -107 499 -254 738 -843 556 -1373 -132 -387 -448 -664 -858 -752 -116 -25 -334 -25 -450 0 -116 25 -189 51 -301 108 -629 321 -813 1135 -383 1699 55 73 195 206 264 251 137 91 309 158 470 184 106 18 296 13 405 -10z"/> وتلك مقالة قد تجدها مفيدة إن أردت معرفة المزيد عن ملفات الsvg وإستعمالها في الويب
     
  13. إجابة شرف الدين حفني سؤال في ما المقصود بعملية إعادة التصنيع refactoring؟ كانت الإجابة المقبولة   
    عملية إعادة التصنيع (refactoring) يُقصد بها إعادة كتابة الشفرة البرمجية أو إعادة كتابة جزءاً من الشفرة البرمجية بغرض:
    تحسين كفائة الشفرة البرمجية من حيث الأداء تحسين الكفاءة من حيث جعلها أسهل فهماً التأكد من سهولة تطوير الشفرة البرمجية وتمديدها extend وبوجه عام فإن غالبا الشفرة البرمجية التي نحتاج أن نقوم بإعادة تصنيعها (refactoring) تكون هي الشفرة التي ﻻ تراعي المبادئ الخمسة SOLID Principles والتي تنص على التالي
    مبدأ المسؤلية الواحدة: وهو مبدأ ينص على أن لكل class مسؤلية واحدة , وكل دالة فيه يكون لها وظيفة واحدة فقط ﻻ أكثر
    مبدأ المفتوح - المغلق: ينص هذا المبدأ على أن أي نظام يكون مفتوح للتمدد مغلق للتعديل
    مبدأ ليسكوف للإستبدال: إذا كان النظام يستخدم class معين فإنه يجب أن يكون قادراً على إستخدام أي class مشتق منه 
    مبدأ فصل الواجهات (interface Segregation) : ﻻ يجب أن تحتوي الواجهات interfaces على دوال قد ﻻ يحتاج المستخدم لإستخدامها, حيث يجب إختيار الدوال في الواجهات بعناية
    مبدأ عكس الإعتمادية (dependency inversion): ينص على أن classes المستويات العليا ﻻ يجب أن تعتمد على classes المستويات الدنيا , فمثلاً إن كان لدينا class مُسمى سيارة و class أخر مُسمى محرك , فﻻ يجب أن تعتمد السيارة على المحرك
    وبالأسفل بعض المقالات المفيدة في فهم هذا الموضوع بشكل أفضل
     
  14. إجابة شرف الدين حفني سؤال في أيهما أفضل استخدم cin أم scanf في لغة ++C كانت الإجابة المقبولة   
    حقيقي أن ال  scanfو printf أسرع من cin و cout ولكن يمكن تعديل ذلك
    حيث يكمن تفوق السرعة في أن مكابت الiostream في الc++ تحاول المحافظة على التزامن مع مكاتب إدخال وإخراج في لغة الc , إذا قمنا بإيقاف هذا التزامن ستتفوق مكاتب الc++
    ويمكننا تحقيق ذلك من خﻻل الكود الأتي
    std::ios::sync_with_stdio(false); إن قارنت نتائج إستخدام مكاتب الc مع مكاتب الc++ قبل تعطيل المزامنة ستجدها كالأتي
    iostream version: 24.3 seconds scanf version: 6.4 seconds بينما بعد تعطيل المزامنة نجد أن النتائج تحولت كالتالي
    scanf version: 6.8 seconds iostream with 5.5 seconds  
  15. إجابة شرف الدين حفني سؤال في الفرق بين foreach و iterator في جافا كانت الإجابة المقبولة   
    ال foreach هي نفسها كإستخدام الiterator ولكن بطريقة أسهل أو كما يُقال syntactic sugar
    حيث أن الforeach تقوم بإستخدام الiterator بشكل مخفي عن المستخدم بغرض التسهيل, فمثلاً الشفرة
    for (String i : list) { System.out.println(i); } أسهل من إستخدام الشفرة
    Iterator it=list.iterator(); while (it.hasNext()){ System.out.println(it.next()); } ولكن يجب التنويه أن إستخدام الiterator يعطيك تحكم أكبر قد تحتاجه حيث ﻻ يمكنك تنفيذ بعض الوظائف بالforeach بسبب عدم وجود تحكم كامل , فمثلاً إن أردنا حذف عنصر من المجموعة ﻻ يمكننا تحقيق ذلك بإستخدام الforeach بينما يعطينا الiterator القابلية لتحقيق ذلك الغرض
    for (String i : list) { list.remove(i); // سيتم إلقاء خطأ هنا } بينما بإستخدام الiterator
    Iterator it=list.iterator(); while (it.hasNext()){ it.remove(); // تعمل الشفرة بشكل سليم بدون إلقاء أيةِ أخطاء }  
  16. إجابة شرف الدين حفني سؤال في هل binary search tree خوارزمية؟ كانت الإجابة المقبولة   
    في الحقيقة يوجد خوارزمية بهذا الإسم بالإضافة إلى هيكل بيانات يحمل نفس الإسم,
    بالنسبة إلى هيكل البيانات شجرة البحث الثنائية: هو عبارة عن نوع من الأشجار الثنائية ولك يشترط أن يكون كل العناصر على يمين العنصر أكبر منه , وكل ماهو على يساره أصغر منه, كم هو واضح بالأدنى
    tree:{ root:rootElm } rootElm{ value:10, right:a, left:b } a{ value:15, right:a2, left:b2 } b{ value:5, right:ab3, left:b3 } وكل عنصر من العناصر على اليسار واليمين بالمثل اكبر مما على يساره وأصغر مما على يمينه.
    أما بالنسبة للخوارزميات فيوجد خوارزمية اسمها (خوارزمية البحث الثنائي) تُستخدم للبحث عن العناصر والتي تعتمد فكرتها على أن تكون مجموعة العناصر المُدخلة مُرتبة, فتقوم الخوارزمية بالنظر إلى العنصر بالمنتصف, إن كان العنصر المطلوب أكبر منه نبحث في الجزأ الأيمن للمصفوفة, إن كان أصغر نبحث في الجزأ الأيسر, ونقوم بعمل نفس التكنيك مع كل نصف منهما حتى نعصر على العنصر المطلوب
    x:7 input{1,3,4,5,7,8,10} mid=5<7 new input{7810} ......  
  17. إجابة شرف الدين حفني سؤال في كيف أعالج ظهور الخطأ ERR_HTTP_HEADERS_SENT في Express.js؟ كانت الإجابة المقبولة   
    بروتوكول الhttp يتضمن إرسال العميل بطلب , والرد عليه من قبل الخادم ومن ثم يتم إغﻻق الإتصال, ﻻ يمكنك إرسال أكثر من رد لنفس الطلب, وهذا هو ما يسبب ذلك الخطأ لديك أنك قمت بمحاولة إرسال أكثر من رد لنفس العميل حيث في السطر
    res.status(404).send("err") بعد تنفيذ ذلك السطر أعتقد أنك تظن بأن البرنامج سيقف ولن يتم إرسال ردود أخرى, ولكن ال node ﻻ تعمل بذلك الطريقة فبعد ذلك السطر سيكمل البرنامج تنفيذ باقي الشيفرة حتى يصل هنا
    user.save() .then(()=>res.json("user created")) وهنا يكون ثاني رد يحاول الخادم إرساله لنفس الطلب, ما الحل؟ الحل هو إيقاف الدالة بعد إرسال الرد الأول وذلك عن طريق وضع كلمة return التي بدورها ستقوم بإيقاف الدالة وإرجاع قيمة , كالتالي
    if(req.body.user.email==undefined){ res.status(404).send("err") return } بهذا الشكل نضمن عدم إرسال اكثر من رد من الخادم لنفس الطلب
  18. إجابة شرف الدين حفني سؤال في ماذا يعني الخطأ Strict types declaration is missing في PHP كانت الإجابة المقبولة   
    يجب أولاً أن تعلم بوجود ما يسمى بال Scalar types والذي يعني نوع بيانات يحمل قيمة واحدة مثل  Integer, string, float ,boolean
    عكسه لدينا الcompound types مما يعني نوع بيانات يحمل أكثر من قيمة مثل  array, map , حسناً , نرجع لسؤالك ماهو الstrict types? كما تعلم على الرغم من توافر إمكانية تعريفك للمتغير كنوع معين مثل
    function test(int $a, float $b) : int { return $a + $b; } test("sharaf",4) هنا قمنا بتعريف الparameters التي تمر بالدالة test أنهم من النوع  int & float على الرغم من ذلك قمنا بتمرير parameters من النوع string, int ومع ذلك سيعمل البرنامج دون أن يلقي خطأ, فائدة الstrict decleration أن يقوم بإلقاء خطأ عند محاولة تمرير بيانات من نوع غير المطلوب, وذلك لضمان أن يقوم المبرمج بكتابة برنامج منظم بشكل أكبر وأسهل للقراءة وأقل عرضة للbugs , فمثلاً الكود بالأعلى إن قمنا بتشغيله عند تفعيل الوضع الصارم(strict declaration) سيقوم بإلقاء خطأ
    Fatal error: Uncaught TypeError  
  19. إجابة شرف الدين حفني سؤال في ما المقصود بعملية projection في قواعد البيانات كانت الإجابة المقبولة   
    عملية projection يُقصد بها إختيار خواص معينة من العﻻقة مما ينشئ لنا عﻻقة جديدة , مثلا لدينا العﻻقات أو الجداول الأتية
    user(id,name,age) post(id,user_id,title) إن قمنا بإختيار الخاصية name, id من العﻻقة user هذا يُسمى projection لأننا قمنا بإختيار خواص معينة من العﻻقة , ويمكن تمثيله بالجملة الإستعﻻمية الأتية
    select id, name from user ويمكن للprojection أن يكون معقداً أكثر , مثلاً إن أردنا إختيار أسامى المنشورات التي قام المستخدم بنشرها سنحتاج أن نختار الtitle الخاص بالمنتجات التي لديها خاصية user_id مساوية لقيمة id الخاصة بالمستخدم, كما في الجملة التالية
    select title from post inner join user on user.id = post.user_id وبوجه عام عملية إستخراج عﻻقة من عﻻقة أخرى عن طريق إختيار خواص محددة يسمى projection
  20. إجابة شرف الدين حفني سؤال في ما الفرق بين المعامل الشرطي الثنائي والمعامل الشرطي الثلاثي في جافاسكريبت كانت الإجابة المقبولة   
    كلا المعاملان وظيفتهم المقارنة, الفرق أن ال=== تقوم بمقارنة القيمة ونوع البيانات , بينما == تقوم بمقارنة القيمة فقط
    فمثلا
    0=="0" تساوي true لأن ال== تقارن القيمة فقط , وكلاً منهم قيمتها صفراً
    بينما 0==="0" تساوي false لأن ال=== تقارن القيمة ونوع البيانات, وهنا نوع البيانات مختلف, احدهما نوعه رقم والأخر سلسلة نصية/ حرف
    والجدول التالي يوضح بعض الأشياء التي قد تسبب الحيرة للمبرمج أثناء التعامل مع هذان المعاملان
    0 == false // حقيقي, لأن قيمة ال"غير حقيقي" تساوي صفراً 0 === false // غير حقيقي, لأن على الرغم أن قيمة ال"غير حقيقي" تساوي صفراً , إلا أن نوعها ليس رقم وإنما Boolean 1 == "1" // حقيقي, لأ، كلاً منهما قيمته ب1 على الرغم من إختﻻف نوع البيانات 1 === "1" // غير حقيقي لأننا نستخدم علامة المساواة الثﻻثية والتي تهتم بنوع البيانات, فعلى الرغم أن كلاً منهم قيمته 1 إﻻ أن كلاً منهما له نوع بيانات مختلف null == undefined // حقيقي لأن لهم نفس القيمة null === undefined // غير حقيقي لأن عﻻمة المساواة الثلاثية تتوجب أن يكون لهم نفس نوع البيانات '0' == false // حقيقي لأن عﻻمة المساواة الثنائية تهتم بالقيمة فقط , وقيمة ال"غير حقيقي" بصفراً '0' === false // غير حقيقي, لأن عﻻمة المساواة الثﻻثية تهتم بنوع البيانات, وهنا النوع مختلف  
  21. إجابة شرف الدين حفني سؤال في رفع مشروع React على GitHup و github pages كانت الإجابة المقبولة   
    ذلك لأنك تقوم برفع ملفات رى أكت دون أن تقوم بعمل build , يجب أن تقوم بعمل عملية build حتى تستطيع من رفع الملفات على git-hub ويمكنك إتباع الخطوات الأتية لرفع مشروعك على github-pages
    تأكد من تثبيت كلاً من node, npm, git على حاسوبك تثبيت gh-pages ك dev-dependency npm install gh-pages --save-dev  
    ضع خاصية الhomepage في ملف الpackage.json
    { ......, homepage:"http://{اسم المستخدم الخاص بك}.github.io/إسم المستودع" }  
    ضع scripts تقوم بعملية الbuild بإستخدام الnodeوال gh-pages حتي يتم نشر تطبيقك على الموقع
    "scripts": { //... "predeploy": "npm run build", "deploy": "gh-pages -d build" } بالطبع تلك الscripts سيتم كتابتها فى الpackage.json  
    قم بإنشاء مستودع على git hub
    git init git remote add origin {رابط المستودع} والأن قم بعملية deploy
    npm run deploy  
    مبروك تم رفع التطبيق ستجده في فرع gh-pages في github , بالإضافة لذلك ستجد التطبيق يعمل بشكل حي من خﻻل الرابط الذي وضعته في الhomepage في ملف package.json
  22. إجابة شرف الدين حفني سؤال في معنى streams في node.js كانت الإجابة المقبولة   
    ال stream هي واجهة تتيح للمبرمج قراءة وكتابة البيانات بشكل متواصل , في العادي إن أردت قراءة ملف ما تقوم بالتالي
    fs.readFile('/test.txt, 'utf8' , (err, data) => { if (err) { console.error(err) return } console.log(data) }) هنا تقوم الnode js بقراءة الملف كله على الذاكرة ومن ثم يمكنك إجراء العمليات عليه, هنا يوجد مشكلتان
    ﻻ يمكنك إجراء عمليات على الملف قبل إنتهاء قرائته كلياً إن كان حجم الملف كبير لن تستطيع الذاكرة إستيعابه مما قد يؤدى إلى خطأ Stack over flow ومن هنا يظهر دور الstream حيث تقوم بقراءة البيانات قطعة قطعة
    const fileSystem = require("fs"); var data = ""; const readStream = fileSystem.createReadStream("test.txt"); readStream.setEncoding("UTF8"); readStream.on("data", (chunk) => { data += chunk; }); readStream.on("end", () => { console.log(data); }); في هذا الكود قمنا بعمل إستماع للحدث(event listening) حيث كل مرة تصل فيها جزأ من البيانات يتم إطﻻق الحدث وتنفيذ الكود 
    readStream.on("data", (chunk) => { data += chunk; }); وعند إنتهاء البيانات يتم إطﻻق حدث الإنتهاء وتنفيذ الكود
    readStream.on("end", () => { console.log(data); }); وكما تﻻحظ حتى نستطيع إستخدام الstream قمنا بإنشاء ما يسمى بالreadStream , وهى الstream التي تمكننا من قراءة البيانات ووجه عام يوجد أربع أنواع من الstream
    readable stream: مسؤلة عن قراءة البيانات writable stream: مسؤلة عن كتابة البيانات duplex stream: يمكنها قراءة البيانات وكتابة البيانات transform stream: تقوم بقراءة البيانات ومعالجتها بشكلٍ ما ومن ثم كتابتها بعد المعالجة
  23. إجابة شرف الدين حفني سؤال في ماهو تعقيد الوقت complexity time في الخوارزميات وبنى المعطيات كانت الإجابة المقبولة   
    مفهوم تعقيد الوقت(time complexity) يعبر عن الوقت الﻻزم لتنفيذ الخوارزمية, ولكن ﻻ يتم حسابه بالثانية أو الدقيقة بل بعدد السطور البرمجية أو بمعنى أصح عدد التعليمات البرمجية, فمثلاً إذا كان لدينا خوارزمية تقوم بالتالي:
    قراءة قيمة من المستخدم ضرب القيمة في عشرة طباعة القيمة الجديدة هنا نستطيع أن نقول أن عدد السطور البرمجية التي تم تنفيذها ثلث أسطر, ولكن تعقيد الوقت هنا يساوي 1, ما السبب؟ السبب أن تعقيد الوقت يتم حسابه بالنسبة للمدخلات, فمثلاً في المثال السابق لن يفرق إن أدخل المستخدم 10 أو 100 أو 11000000
    في كل تلك الحالات سيكون لدينا نفس عدد التعليمات البرمجية, بينما إن قمنا بإنشاء البرنامج التالي:
    خذ مجموعة عناصر من المستخدم قم بزيادة رقم واحد على كل عنصر منهم إطبع العناصر الجديدة في تلك الحالة كل مازاد عدد العناصر زاد عدد التعليمات البرمجية التي يقوم الحاسب بتنفيذها
    ويوجد عدة طرق لحساب التعقيد الوقتي مثل:
    BigO: والتي تعبر عن القيمة التي يكون الوقت اقل او مساوى لها Big Omega: تعبر القيمة التي يكون الوقت اكبر او مساوي لها Big Theta: تعبر عن القيمة التي يكون الوقت مساوي لها أو نستطيع أن نقول أن ال BigO يعبر عن اسوأ حالة للخوارزمية, بينما الBig Omega يعبر عن افضل حالة للخوارزمية بينما Big Theta تعبر عن الحالة المتوسطة
  24. إجابة شرف الدين حفني سؤال في ما معنى أنماط التصميم design pattern كانت الإجابة المقبولة   
    انماط التصميم(design patterns) ترمز لطريقة معينة لحل مشكلة شائعة نوعا ما في عالم الSoftware , مثلاً نوع من المشاكل هو كيفية إنشاء الكائنات؟ يوجد عدد ﻻ نهائي من الطرق لإنشاء الكائنات بالتأكيد حسب الموقف ولكن يوجد مواقف شائعة يمكننا مناقشتها والإهتمام بها, مثلاً إن كنا نريد إنشاء كائن وكان هذا الكائن لديه الصفات الأتية
    هذا الكائن مشترك بين عدد من الكائنات في البرنامج عملية إنشاء الكائن مكلفة وتستهلك كميةً لا بأس بها من موارد الجهاز هذا الكائن ليس له state معينة, او الstate الخاصة به مشتركة بين الكائنات في البرنامج طوال دورة حياة البرنامج( الstate نقصد بها حالة الكائن ,مثلاً إن كان يعبر عن إتصال بقاعدة البيانات, فهل حالة الكائن هي أن الإتصال مفتوح ؟ أم تم إغﻻق الإتصال؟ في هذه الحالة ليس من العقل أن نقوم بإنشاء الكائن في كل مرة نحتاجه بها , من المنطقي أن نقوم بإنشاء ذلك الكائن مرة واحدة ويقوم باقي الكائنات بإستدعائه في كل مرة كما في المثال الأتي
    class singleTone{ private static singleTone obj=new singleTone(); private singleTone(){} public static singleTone getInstance(){ return obj; } } الconstructor الخاصة بهذا الclass من النوع الخاص privateمما يعنى أن لا يمكننا إنشاء كائنات منه, الطريقة الوحيدة للحصول على كائن منه هي مناداة الدالة getInstance والتي بدورها تقوم بإرجاع الكائن الذي قمنا بإنشاءه سابقاً في بداية الclass , ففي هذه الحالة نستطيع ضمان أن لن يتم إنشاء هذا الكائن أكثر من مرة , وبالمناسبة هذا النمط يُسمى بال singletone pattern   وقد وضعته حتى أوضح لك معنى انماط التصميم بشكل أفضل
  25. إجابة شرف الدين حفني سؤال في ما الفرق بين إستخدام let أو var في لغة جافاسكريبت كانت الإجابة المقبولة   
    الlet يكون مجاله بداخل القوسين الذي عرف بداخلهم , بينما الvar يكون مجاله ضمن الدالة التي عرف بها, لنفهم هذا الأمر سنكتب الكود التالي كمثال:
    function print() { var firtname = "sharaf"; let lastname = "ashraf"; console.log(firtname, lastname); // sharaf ashraf { var fname = "sharaf1" let lname = "ashraf1"; console.log(fname, lname); // sharaf1 ashraf1 } console.log(fname); // sharaf1 console.log(lname); // ReferenceError } run(); نﻻحظ ان كلا من المتغيرين fname, lname تم تعريفهم في نفس المجال, لكن على الرغم من ذلك عند طباعتنا لهم خارج الأقواس, يتم طباعة المتغير fname لأنه من النوع var ولكن يحدث خطأ عند محاولة طباعة lname لأنه من النوع let
    كما بالإضافة إلى أن عند تعريف المتغير من النوع var يتم إعطائه قيمة إبتدائية ب"غير معرف" حتى قبل إنشائه, بينما المتغير let إن حاولنا الوصول إليه قبل تعريف لا يأتينا قيمة "غير معرف" إنما يأتينا خطأ من النوع ReferenceError
×
×
  • أضف...