العودة للدورة|إتقان مقابلات تصميم الأنظمة: بنية قابلة للتوسع من التقدير إلى الإنتاج
معمل

ابنِ واجهة خلفية لمشاركة الركوب

35 دقيقة
متقدم
محاولات مجانية غير محدودة

التعليمات

أنظمة مشاركة الركوب مثل Uber وLyft من بين أكثر أسئلة مقابلات تصميم الأنظمة شيوعاً. تختبر فهمك للفهرسة الجغرافية المكانية والمطابقة الفورية والتسعير الديناميكي وآلات الحالة. في هذا المختبر، ستبني المكونات الأساسية للواجهة الخلفية التي تُشغّل خدمة مشاركة الركوب.

نظرة عامة على البنية

rideshare/main.py (نقطة دخول المحاكاة)
  ├── rideshare/geo/geohash.py           — تشفير/فك تشفير Geohash
  ├── rideshare/geo/spatial_index.py      — فهرس مكاني للاستعلامات القريبة
  ├── rideshare/matching/matcher.py       — خوارزمية مطابقة الرحلات
  ├── rideshare/matching/eta_calculator.py — حساب وقت الوصول (Haversine)
  ├── rideshare/pricing/surge_calculator.py — التسعير الديناميكي
  ├── rideshare/pricing/fare_calculator.py  — حساب الأجرة
  └── rideshare/tracking/ride_tracker.py   — آلة حالة دورة حياة الرحلة

تعليمات خطوة بخطوة

FILE 1: rideshare/geo/geohash.py

نفّذ تشفير وفك تشفير geohash للفهرسة الجغرافية المكانية.

  • شفّر خط العرض/الطول إلى سلسلة geohash بدقة قابلة للتكوين (افتراضياً 6)
  • استخدم تشابك البتات: تناوب بين بتات خط الطول وخط العرض
  • فك تشفير سلسلة geohash إلى خط عرض/طول تقريبي (مركز الخلية)
  • احسب خلايا geohash الثمانية المجاورة لـ geohash معين
  • استخدم أبجدية Base32: 0123456789bcdefghjkmnpqrstuvwxyz

FILE 2: rideshare/geo/spatial_index.py

ابنِ فهرساً مكانياً يستخدم geohashes للاستعلامات القريبة السريعة.

  • أدرج السائقين مع موقعهم الحالي (خط العرض، خط الطول)
  • أزل السائقين عندما يصبحون غير متصلين أو يتم مطابقتهم
  • استعلم عن السائقين القريبين ضمن نصف قطر معين باستخدام بادئة geohash + توسيع الجيران
  • احسب المسافات الفعلية باستخدام Haversine لتصفية الإيجابيات الخاطئة من تقريب geohash
  • أعد النتائج مرتبة حسب المسافة من نقطة الاستعلام

FILE 3: rideshare/matching/matcher.py

نفّذ خوارزمية مطابقة الرحلات التي تجد السائق الأمثل.

  • سجّل السائقين بناءً على مزيج مرجّح: المسافة (40%)، وقت الوصول (30%)، التقييم (30%)
  • اصفِ السائقين الذين يتجاوزون أقصى مسافة التقاط
  • اصفِ السائقين الذين لا يتوافق نوع مركبتهم مع طلب الرحلة
  • أعد أفضل تطابق أو None إذا لم يتوفر سائقون
  • ادعم أنواع مركبات مختلفة: اقتصادي، مريح، فاخر

FILE 4: rideshare/matching/eta_calculator.py

احسب وقت الوصول المقدّر للسائقين.

  • استخدم صيغة Haversine لحساب مسافة الدائرة العظمى بين نقطتين
  • طبّق مضاعف عامل الطريق (افتراضياً 1.4) لأن الطرق ليست خطوطاً مستقيمة
  • طبّق مضاعف حركة المرور بناءً على وقت اليوم (ساعة الذروة = مضاعف أعلى)
  • أعد وقت الوصول بالدقائق مع مكوني المسافة والوقت

FILE 5: rideshare/pricing/surge_calculator.py

نفّذ التسعير الديناميكي بناءً على العرض والطلب.

  • احسب نسبة الطلب/العرض لمنطقة جغرافية (بادئة geohash)
  • اربط النسبة بمضاعف الارتفاع: النسبة < 1.0 → 1.0x، النسبة 1.0-2.0 → خطي 1.0x-2.0x، النسبة > 2.0 → محدود
  • طبّق حدود ارتفاع دنيا (1.0) وقصوى (3.0) قابلة للتكوين
  • تتبع عدد الطلبات والسائقين المتاحين لكل منطقة
  • وفّر طريقة لتناقص بيانات الطلب القديمة بمرور الوقت

FILE 6: rideshare/pricing/fare_calculator.py

احسب أجور الرحلات مع جميع مكونات التسعير.

  • الأجرة الأساسية + (المسافة_كم × معدل_لكل_كم) + (المدة_دقيقة × معدل_لكل_دقيقة)
  • طبّق مضاعف الارتفاع من حاسب الارتفاع
  • طبّق حد أدنى للأجرة (لا رحلة أرخص من الحد الأدنى)
  • ادعم بطاقات أسعار مختلفة لكل نوع مركبة (اقتصادي، مريح، فاخر)
  • أعد تفصيلاً يُظهر الأساس والمسافة والوقت والارتفاع والإجمالي

FILE 7: rideshare/tracking/ride_tracker.py

نفّذ دورة حياة الرحلة كآلة حالة.

  • الحالات: REQUESTED → MATCHED → DRIVER_EN_ROUTE → ARRIVED → IN_PROGRESS → COMPLETED أو CANCELLED
  • تحقق من صحة انتقالات الحالة (مثلاً، لا يمكن الانتقال من REQUESTED مباشرة إلى IN_PROGRESS)
  • تتبع الطوابع الزمنية لكل انتقال حالة
  • ادعم الإلغاء من حالات REQUESTED أو MATCHED أو DRIVER_EN_ROUTE أو ARRIVED
  • احسب مدة الرحلة ووقت الانتظار من الطوابع الزمنية

FILE 8: rideshare/main.py

اربط كل شيء معاً بمحاكاة.

  • ابذر سائقين نموذجيين في مواقع مختلفة
  • أنشئ طلبات رحلات من ركاب نموذجيين
  • شغّل خوارزمية المطابقة لربط الركاب بالسائقين
  • احسب التسعير الديناميكي والأجور
  • نفّذ دورة حياة الرحلة الكاملة من الطلب إلى الإكمال
  • اطبع ملخصاً لكل رحلة مع التوقيت وتفصيل الأجرة وتفاصيل السائق

تلميحات

  • أبجدية Base32 لـ geohash هي 0123456789bcdefghjkmnpqrstuvwxyz (32 حرف، بدون a، i، l، o)
  • صيغة Haversine: a = sin²(Δlat/2) + cos(lat1) × cos(lat2) × sin²(Δlng/2)، c = 2 × atan2(√a, √(1-a))، d = R × c حيث R = 6371 كم
  • لجيران geohash، كل خلية geohash لها بالضبط 8 جيران (N، NE، E، SE، S، SW، W، NW)
  • متوسط سرعة القيادة في المدينة: ~30 كم/ساعة (يُستخدم لوقت الوصول من المسافة)
  • التسعير الديناميكي لكل منطقة: استخدم بادئة geohash (مثلاً، دقة 4) كمعرّف المنطقة

معايير التقييم

تشفير/فك تشفير geohash مع تشابك البتات الصحيح: encode() تتناوب بين بتات خط الطول وخط العرض، تجمع كل 5 بتات في حرف Base32 من أبجدية geohash القياسية (0123456789bcdefghjkmnpqrstuvwxyz)، وتنتج تجزئات صحيحة لإحداثيات معروفة (مثلاً سان فرانسيسكو 37.7749/-122.4194 → تبدأ بـ '9q8y'). decode() تعكس العملية لإرجاع مركز خلية geohash. neighbors() تحسب بشكل صحيح جميع الخلايا الثمانية المجاورة بإزاحة خط العرض/الطول بحجم الخلية.15 نقاط
فهرس مكاني مع إدراج/إزالة/استعلام القريب باستخدام شبكة geohash: insert() تحسب geohash لموقع السائق، تخزن في قاموس مفتاح ببادئة geohash، وتتعامل مع إعادة الإدراج عند تغيير الموقع. remove() تنظف كلاً من الشبكة وقاموس السائقين. nearby() تبحث في الخلية المستهدفة وجميع الجيران الثمانية، تحسب مسافة Haversine الفعلية لكل مرشح، تصفي بنصف القطر واختيارياً بنوع المركبة، وتعيد النتائج مرتبة تصاعدياً بالمسافة.15 نقاط
خوارزمية المطابقة تجد السائق الأمثل بالمسافة + التقييم + وقت الوصول: find_match() تستعلم الفهرس المكاني عن السائقين القريبين المتاحين من نوع المركبة المطلوب، تسجل كلاً منهم بمزيج مرجّح (المسافة 40%، وقت الوصول 30%، التقييم 30%) مع تطبيع صحيح (المسافة نسبة لأقصى مسافة التقاط، وقت الوصول نسبة لحد 30 دقيقة، التقييم نسبة لـ 5.0)، وتعيد السائق الأعلى تسجيلاً. find_top_matches() تعيد أفضل N مرشحين مرتبين تنازلياً بالنتيجة.15 نقاط
حاسب وقت الوصول مع Haversine وتعديل حركة المرور: haversine() تنفذ صيغة Haversine بشكل صحيح بتحويل الدرجات إلى راديان وإرجاع المسافة بالكيلومتر. calculate() تضرب مسافة الخط المستقيم بعامل الطريق (1.4)، تحول للوقت باستخدام avg_speed_kmh (30)، وتطبق traffic_multiplier بناءً على hour_of_day. get_traffic_multiplier() تعيد 1.5 لساعات الذروة (7-9، 17-19)، 1.0 لمنتصف النهار (10-16)، و0.8 لليل (20-6).10 نقاط
تسعير ديناميكي بنسبة الطلب/العرض وحدود قابلة للتكوين: record_request() تزيد عداد الطلب للمنطقة. update_supply() تعيّن عدد السائقين. get_surge() تحسب نسبة الطلب/العرض، تربطها بمضاعف (النسبة < 1 → 1.0، خطي بين 1-2، محدود بأقصى ارتفاع للنسب الأعلى)، وتتعامل مع الحالات الحدية (عرض صفري مع طلب → أقصى ارتفاع، نشاط صفري → بدون ارتفاع). decay_demand() تقلل جميع عدادات الطلب بعامل تناقص لمنع البيانات القديمة.10 نقاط
حاسب الأجرة يجمع الأساس + المسافة + الوقت × الارتفاع: calculate() تبحث عن RateCard الصحيحة لنوع المركبة، تحسب رسوم المسافة (كم × معدل_لكل_كم) ورسوم الوقت (دقيقة × معدل_لكل_دقيقة)، تضيف الأجرة الأساسية للمجموع الفرعي، تطبق surge_multiplier للحصول على مبلغ الارتفاع، تطبق حد أدنى للأجرة، وتعيد FareBreakdown كامل. أنواع المركبات المختلفة (اقتصادي، مريح، فاخر) تنتج مجاميع مختلفة من بطاقات الأسعار المميزة.10 نقاط
متتبع الرحلات مع آلة حالة كاملة وإدارة دورة الحياة: create_ride() تهيئ في حالة REQUESTED مع طابع زمني. transition() تتحقق من VALID_TRANSITIONS (ترفض الانتقالات غير الصالحة مثل REQUESTED → IN_PROGRESS بـ ValueError)، تسجل StateTransition مع طابع زمني وبيانات وصفية، تُحدّث الحالة الحالية. cancel_ride() تتعامل مع الإلغاء من أي حالة قابلة للإلغاء. get_wait_time() تحسب مدة REQUESTED→IN_PROGRESS. get_ride_duration() تحسب مدة IN_PROGRESS→COMPLETED. جميع الطوابع الزمنية مسجلة لكل تغيير حالة.15 نقاط
المحاكاة الرئيسية تعرض تدفق الرحلة الكامل: run_simulation() تهيئ جميع المكونات الستة (SpatialIndex، ETACalculator، RideMatcher، SurgeCalculator، FareCalculator، RideTracker)، تبذر سائقين نموذجيين، تعالج طلبات الرحلات عبر دورة الحياة الكاملة (REQUESTED → MATCHED → DRIVER_EN_ROUTE → ARRIVED → IN_PROGRESS → COMPLETED)، تحسب الأجور المعدّلة بالارتفاع، وتطبع ملخصاً يُظهر تعيين السائق ووقت الوصول وتفصيل الأجرة وتوقيت الرحلة لكل طلب.10 نقاط

قائمة التحقق

0/8

حلك

محاولات مجانية غير محدودة
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.