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

لوحة المتصدرين

  1. Zen Eddin Allaham

    Zen Eddin Allaham

    الأعضاء


    • نقاط

      11

    • المساهمات

      960


  2. Rubu Studyrubu

    Rubu Studyrubu

    الأعضاء


    • نقاط

      4

    • المساهمات

      2


  3. حنان محمد12

    حنان محمد12

    الأعضاء


    • نقاط

      2

    • المساهمات

      5


  4. Ibrahim Almahdy

    Ibrahim Almahdy

    الأعضاء


    • نقاط

      2

    • المساهمات

      293


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 10/19/25 في كل الموقع

  1. اريد الاستشارة بما انكم مجموعة متخصصة في مجال التقنية أترون انه من الأفضل: ان اتخصص في الذكاء الاصطناعي وادرس علوم الكمبيوتر عن طريق الاونلاين أو اتخصص في هندسة البرمجية وادرس علوم الكمبيوتر والai عن طريق الاونلاين؟ (اطمح لهندسة الروبوتات ولكن هذا التخصص لم يتوفر بعد لهذا افكر في اقرب بدائل له)
    4 نقاط
  2. رفعت مشروع في Vercel لكن انا استخدم وحدات fs path في رفع صور لكن لماذا vercel يطلب Cloudinary ولا يستطيع تعامل مع fs path
    3 نقاط
  3. الحمدلله انتهيت من مشروع تخرج وباقي فقط رفع لكن اريد معرفة ماذا يعني قصور في مشروع
    3 نقاط
  4. الان انا ب انتظار مراجعة مشروع تخرج لكي احصل على شهادة بس بدي اعرف شهادة اكاديمية حسوب هل لها فترة انتهاء صلاحية وتصبح فقط ورقة
    2 نقاط
  5. أريد شرح مجمل عن دورة الذكاء الاصطناعي والنتائج المتوقع الخروج منها وطبيعة المشاريع التي سيتم العمل عليها
    2 نقاط
  6. السلام عليكم انتهيت من مشروع تخرج وسلمته للمركز مساعدة بس ليش مركز مساعدة يتأخرو برد
    2 نقاط
  7. الان بدأ يرفع صور بنجاح لكن لا يتم عرض صور في واجهة رئيسية بعد ما استخدمنت Cloudinary برغم انها تحفظ في قاعدة بيانات https://image-gallery-llmy3g4pa-zen-allahams-projects.vercel.app/ "use server"; import { NextRequest, NextResponse } from "next/server"; import { connectDB } from "@/app/libs/connectDB"; import { isAuthenticate } from "@/app/libs/isAuthenticate"; import Image from "@/app/models/Image"; import { v2 as cloudinary } from "cloudinary"; import { Readable } from "stream"; cloudinary.config({ cloud_name: process.env.CLOUDINARY_CLOUD_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, }); function bufferToStream(buffer: Buffer) { const readable = new Readable(); readable._read = () => {}; readable.push(buffer); readable.push(null); return readable; } export async function POST(request: NextRequest) { try { await connectDB(); const user = await isAuthenticate(request); if (!user) { return NextResponse.json({ message: "غير مصرح" }, { status: 401 }); } const formData = await request.formData(); const title = formData.get("title") as string; const description = formData.get("description") as string; const file = formData.get("file") as File; if (!file) { return NextResponse.json({ message: "اختر صورة أولاً" }, { status: 400 }); } const fileBuffer = Buffer.from(await file.arrayBuffer()); const uploadResult = await new Promise<any>((resolve, reject) => { const stream = cloudinary.uploader.upload_stream( { folder: "images" }, (error, result) => { if (error) reject(error); else resolve(result); } ); bufferToStream(fileBuffer).pipe(stream); }); // إنشاء مستند جديد في MongoDB const newImage = await Image.create({ title, description, imageUrl: uploadResult.secure_url, userId: user._id, likes: 0, likedBy: [], }); return NextResponse.json({ success: "تم رفع الصورة بنجاح", image: newImage, }); } catch (err) { console.log(err); return NextResponse.json( { message: "حدث خطأ في السيرفر" }, { status: 500 } ); } } import { connectDB } from "@/app/libs/connectDB"; import Image from "@/app/models/Image"; import { NextRequest, NextResponse } from "next/server"; export async function GET(request:NextRequest){ try{ await connectDB(); const images = await Image.find().sort({createdAt: -1}); return NextResponse.json(images); }catch(err){ console.log(err); return NextResponse.json({ message: "حدث خطأ في السيرفر" }, { status: 500 }); } }
    1 نقطة
  8. متى سيتم نزول التحديثات للمسارات المؤرشفة والتي لم يتم استبدالها بالتحديث وهل مسار react سيتم تحديثه ؟
    1 نقطة
  9. إنشاء تطبيق أسئلة وأجوبة باستخدام Next.js
    1 نقطة
  10. إن المشكلة الأساسية بالفعل في جداول التجزئة (Hash Tables) هي الاصطدامات (Collisions) وأنت محق تماما والطريقة التي استخدمتها في الكود الخاص بك هي مثال جيد للتعليم مثلا والتطبيقات البسيطة ولكنها غير فعالة في التطبيقات الحقيقية لنفس السبب الذي ذكرته وهو أن الكلمات التي تبدأ بنفس الحرف ستتكدس في نفس القائمة المتصلة (Linked List) مما يبطئ البحث بشكل كبير. والآن لنجيب على أسئلتك بالترتيب . ما هي العملية التي تتم على الكلمات لإيجاد الدلو (Bucket) المناسب : هذه العملية تسمى دالة التجزئة (Hash Function) ووظيفتها هي تحويل أي مدخل في حالتنا هنا الكلمة النصية إلى رقم صحيح فريد قدر الإمكان وهذا الرقم هو الذي يحدد فهرس (index) الدلو الذي ستُخزن فيه الكلمة. دالة التجزئة التي استخدمتها بسيطة جداً: short hash = toupper(vocabulary[0]) - 'A' وهي تأخذ الحرف الأول فقط وهذا هو سبب ضعفها فدالة التجزئة الجيدة يجب أن تحقق هدفين رئيسيين: أن تأخذ كل حروف الكلمة في الحسبان بحيث إذا تغير أي حرف في الكلمة، يتغير ناتج الدالة بشكل كبير. أن توزع النواتج بشكل متساوي يجب أن توزع الكلمات على كل ال Buckets المتاحة في الجدول بشكل عشوائي ومتساوي قدر الإمكان لتجنب التكدس في أماكن معينة. وإليك مثال على دالة تجزئة أفضل (Polynomial Rolling Hash) وهذه واحدة من أشهر وأبسط الطرق الفعالة والفكرة هي إعطاء كل حرف في الكلمة وزن مختلف بناءً على موقعه فمثلا نختار رقم أولي وليكن 31 ونمر على حروف الكلمة واحدا تلو الآخر ونحسب قيمة الـ hash كالتالي: hash = (hash * 31 + character_value) % TABLE_SIZE مثال لكلمة "CS50" لنفترض أن حجم الجدول TABLE_SIZE هو 1000. C (قيمته 67): hash = (0 * 31 + 67) % 1000 = 67 S (قيمته 83): hash = (67 * 31 + 83) % 1000 = (2077 + 83) % 1000 = 2160 % 1000 = 160 5 (قيمته 53): hash = (160 * 31 + 53) % 1000 = (4960 + 53) % 1000 = 5013 % 1000 = 13 0 (قيمته 48): hash = (13 * 31 + 48) % 1000 = (403 + 48) % 1000 = 451 % 1000 = 451 إذا كلمة "CS50" سيتم تخزينها في الدلو رقم 451 لاحظ كيف أن كل حرف وموقعه أثر في النتيجة النهائية. ثانيا كيف تتم عملية تقسيم وتوسيع الجدول : هنا يأتي دور الإجابة على سؤالك الأول فالمشكلة في الكود الخاص بك ليست فقط في دالة التجزئة ولكن أيضا في حجم الجدول لديك 26 دلو فقط وهو عدد الحروف الأبجدية وهكذا إذا كان لديك قاموس يحتوي على 140,000 كلمة ففي المتوسط سيكون كل دلو يحتوي على 140,000 / 26 ≈ 5384 كلمة وهذا عدد كبير جدا. زالحل هو ببساطة زيادة عدد ال Buckets فبدلا من 26 دلو يمكننا استخدام عدد أكبر بكثير مثلا 5000 دلو أو أكثر وكلما زاد عدد ال Buckets قل احتمال حدوث الاصطدامات وبالتالي أصبحت القوائم المتصلة (Linked Lists) أقصر بكثير. ولاحظ في دالة التجزئة التي وضحتها لك سابقا الخطوة الأخيرة وهي % TABLE_SIZE (باقي القسمة على حجم الجدول) فإن هذه العملية تضمن أن ناتج الدالة hash سيكون دائما رقم صحيح يقع بين 0 و TABLE_SIZE - 1 وهو ما يمثل فهارس ال Buckets المتاحة في الجدول. إذا تلخيصا لما سبق : لجعل جدول التجزئة الخاص بك فعال لتخزين قاموس ضخم فستحتاج إلى أمرين: زيادة حجم الجدول بشكل كبير أى زيادة ال Buckets وهذا يقلل من احتمالية أن تقع كلمتان مختلفتان في نفس الدلو. استخدام دالة تجزئة قوية فدالة تأخذ كل حروف الكلمة في الحسبان لتوزيع الكلمات بشكل متساو على جميع الBuckets المتاحة. وبهاتين الطريقتين ستحافظ على القوائم المتصلة قصيرة وبالتالي يصبح زمن البحث عن أي كلمة قريبًا جدًا من الزمن الثابت O(1)، وهو الهدف الأساسي من استخدام جداول التجزئة.
    1 نقطة
  11. المشكلة ليست في فكرة الـ Hash Table نفسها، بل في دالة التجزئة التي استخدمتها وحجم الجدول الصغير، فالدالة ليست جيدة: short hash = toupper(vocabulary[0]) - 'A'; لأنها تعتمد فقط على الحرف الأول من الكلمة، بالتالي كل الكلمات التي تبدأ بنفس الحرف مثل Apple, Ant, Art, Around وستذهب إلى نفس الـ Bucket أي نفس الخانة في المصفوفة dictionary، وفي اللغة الإنجليزية، هناك حروف تبدأ بها كلمات كثيرة جداً مثل S, T, A وحروف أخرى نادرة كـ X, Z, Q، لذا سيحدث تكتل أي Clustering فبعض الـ Buckets ستحتوي على Linked Lists طويلة جدًا. وعند البحث عن كلمة تبدأ بحرف شائع، ستضطر للمرور على قائمة طويلة، ويصبح أداء البحث يقترب من O(n) في أسوأ الحالات، ويلغي الفائدة من استخدام الـ Hash Table. أيضًا حجم الجدول صغير، فلديك 26 Bucket فقط، وهو عدد قليل جدًا بالنسبة لقاموس ضخم يحتوي على آلاف الكلمات. وبالنسبة للتقسيم فالأفضل للكلمات يعتمد بشكل مباشر على العملية التي تتم على الكلمات أي دالة التجزئة، والجيد منها يعمل على توزيع الكلمات بشكل عشوائي ومتساوٍا قدر الإمكان على جميع الـ Buckets المتاحة، ولفعل ذلك يجب أن تضع في الاعتبار الكلمة بأكملها، وليس فقط الحرف الأول. بيحث نفس الكلمة يجب أن تعطي نفس قيمة الـ Hash في كل مرة، وتعتمد على كل حروف الكلمة وأي تغيير بسيط في الكلمة مثل cat و car يؤدي إلى قيمة Hash مختلفة. وأن توزع الكلمات بشكل متساوٍا على الـ Buckets المتاحة لتجنب التكتل. مثال بسيط للتوضيح مع الوضع في الإعتبار ما سبق، وهي دالة تستقبل مجموع قيم ASCII لكل الحروف في الكلمة. unsigned int hash(const char* word, unsigned int N) { unsigned int sum = 0; for (int i = 0; word[i] != '\0'; i++) { sum += word[i]; } return sum % N; } لكن ما زالت ليس جيدة كفاية، فالكلمتان cat و act لهما نفس الحروف وبالتالي ستحصلان على نفس قيمة الـ Hash وذاك يسمى تصادم - Collision. وذلك ما تم تحسينه في الدالة التالية: unsigned int hash_djb2(const char *word, unsigned int N) { unsigned long hash_value = 5381; int c; while ((c = *word++)) { hash_value = ((hash_value << 5) + hash_value) + c; } return hash_value % N; } توفر قيم مختلفة لكلمتي cat و act، وستوزع الكلمات بشكل ممتاز. بعد الدالة السابقة لم يعد من المنطقي استخدام جدول بحجم 26 فقط، فلو القاموس يحتوي على 140,000 كلمة، فالأفضل استخدام جدول بحجم كبير لتقليل احتمالية التصادمات وجعل القوائم المتصلة قصيرة جدًا. أي بدلاً من تعريف الجدول هكذا: #define ALPHABETS 26 node* dictionary[ALPHABETS] = {NULL}; نقوم بتعريفه بحجم أكبر بكثير، وكقاعدة عامة حجم الجدول يكون عدد أولي قريب من عدد العناصر التي تتوقع تخزينها أو أكبر، لأنّ استخدام عدد أولي يساعد في تحسين التوزيع عند استخدام عملية باقي القسمة %. #define N_BUCKETS 10007 node* dictionary[N_BUCKETS] = {NULL}; وبالتالي بدلاً من حساب الـ Hash بناءًا على الحرف الأول، نستخدم الدالة الجديدة: for (int i = 0; i < n_of_words; i++) { string vocabulary = get_string("Word: "); // بدلاً من // short hash = toupper(vocabulary[0]) - 'A'; unsigned int hash_index = hash_djb2(vocabulary, N_BUCKETS); insert_node(&dictionary[hash_index], vocabulary); }
    1 نقطة
×
×
  • أضف...