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

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

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

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

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

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

    2

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

  1. إجابة شرف الدين حفني سؤال في ما الفرق بين bootstrap4 و bootstrap5 كانت الإجابة المقبولة   
    يوجد عدد من الclasses تمت إضافتها وأخرون تمت إزالتهم, أمثلة على ما تمت إزالته :
    orm – row form – inline list – inline card – deck حيث كان لهم وجود في الإصدار 4 ولكن تمت إزالتهم من الإصدار الخامس.
    أمثلة على ماتمت إضافته:
    gx-* (للتحكم في المسافة الأفقية بين العواميد) gy-* (للتحكم في المسافة الرأسية بين الصفوف) g-* (للتحكم في كلاً من المسافات الرأسية والعمودية) ويوجد عدد كبير من الإختﻻفات الأخرى بين الإصدارين مثل:
    لدى نظام الشبكات(grid system) في الإصدار الرابع 5 طبقات xs,sm,md,lg,xl بينما تمت إضافة طبقة جديدة للإصدار الخامس وهي الطبقة xxl للشاشات الأكبر حجماً لدى الإصدار الخامس دعم أكثر للألوان حيث يحتوي على عدد من الألوان أكبر من الإصدار السابق له تم التخلي عن إستخدام الjquery في الإصدار الخامس والإعتماد على الجافاسكريبت دون مكتبات تم التوقف عن دعم متصفح internet explorer الإصدارين 10&11 مظهر عناصر الformأصبح ثابتا على جميع أنظمة التشغيل, بينما كان متغيراً حسب نظام التشغيل في الإصدار السابق تلك أمثلة من الإختلافات ,لم اذكر لك جميع الإختلافات حتى لا تشعر بالتشتيت , إن أردت ذكرها لك يمكننى ذلك, تحياتى
  2. إجابة شرف الدين حفني سؤال في كيف أحصل على query string في الرابط في next.js كانت الإجابة المقبولة   
    لا يمكنك الحصول عليها بإستخدام getStaticProps لأن دالة الgetStaticProps والgetStaticPaths يتم تنفيذهم في الstatic site generation بينما الquery يتم تمريرها وقت التشغيل, من الممكن تنفيذ ما تريده بإستخدام getServerSideProps بدلاً منها كما في الشكل الأتي
    export async function getServerSideProps(context) { const query = { context } const { id } = query const user = await getUsers(id) return { props: { users } } } وتستطيع إستلام الusers في الcomponent كما بالشكل الأتى
    export default function UsersPage({ users}) { return ( <h1>hello world</h1> ) }  
  3. إجابة شرف الدين حفني سؤال في هل يمكن لـ "list_display" في ModelAdmin عرض حقول foreign key في جانغو Django؟ كانت الإجابة المقبولة   
    لتستطيع مناداة حقل من الكائنات التي بينها علاقة يمكنك إنشاء دوال في الكائنات حتى تساعد على إرجاع الحقل المطلوب , فمثلاً في حالتك تريد أن تحصل على إسم المؤلف, إذا يمكنك أولا إنشاء دالة عند الكتاب تساعدك على ذلك
    class PostAdmin(admin.ModelAdmin): list_display = ['title', 'get_author', ] def get_name(self, obj): return obj.author.name get_name.short_description = 'author_name' #Renames column head ومن ثم يمكنك في ملف الPerson أن تضع إسم هذه الدالة في الlist_display
    class PersonAdmin(admin.ModelAdmin): list_display = ['post.author_name',]  
  4. إجابة شرف الدين حفني سؤال في goto في لغة جافا سكريبت كانت الإجابة المقبولة   
    هل تقصد goto كما في لغة c++?
    إن كان ذلك مقصدك فإن react js ليست لغة وإنما هي مكتبة , السؤال الصحيح هل يمكن إستخدامها في لغة جافاسكريبت أم لا, للأسف جافاسكريبت لا تدعم الgoto 
    ولكن ت دعم أشياء مشابهة مثل
    break تقوم بإستخدامها لإنهاء الحلقة التكرارية for, while ,do while  for(i=0;i<5;i++){ console.log(i) if(i==3) break; } ستلاحظ أن ناتج الطباعة 1 2 3 لأن من بعد الرقم 3 تم إستخدام الكلمة break التي أنهت الحلقة
    continue بدلاً من الخروج من الحلقة فإنها تقوم فقط بتخطي اللفة الحالية 
    for(int i=0; i<5;i++){ if(i==3) continue; console.log(i) } تلاحظ طباعة 1 2 4 5 , رقم 3 لم يطبع لأنه تم الخروج من اللفة وقتها
  5. إجابة شرف الدين حفني سؤال في كيفية استقبال الملفات باستخدام multer كانت الإجابة المقبولة   
    أولاً نقم بتثبيت mutler
    npm i multer بعد ذلك نقوم بإستدعائه والسماح لExpress بإستقبال البيانات من الforms عن طريق الbody-parser
    const multer = require('multer'); app.use(bodyParser.urlencoded({extended: true})) ونقم بإنشاء متغير الupload الخاص بmulter كما في الشفرة:
    var upload = multer({ dist:"your distination" }) عند الendpoint التي تريد إستقبال الملف فيها تضع اول parameter عنوان الendpoint والثاني 
    upload.single('file') والثالث الدالة الخاصة بالendpoint ,ومن ثم يمكنك الوصول إلى الملف بإستخدام 
    req.file  
  6. إجابة شرف الدين حفني سؤال في مالفرق بين composition و aggregation في مخططات UML كانت الإجابة المقبولة   
    الcomposition وال aggregation هما نوعين من الإرتباط (association)  ولكن يوجد عدة فروقات بينهما فمثلًا بالنسبة للcomposition
    تعنى أن العلاقة بينهما علاقة جزأية , بمعنى أن أحد الكائنين هو جزأ من الآخر ,كما هو الحال في المبنى وقالب الطوب أو السيارة والمحرك, فكل من المحرك وقالب الطوب هما أجزاء من المبنى والسيارة كل من الكائنين يعتمد على الأخر فلا يوجد سيارة بدون محرك ولا محرك بدون سيارة إذا كان هناك علاقة تركيب(composition) فلا يمكن للكائن المٌركب(composed) أن يتواجد بدون الكائن الأخر الaggregation
    تعنى أن العلاقة بينهم علاقة احتواء (has-a relationship) بمعنى أن الكائن الأول والثاني كل منهم يحتوي على الأخر ولكن بدون أن يكون جزأ منه مثل العلاقة بين المستخدم والمنشورات التي نشرها علاقة احادية الإتجاه, بمعنى أن المستخدم يمتلك المنشورات, لكن المنشورات لا تمتلك المستخدم لا تعتمد كائنات تلك العلاقة على بعضهم, فإذا حدث شئ للمستخدم لا يؤثر على المنشور ولا يؤثر المنشور على المستخدم
  7. إجابة شرف الدين حفني سؤال في لاأستطيع إنشاء trigger في mysql كانت الإجابة المقبولة   
    أعتقد سبب المشكلة أنك في الحقيقة لا تستخدم mysql وإنما تستخدم mariadb 
    إذا كنت تستخدم xampp فإعلم أن قاعدة البيانات الإفتراضية هي mariadb والتي تختلف قواعد كتابتها قليلًا عن قاعدة بيانات mysql ,لديك حلين
    أن تقوم بتحميل قاعدة بيانات mysql وتعمل عليها  الحل الأسهل أن تقوم بتغيير الكود حتى يكون مناسب مع mariadb كما في الشكل الآتي CREATE TRIGGER `on_comment` BEFORE INSERT ON `article_likers` FOR EACH ROW update articles set likes=likes+1 where articles.id= NEW.article_id حيث أن المشكلة تكمن في كلمتين BEGIN--END , عند إزالتهم ستلحظ أن الخطأ لم يعد موجودًا 
  8. إجابة شرف الدين حفني سؤال في نصائح للبدء في مجال problem solving كانت الإجابة المقبولة   
    الproblem solving يعتمد بشكل أساسي على الخوارزميات وهياكل البيانات, من الجيد أن تبدأ بدراسة الخوارزميات وهياكل البيانات, فإن جزأ كبير من المشكلات ستجده مبنى على تكتيكات مثل:
    الخوارزمية الجشعة(greedy algorithm) والتي تشبه الى حد كبير الحل البديهى للمسألة , حيث أنك تمر على عناصر المدخلات عنصر عنصر وتقم بعملية على كل عنصر حتى يتم حل المشكلة فرق واغزٌوا(divide and conquer) والتي اكتسبت إسمها من أحد تكتيكات الحروب في العصور الوسطى, حيث كان يتم تفرقة جيش الخصم إلى فرق صغيرة يسهل محاصرتهم للإقصاء, حيث يتم في هذا التكتيك الخوارزمي تقسيم المشكلة إلى مشاكل اصغر بإستخدام الrecursion ويتم حل كل مشكلة على حدة دون أن تتداخل مع مثيلتها حتى يتم حل المشكلة البرمجة الديناميكية(dynamic programming) تشبه الى حدٍ كبير التكتيك السابق ولكن لا تتم بالrecursion , وتتداخل نواتج حل المشكلات الصغيرة سويا حتى يتم إستخدام تلك النواتج لحساب الناتج للمشكلة ككل بفهمك لتلك التكتيكات وتكتيكات مختلفة أخرى بالإضافة إلى التدريب على مشكلات مختلفة سيساعدك على ترتيب وتحديد خطواتك لحل المشكلة, ولكن ستقابلك مشكلة أخرى وهى كيفية تخزين المدخلات للمشكلة؟ وهنا يأتى دور هياكل البيانات حيث تتعرف على هياكل مختلفة لحمل البيانات مثل المصفوفة array , الصفqueue, المكدس stack, القائمةlist, كل هيكل من تلك الهياكل المختلفة لديه عيوب ومميزات وكل هيكل منهم يُعد الأنسب لمشكلة ما
    الملخص: تعلم الخوارزميات وهياكل البيانات بالإضافة إلى اساسيات الرياضيات وتدرب على مشكلات مختلفة وعندها ستتعلم مواضيع أخرى تساعدك في فهم باقى المشكلات التي سوف تقابلها
  9. إجابة شرف الدين حفني سؤال في ما الفرق بين where و having في قواعد بيانات SQL كانت الإجابة المقبولة   
    having تستخدم عند إستخدام group by , ويتم إستخدامها لتصفية المجموعات , بينما where يتم إستخدامها لتصفية التسجيلات
    مثال: 
    select name, Count(1) From users Where rating >4 Group By rating في هذا الكود يتم إختيار الإسم وعدد العناصر من الجدول users ويتم فلترة التسجيلات حيث يتم إختيار فقط التقييمات الأكبر من 4 , ثم يقسمو مجموعات حسب تقييمهم
    حسنا ماذا إن أردنا تصفية المجموعات الناشئة بدلًا من تصفية التسجيلات فقط؟ , إليك مثال
    select name, Count(1) From users Where rating >4 Group By rating HAVING count(1)>3 في هذا المثال قمنا بتصفية التسجيلات حيث نختار الطلاب الذين تقييمهم أعلى من 4 وأيضًا قمنا بتصفية المجموعات حيث عرضنا فقط المجموعات التي تحتوي على أكثر من ثلاث طلاب, تلك هي وظيفة العبارة having , أن تقوم بتصفية المجموعات الناشئة من دوال الaggregation
  10. إجابة شرف الدين حفني سؤال في هل node.js تدعم multi threading؟ كانت الإجابة المقبولة   
    ال node js تستخدم thread واحد لجميع الطلبات ,ولكن في الكواليس يتم إستخدام multi threads, ما معنى هذا ؟ معنى هذا أن عمليات القراءة والكتابة(i/o operations) تحدث بإستخدام الmultithreading , وتلك العمليات تشمل
    القراءة والكتابة من و إلى قاعدة بيانات القراءة والكتابة من و إلى شبكة القراءة والكتابة من وإلى المساحة التخزينية أي عملية قراءة وكتابة أخرى فمثلا هذا الكود 
    funca(){ ///some code// fetch(URL).then(()=>callback()); ///some code } هنا يتم إستخدام الmulti threading في الخلفية حيث تتم عملية جلب البيانات بإستخدام الدالة fetch من خلال thread أخر محجوز في الnode js من أجل عمليات القراءة والكتابة, وفي نفس الوقت لدينا الthread الذى يستقبل الطلبات من المستخدمين والذى يقوم بتنفيذ باقي الكود
    فإذا كان لدينا 10 مستخدمين قاموا بإرسال طلب لكل مستخدم وكل طلب منهم يحتوي على عملية قراءة من قاعدة بيانات, في هذه الحالة يكون لدينا thread واحد فقط لمعالجة ال10 طلبات, و10 threads أخرين من أجل تنفيذ عمليات القراءة والكتابة 
  11. إجابة شرف الدين حفني سؤال في ما معنى use strict في لغة الجافاسكريبت كانت الإجابة المقبولة   
    الuse strict تجعل البرنامج يعمل في وضعية الstrict
    إذا ماهي وضعية الStrict ؟
    وضعية الstrict تفرض عليك بعض القيود عند كتابة الشيفرة البرمجية , تلك القيود مهمتها أن تجعل الشيفرة السيئة المقبولة "مرفوضة" ,بمعنى أن بعض العادات السيئة التي كان بإمكانك القيام بها عند كتابة شيفرة الجافاسكريبت لن يعد بإمكانك القيام بها , أمثلة من تلك العادات :
    لا يمكنك الإشارة إلى متغير أو كائن بدون أن تقم بتعريفه مسبقاً فمثلاً  "use strict"; name="sharaf" ; هذه الشفرة في المسبق كانت مقبولة ولن تتسبب بأخطاء, لكن بعد تفعيل وضعية الstrict او(الوضعية الصارمة) سيتسبب هذه السطر بخطأ لأنك قمت بالإشارة إلى المتغير name بدون أن تقم بتعريفه
    لا يمكنك حذف كائن أو متغير 
    let name = "sharaf"; delete name; هذه الشفرة تعمل بدون الوضعية الصارمة ولكن بعد تفعيل الوضعية الصارمة سيحدث خطأ لأنك حاولت أن تحذف المتغير name وهذا لا يعُد مقبولاً في الوضعية الصارمة
    لا يمكنك إستخدام النظام الثماني
    let octa_number = 010; هذه الشفرة ستتسبب في خطأ عند تفعيل الوضعية الصارمة لأن القيمة 010 تعد في النظام الثماني ليس العشري
    لا يمكنك الكتابة إلى كائن قمت بتعريفه مسبقاً بأنه مُعد للقراءة فقط
    "use strict"; const car = {}; Object.defineProperty(car, "name", {value:"bmw", writable:false}); car.name ="kia"; تلك الشفرة أيضا ستتسبب بخطأ عند إستخدام الوضعية الصارمة بسبب محاولتك للتعديل على كائن مُعد للقراءة فقط
    ويوجد العديد من القواعد الأخرى ,حتى لا أقوم بتشتيتك سأترك لك رابط ينص على القواعد جميعها
    اما عن فائدة هذه الوضعية فيمكن تلخيصها في الآتي:
    تقوم بإزالة ما يسمى بالأخطاء الصامتة, وهي تلك الأخطاء التي قد تسبب مشاكل في الشفرة مستقبلاً ولكن لا توقف تنفيذه فبالتالي تتحول الي bugs تجبرك على كتابة شفرة نظيفة منظمة قابلة للقراءة بسهولة تحسن من أداء الشفرة حيث أن عمليات التحسين "optimizations" يستطيع المحرك أن يحددها ويقم بها بسهولة أكبر عند تفعيل هذه الوضعية وها هو رابط يحتوي على قواعد الوضع الصارم https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
    وتلك مقالة من اكاديمية حسوب تشرح الوضع الصارم 
     
  12. إجابة شرف الدين حفني سؤال في الفرق بين composition و inheritance كانت الإجابة المقبولة   
    الinheritance "الميراث" عندما يكن لدينا الكلاس A وكلاس اخر من نفس نوعه ولكن مزود بخصائص اكثر يسمى class B , وعادة يتم استخدام الميراث كما قلنا عندما يكون B فعلا صنف ممتد من A مثل الuser وال adminUser
    يتم الميراث كما فى المثال:
    class User{ String name; int age; /////////getters and setters/ } class SuperUser extends User{ banUser(){ //////logic to ban user } unbanUser(){ ////logic to unban user } } في المثال السابق نجد ان الSuperUser لديه جميع خصائص الكلاس User ولديه بالاضافة إلى ذلك وظائف جديدة كحظر وفك الحظر عن المستخدمين
    ولكن إذا كان لدينا كلاس أخر يدعى book ,فهنا ليس من العقل ان يتم ميراثه من قِبل الكلاس user لإنهم ليسوا نفس النوع ,فهنا يتم استخدام الcomposition وهو أن يتم وضع الbook على هيئة خاصية للكلاس user كما في المثال
    class book{ String name; int price; ///////getters and setters//// } class User{ String name; int age; Book b; ///////getters and setters////// } هنا يمكننا استخدام دوال الكلاس book بدون ميراثه عن طريق استدعاء الكائن b
    وبوجه عام فإن الcomposition يتم تفضيله عن الinheritance(ميراث) لعدة اسباب من ضمنها :
    عدد من لغات البرمجة لا يدعم تعدد الميراث, بالإضافة الى أن تعدد الميراث يسبب مشاكل وتعقيد الcomposition يمكنك من تغيير نوع الكلاس المستخدم فى مرحة التشغيل(runtime) مثلاً إذا كان لدينا كلاس يسمى SuperBook وكلاس يسمى OrdinaryBook وكلاً منهم يشترك في نفس الواجهة البرمجية interface يمكنك في مرحلة الruntime أن تقم بتغيير خاصية الbook لدى الuser إلى الSuperBook او الOrdinaryBook ,بينما الميراث لا يحدث إلا في مرحلة الترجمة(compile time)  الcomposition اسهل في عملية الاختبار
  13. إجابة شرف الدين حفني سؤال في كيفية إرسال رسالة من عميل لعميل ثاني باستخدام Socket.io كانت الإجابة المقبولة   
    لا يمكنك إرسال رسائل من عميل لآخر بشكل مباشر, يجب إرسال الرسائل الى الخادم اولاً ثم يتم تمريرها الى العميل الاخر , كما في المثال بالادنى , لدينا endpoint لدى الخادم تسمى msg واللتي تأخذ parameters عبارة عن
    نص الرسالة:message
    معرف المرسل إليه :recieverId
    this.io.on('connection', (socket) => { socket.on('msg', (message) => { socket.broadcast.to(data.recieverId).emit('getMsg',{ msg:data.msg }); }); وتقم تلك الendpoint بإرسال الرسالة الى الكلاينت المطلوب من خلال الدالة broadcast.to.emit حتى يحدث fire لل event المسمى getMsgالكلاينت المرسل إليه ويستقبل الرسالة كما في المثال:
    clientSocket.on("getMsg",(data)=>doSomethingWithData(data)) ويتم إرسال الرسائل من العميل الى الخادم عن طريق اطلاق الحدث msg لدى الخادم من خلال الكلاينت كما هو موضح:
    socketClient.emit("msg",data);  
  14. إجابة شرف الدين حفني سؤال في التحويل من CSV إلى JSON في node.js كانت الإجابة المقبولة   
    يمكنك تحقيق ذلك عن طريق إستخدام الmodule المسمى بcsvtojson
    ويمكنك الحصول عليه عن طريق تثبيته من خلال حزمة الادوات npm  من خلال هذا الأمر
    npm install csvtojson ولتقم بتحويل ملف csv الى json نفعل كالأتي
    const csvParser=require("csvtojson"); csvParser().fromFile("ضع هنا مسار الملف").then(jsonFile=>doSomeThing(jsonFile)) وفي حالة كان ملف الcsv ضخم يمكنك تحويله عن طريق استخدام الstream وال pipe كما هو موضح فى المثال أدناه
    csv() .fromStream(ضع هنا reference لstrem تقم بقراءة الملف) .subscribe(function(json){ //يجب عليك معالجة كل جزأ من الملف على حدة لأنه يصل من خلال الstreamعلى هيئة chunks return new Promise(function(resolve,reject){ doSomeThing(json,function(){resolve()}) }) }) وللتوضيح, الفرق بين الكود بالأعلى وبالأدنى أن بالأعلى يتم قراءة الملف كله في الذاكرة ومن ثم تتم العملية عليه, بينما في المثال بالأدنى يتم قراءة الملف على هيئة اجزاء صغيرة ومعالجة كل جزأ منها على حدة حتى لا تمتلئ الذاكرة
  15. إجابة شرف الدين حفني سؤال في كيفية تشفير الكلمات السرية فى قاعدة البيانات كانت الإجابة المقبولة   
    عادةً كلمات السر فى قاعدة البيانات لا يحدث لها عملية تشفير وإنما يحدث عليها عملية Hashing
    ويوجد فرق بين التشفير وبين الhashing , فإان التشفير هو طريقة لتحويل النص الى نص اخر لا معنى له ويكن عادةً هناك ما يسمى بمفتاح التشفير اللذي يمكنك من تحويل الشيفرة الى الكلمة الاصلية مرة اخرى
    وانما الHashing هو عبارةة عن دالة احادية الإتجاه, اى إن دالة الHashing تقم بأخذ النص الأصلي وتحويله الى نص اخر , ولكن لا يوجد مفتاح ليقم بإرجاع الشيفرة الى النص الاصلي, وهذا هو ما يحدث للكلمات السرية في قواعد البيانات من اجل ضمان امن البيانات فإذا حدث اختراق في قاعدة البيانات لا يستطيع المخترق معرفة مفتاح التشفير ويحصل على جميع المعلومات, فإنه لا يوجد في الأساس مفتاح تشفير وبالتالي لا يكون المخترق قادرً على اختراق البيانات
    وتتم عملية الHashing عادة بإستخدام دالة تسمى B-crypt وهي من أشهر دوال الhashing
  16. إجابة شرف الدين حفني سؤال في عمل دالة اقتطاع النص في php كانت الإجابة المقبولة   
    حسب ما فهمت انك تريد ان تبدل المسافات بعلامة - صحيح؟
    إذا كان الأمر كذلك فان سبب المشكلة لديك ان كلا من السطرين 
    $string = preg_replace('#[^\w]#', ' ' , $string); $string = preg_replace('#[\s]+#', ' ', $string); كل ما يفعلونه انهم يقومون بتحويل المسافات, الى مسافات مرة اخرى , وهذا لان الرمز \s يرمز للمسافات
    والرمز \w يرمز لاى رمز غير الحروف الابجدية, فاذا انتا تقوم بتحويل الرموز والمسافات الى مسافات مرة اخرى بدل من تحويلهم الى شرطة -
    والسطر الاخير والاول 
    $string = trim($string); return trim(strtolower($string), '-') وظيفتهم أنهم يمسحون المسافات من الجانب الايمن والايسر بفضل الدالة trim ولكن ماذا عن المسافات فى المنتصف بين الكلام؟
    الحل ان تقم باستخدام دالة preg_replace كما فعلت سابقا, ولكن تقم باستبدالهم بشرطة - بدلاً من تبديلهم بمسافات كما في الكود الاتي:
    function seo($string) { $string = trim($string); $string = preg_replace('/\s+/', '-', $string); return strtolower($string); }  
  17. إجابة شرف الدين حفني سؤال في ما الفرق بين useCallback و useMemo في React.js كانت الإجابة المقبولة   
    في react عندما تنشئ function وتمررها الى child component , ففى كل مرة تتغير حالة الparent component ويحدث re-render نجد أن الجافاسكريبت تتعامل وقتها مع الcallback function ع أنها دالة جديدة فيحدث re-render للchild component ,هنا حدثت عملية render اضافية بلا فائدة مما يؤثر سلبا على الاداء,إذا ما الحل؟
    الحل أن نقم بعملية memoization للدالة الممررة للchild component حتى تتعامل معها الجافاسكريبت كل مرة ع أنها نفس الدالة مالم يحدث لها تغيير وبهذا نكون عالجنا مشكلة الrender الاضافي مما يحسن الأداء
    مثال: 
    function Parent({ ... }) { const [a, setA] = useState(0); const onPureChange = useCallback(() => {doSomething();}, []); ... return ( ... <Pure onChange={onPureChange} /> ); } في هذا المثال عندما تتغير قيمة a يحدث render لل parent component وال Child component
    بينما إذا قمنا باستخدام الuseCallback على هذا الوجه في المثال الادنى:
    const [a, setA] = useState(0); const onPureChange = useCallback(() => {doSomething();}  لا يحدث render لل child component عند تغيير قيمة الa 
    اما بالنسبة لل useMemo فإنها تقم ايضا بعملية memoization ولكن ليس للدالة نفسها وانما للناتج , ويستخدم عندما يكون لدينا دالة تقم بعمليات حسابية طويلة وتستهلك موارد وأداء وفى نفس الوقت لا يتغير ناتج الدالة كثيرا, في هذه الحالة يكن الحل الامثل ان نخزن الناتج فى useMemo hook حتى لا يحدث render اضافى عند تمرير الدالة وفى نفس الوقت لا نحتاج لنداء نفس الدالة كل مرة يحتاجها الchild component لأن ببساطة ناتج الدالة مخزن بالفعل
    فلو قمنا باستخدام useMemo عوضا عن useCallback فى المثال السابق,فاننا لسنا فقط نخزن الreference الخاص بالدالة انما ايضا نقم بتخزين ناتج الدالة فلا نحتاج لاستدعائها 
  18. إجابة شرف الدين حفني سؤال في ما هو ال header فى http request كانت الإجابة المقبولة   
    ال Headers تحتوى على معلومات اضافية للطلب, مثلا لو افترضنا انك ارسلت طلبا من المتصفح لسيرفر الفيسبوك لتسجيل الدخول فيكون شكل بيانات الطلب مثلا على النحو الاتى {username:"ahmed_ibrahim@gmail.com,password:"xxxx"} ولكن ماذا عن معلومات الكاشينج؟ معلومات الauthentication ,معلومات حول صيغة البيانات المرسلة Content-type كل تلك المعلومات الاضافية اللتى هى معلومات عن الطلب ذات نفسه وليست عن طلبك انت تحديدا يتم وضعها فى الheaders
    فمثلا لو شرحنا الheaders اللتى وضعتها حضرتك خطوة خطوة:
    'Content-Type': 'application/x-www-form-urlencoded' تعنى ان بيانات الطلب مرسلة من form ولا تحتوى على ملفات او بيانات binary ,اى كلها نصية
    'x-requested-api': 'ocapi', 'x-requested-with': 'XMLHttpRequest', معلومات لضمان حماية الموقع من الcsrf attack 
    Accept: 'application/json' تعنى ان العميل يفهم الداتا بصيغة json فيجب على الخادم ان يرسل الداتا بنفس الصيغة
×
×
  • أضف...