لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 11/09/17 في كل الموقع
-
الإصدار 1.0.0
47189 تنزيل
يضع هذا الكتاب المُوجز القارئ على أعتاب عالم تصميم تجربة المُستخدمين UX، وهو علم له قواعده وأصوله وأدواته، ويهدف إلى تعريف القارئ المُبتدئ بأساس هذا العلم وكيف يُطبّق على المُنتجات الرّقمية من مواقع ويب خدميّة وتطبيقات على الأجهزة الذّكية وصولًا إلى التّصميم الأمثل الّذي يُوفِّق بين هدف المُستخدم أوّلًا وهدف الخدمة التّجاريّ، الأمر الّذي يعني منتجًا ناجحًا. يبدأ الكتاب بشرح مفاهيم عامة عن تجربة المستخدم ليواصِل مع شرح كيفية إجراء مختلف الدراسات التي يحتاج المصمِّم للقيام بها، ومتطلباتها، ثم الأمور الواجب أخذها بالحسبان عند التصميم لضمان تجربة استخدام مريحة وممتازة، ليختتم في النهاية بالإشارة إلى أهمية الإحصائيات وضرورة الاعتماد عليها، حيث خُصّصت عدة أقسام لهذه النقطة، لتشير إلى مدى أهمية اعتماد بيانات وإحصائيات المستخدمين مثل أساس للتصميم، وكذا أبرز الإحصائيات الممكن التحصل عليها من خلال عدة اختبارات. يمكنك قراءة فصول هذا الكتاب مباشرةً على شكل مقالات، وإليك العناوين: مدخل إلى تجربة المستخدم User Experience فهم ودراسة المستخدمين في مجال تجربة المستخدم دراسة الشريحة المستهدفة في مجال تجربة المستخدم كيفية التصميم للأجهزة المختلفة هندسة المعلومات في تجربة المستخدم تعرف على أنماط التصميم في مجال تجربة المستخدم أشياء لا يمكن اعتبارها رسوما تخطيطية (Wireframes) في مجال تجربة المستخدم تعرف على الرسوم التخطيطية (Wireframes) في مجال تجربة المستخدم مفهوم الثقل المرئي (Visual Weight) والألوان في مجال تجربة المستخدم التكرار ومخالفة الأنماط في مجال تجربة المستخدم المحاذاة والقرب في مجال تجربة المستخدم تعرف على أساليب مسح الواجهة والتراتب المرئي في مجال تجربة المستخدم أساليب الإطلاع في مجال تجربة المستخدم: التصفح، البحث والاكتشاف تصميم هيكل صفحة الويب والعناصر الأساسية في مجال تجربة المستخدم الأزرار، النماذج والدعوات إلى الإجراء في مجال تجربة المستخدم استخدام علم النفس في مجال تجربة المستخدم لتكييف المستخدم وإقناعه كيف تغير الخبرة من تجربة المستخدم؟ تصميم تجربة المستخدم من خلال بيانات وإحصائيات المستخدمين تعرف على أنواع المخططات الإحصائية في مجال تجربة المستخدم اختبارات أ/ب (A/B Test) في مجال تجربة المستخدم1 نقطة -
مقدمة تُعتبر المصفوفة في الجافا سكريبت كائن عمومي (global) الغرض منه هو تخزين البيانات، وتحتوي المصفوفة إما على مجموعة من العناصر بنوع بيانات واحد أو أكثر، وقد تكون فارغة. نستخدم الفهارس العددية التي تبدأ من القيمة 0 للوصول إلى عناصر المصفوفة. المصفوفات مفيدة جدًا بما أنها تُخزن عدة قيم في متغير واحد، وهذا الأمر يقلل وينظم الشيفرة البرمجية التي نكتبها ويجعلها أكثر ملائمة للقراءة والصيانة. تستطيع المصفوفة أن تحتوي على أي نوع بيانات، ابتداءً من الأرقام ومرورا بالنصوص والكائنات وغيرها من أنواع البيانات. لتوضيح كيف من الممكن أن تكون المصفوفات مهمة، لنفترض أننا نريد أن نحفظ أسماء المحيطات في متغيرات عدة، بحيث يكون لكل محيط المتغير الخاص به: oceans.js // Assign the five oceans to five variables const ocean1 = "Pacific"; const ocean2 = "Atlantic"; const ocean3 = "Indian"; const ocean4 = "Arctic"; const ocean5 = "Antarctic"; هذه الطريقة مُضجرة جدا، وتُصبح أكثر صعوبة بشكل متسارع في المتابعة والصيانة. باستخدام المصفوفات، نستطيع تبسيط الأمر. oceans.js // Assign the five oceans let oceans = [ "Pacific", "Atlantic", "Indian", "Arctic", "Antarctic", ]; بدلًا من استخدام خمسة متغيرات منفصلة، نستطيع الان أن يكون لدينا متغير واحد يحتوي على جميع العناصر الخمسة. لإنشاء المصفوفة، نستخدم الأقواس المربعة [ ] كما هو واضح في الشيفرة البرمجية السابقة، وللوصول إلى عنصر معين في المصفوفة، نستخدم الفهرس مع المصفوفة بالطريقة التالية: // Print out the first item of the oceans array oceans[0]; Output Pacific في هذا الدرس سنتعلم كيفية بناء المصفوفة، وكيفية الوصول إلى عناصرها، والاضافة إليها وتعديلها والحذف منها، كما سنتعلم كيفية المرور خلال عناصرها باستخدام حلقة التكرار. إنشاء مصفوفة يوجد طريقتان لإنشاء المصفوفة في جافا سكريبت: التعريف اللفظي باستخدام الأقواس المعكوفة. التعريف بواسطة الباني (constructor) باستخدام كلمة new. لنوضح كيفية إنشاء مصفوفة تحتوي على أنواع سمك القرش، وذلك باستخدام التعريف اللفظي بواسطة الأقواس المربعة: sharks.js // Initialize array of shark species with array literal let sharks = [ "Hammerhead", "Great White", "Tiger", ]; الان نُعرف نفس المصفوفة باستخدام الباني وذلك بواسطة الجملة new Array() : sharks.js // Initialize array of shark species with array constructor let sharks = new Array( "Hammerhead", "Great White", "Tiger", ); كلا الطريقتين سوف يُنشئ لنا المصفوفة، ولكن طريقة التعريف اللفظي هي المشهورة والأكثر تفضيلا بما أن التعريف باستخدام الباني قد يؤدي إلى نتائج غير مستقرة وغير متوقعة وعليك الانتباه في حال صادفتك تلك الطريقة في التعريف أو في حال استخدامك لها. نستطيع طباعة محتويات المصفوفة بكتابة المتغير الخاص بها مباشرة: // Print out the entire sharks array sharks; Output [ 'Hammerhead', 'Great White', 'Tiger' ] تُستخدم المصفوفات عادة في تجميع العناصر أو القوائم من نفس نوع البيانات، ولكن من الناحية التقنية، فإن المصفوفات تستطيع أن تحتوي على عناصر من أنواع مختلفة بالإضافة إلى إمكانية أن تحتوي على مصفوفات أخرى: // Initialize array of mixed datatypes let mixedData = [ "String", null, 7, [ "another", "array", ], ]; بعد أن تعلمنا كيفية إنشاء المصفوفة، نستطيع الان التعامل معا بأكثر من طريقة، ولكننا في البداية نحتاج الى فهم كيفية فهرسة المصفوفات (Arrays Indexing). ملاحظة: قد تجد اخر عنصر في المصفوفة ينتهي بفاصلة وأحيانا قد لا تجد هذه الفاصلة. تُعرف هذه الفاصلة بالفاصلة التابعة (Trailing comma)، ومن الشائع ان تكون غير موجودة، ولكن بشكل عام أصبح من الأفضل أن يتم استخدامها في الشيفرة البرمجية بسبب أنها تجعل الاختلافات بين الإصدارات (في عملية إدارة الإصدارات Versions Control) أكثر وضوحا وتسهل من إضافة وإزالة عناصر المصفوفة دون أخطاء. لاحظ أن الفاصلة التابعة غير مسموح بها في ملفات JSON. فهرسة المصفوفات إذا تعاملت مسبقاً مع النصوص والفهرسة في الجافا سكريبت، ستكون مُلمًا بمفهوم فهرسة المصفوفات، حيث أن النص يُعتبر شبيهًا بالمصفوفة. لا تحتوي المصفوفات على عناصر مزدوجة على شكل اسم/قيمة، وبدلا من ذلك، فإن المصفوفات تُفهرس بقيم عددية تبدأ من القيمة 0. المثال التالي ينشئ مصفوفة باسم seaCreatures: seacreatures.js let seaCreatures = [ "octopus", "squid", "shark", "seahorse", "starfish", ]; الجدول التالي يُفصل كيف يتم فهرسة كل عنصر في المصفوفة بقيمة عددية ابتداءً من 0: octopus squid shark seahorse starfish 0 1 2 3 4 العنصر الأول في المصفوفة هو octopus ومُفهرس في الموقع 0 من المصفوفة، والعنصر الأخير هو starfish ومُفهرس في الموقع 4. تبدأ الفهرسة من 0، وهذا يتضارب مع طبيعتنا الفطرية ببدء العد من القيمة 1، لذلك نحتاج لأخذ الاحتياط وأن نتذكر هذه النقطة دائما حتى تصبح طبيعية. نستطيع أن نحصل على عدد العناصر في المصفوفة باستخدام الخاصية length: seaCreatures.length; Output 5 على الرغم من أن الفهارس الخاصة بالمصفوفة seaCreatuers تبدأ من 0 إلى 4، فإن الخاصية length سوف تُرجع العدد الفعلي للعناصر الموجودة في المصفوفة. إذا أردنا معرفة رقم الفهرس لعنصر معين في المصفوفة، وليكن مثلا seahorse، نستطيع أن نستخدم لذلك الوظيفة indexOf() : seaCreatures.indexOf("seahorse"); Output 3 إذا لم تحتوي المصفوفة على العنصر الذي نريده، فلن نحصل على رقم فهرس لعنصر غير موجود، وفي هذه الحالة، فإن الوظيفة سترجع لنا القيمة -1 كما في المثال التالي: seaCreatures.indexOf("cuttlefish"); Output -1 بواسطة أرقام الفهارس المرتبطة بعناصر المصفوفة، فإنه لدينا القدرة على الوصول لكل عنصر بشكل منفرد بهدف العمل على هذا العنصر والتعامل معه. الوصول لعناصر المصفوفة يتم الوصول لعنصر في مصفوفة جافا سكريبت بواسطة الإشارة لرقم الفهرس للعنصر بين قوسين معكوفين: seaCreatures[1]; Output squid نعلم أن الرقم 0 سيعيد لنا دائما العنصر الأول في المصفوفة. كذلك نستطيع إيجاد العنصر الأخير في المصفوفة بواسطة إجراء عملية طرح قيمة 1 من قيمة الخاصية length للمصفوفة، والإشارة لناتج هذه العملية كرقم فهرس للعنصر الأخير كما هو موضح في المثال التالي: const lastIndex = seaCreatures.length - 1; seaCreatures[lastIndex]; Output starfish محاولة الوصول لعنصر غير موجود سيعيد لنا undefined: seaCreatures[10]; Output undefined للوصول لعنصر مصفوفة متداخلة (مصفوفة داخل مصفوفة)، فعلينا إضافة فهرس اخر يعود للمصفوفة الداخلية: let nestedArray = [ [ "salmon", "halibut", ], [ "coral", "reef", ] ]; nestedArray[1][0]; Output coral في المثال السابق، قمنا بالوصول للعنصر coral بالإشارة لرقم الفهرس الذي يحتوي المصفوفة الداخلية وهو 1، ثم أشرنا للفهرس الذي يحتوي على العنصر في المصفوفة الداخلية وهو 0. إضافة عنصر لمصفوفة في المتغير seaCreatuers يوجد لدينا 5 عناصر بأرقام فهراس تبدأ من 0 الى 4. إذا أردنا أن نُضيف عنصر جديد لهذه المصفوفة، فيمكننا أن نقوم بذلك بإعطاء قيمة للفهرس التالي الذي يلي اخر فهرس: seaCreatures[5] = "whale"; seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale' ] إذا قمنا بإضافة عنصر وتجاهلنا قيمة الفهرس التالي ووضعنا بدلا منه فهرس بقيمة 7 مثلا، فإن ذلك يؤدي لإضافة عنصر غير مُعرف (undefined) للمصفوفة كما في المثال التالي: seaCreatures[7] = "pufferfish"; seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', , 'pufferfish' ] هذه المشكلة نستطيع تجنبها باستخدام الوظيفة push() والتي تقوم بإضافة العنصر الجديد في نهاية المصفوفة: // Append lobster to the end of the seaCreatures array seaCreatures.push("lobster"); seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', , 'whale', 'pufferfish', 'lobster' ] على العكس تماما من الوظيفة push()، فإن الوظيفة unshift() تقوم بإضافة العنصر في بداية المصفوفة: // Append dragonfish to the beginning of the seaCreatures array seaCreatures.unshift("dragonfish"); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', , 'pufferfish', 'lobster' ] باستخدام الوظيفتين السابقتين، ستكون لديك المقدرة على إضافة عناصر جديدة للمصفوفة إما في بدايتها، أو نهايتها. إزالة عنصر من مصفوفة لإزالة عنصر معين من مصفوفة، نستخدم الوظيفة splice(). في المصفوفة seaCreatuers قمنا بإضافة عنصر غير مُعرف وليس له قيمة، ولإزالته نقوم بالتالي: seaCreatures.splice(7, 1); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish', 'lobster' ] في الوظيفة splice()، المُعامل الأول يشير لرقم الفهرس الذي سنبدأ بالإزالة من عنده (في هذه الحالة 7)، والمُعامل الثاني يشير لعدد العناصر التي نرغب بإزالتها (في حالتنا سيكون 1 حيث أننا نرغب بإزالة عنصر واحد). الوظيفة splice() ستؤثر على المتغير الأصلي. لذلك، إذا أردنا أن نحافظ على المصفوفة الأصلية دون تغيير، نستخدم الوظيفة slice() ونعطي القيمة الناتجة عنها لمتغير جديد. let newArray = slice(7, 1); الوظيفة pop() ستزيل العنصر الأخير من المصفوفة: // Remove the last item from the seaCreatures array seaCreatures.pop(); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] العنصر lobster أُزيل من المصفوفة لأنه العنصر الأخير، ولإزالة العنصر الأول في المصفوفة، نستخدم الوظيفة shift(): // Remove the first item from the seaCreatures array seaCreatures.shift(); seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] باستخدام الوظيفتين pop() و shift() نستطيع إزالة العناصر من بداية المصفوفة أو نهايتها. يُفضل استخدام الوظيفة pop() قدر الإمكان، حيث أن باقي العناصر في المصفوفة تبقى في مواقعها دون تغيير. تعديل العناصر في المصفوفة نستطيع تغيير أي قيمة عنصر في المصفوفة وذلك بإعطاء القيمة الجديدة للعنصر باستخدام عملية المساواة، كما نفعل تماما عند التعامل مع المتغيرات العادية: // Assign manatee to the first item in the seaCreatures array seaCreatures[0] = "manatee"; seaCreatures; Output [ 'manatee', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] طريقة أخرى لتغيير قيمة العنصر باستخدام الوظيفة splice() وذلك بإضافة مُعامل جديد. فمثلا، إذا أردنا تغيير قيمة العنصر seahorse والذي يقع في الفهرس 3، نستطيع إزالته وإضافة قيمة جديدة بدلا منه: // Replace seahorse with sea lion using splice method seaCreatures.splice(3, 1, "sea lion"); seaCreatures(); Output [ 'manatee', 'squid', 'shark', 'sea lion', 'starfish', 'whale', 'pufferfish' ] في المثال السابق، قمنا بإزالة العنصر seahorse من المصفوفة، ووضعنا بدلا منه القيمة sea lion في نفس الفهرس 3. حلقة التكرار خلال المصفوفة نستطيع المرور على عناصر المصفوفة من خلال حلقة تكرار for وذلك بالاستفادة من خاصية length. في المثال التالي، نُنشئ مصفوفة باسم shellfish ونطبع رقم كل فهرس فيها بالإضافة إلى قيمة العنصر المرتبط بالفهرس: // Create an array of shellfish species let shellfish = [ "oyster", "shrimp", "clam", "mussel", ]; // Loop through the length of the array for (let i = 0; i < shellfish.length; i++) { console.log(i, shellfish[i]); } Output 0 'oyster' 1 'shrimp' 2 'clam' 3 'mussel' نستطيع أيضا استخدام حلقة التكرار for…of وهي خاصية جديدة في الجافا سكريبت: // Create an array of aquatic mammals let mammals = [ "dolphin", "whale", "manatee", ]; // Loop through each mammal for (let mammal of mammals) { console.log(mammal); } Output dolphin whale manatee حلقة التكرار for…of لا تقوم باستخدام رقم الفهرس للعناصر في المصفوفة، ولكنها بشكل عام طريقة أبسط وأكثر اختصارا للمرور على المصفوفة من خلال حلقة التكرار. استخدام حلقات التكرار مفيد بشكل كبير في طباعة قيم عناصر المصفوفة وهو يشبه عرض العناصر من قاعدة بيانات خلال موقع الكتروني. خاتمة تُعتبر المصفوفات جزء أساسي ومهم في برمجة الجافا سكريبت. في هذا الدرس تعلمنا كيفية إنشاء المصفوفة، وكيفية فهرستها، وتعلمنا إجراء بعض العمليات المهمة على المصفوفات مثل إزالة العناصر والتعديل عليها. وكذلك تعلمنا طريقتين للمرور على عناصر المصفوفة من خلال حلقات التكرار والتي تهدف لإجراء عمليات على عناصر المصفوفة مثل طباعة محتوياتها وطباعة أرقام الفهارس. ترجمة -وبتصرّف- للمقال Understanding Arrays in JavaScript لصاحبه Tania Rascia حقوق الصورة البارزة محفوظة لـ Freepik1 نقطة
-
إن التاجر الذي يبيع بضاعته في متجر عادي يعلم أنه ربحه محدود بالسوق المحلّي وبمن يستطيع الحضور إلى متجره دون كثير مشقّة أو تعب، وحين يريد عرض منتجاته في سوق جديد فإنه يذهب بنفسه وبضاعته إلى ذلك السوق -كما كان يحدث قديمًا في رحلات التجارة- أو يفتتح أفرعًا جديدة له في ذلك السوق الذي يريد التوسع فيه، وهذا ما يحدث إلى الآن في كثير من الشركات والمتاجر. لكن مع بداية الألفية الجديدة فقد خرجت علينا أنظمة وبرامج رقمية تتيح ﻷصحاب المتاجر وضع منتجاتهم على الإنترنت في هيئة متاجر افتراضية على الإنترنت، وبهذا تتوسع تجارتك إلى كل شخص لديه اتصال بالإنترنت، وليس محيطك المحلّي فقط، وبدون الدخول في تفاصيل وتعقيدات إقامة أفرع حقيقية في الدول التي سمحت لها بالدخول إلى متجرك الإلكتروني. وسنتعرف في هذا المقال على أشهر تلك البرامج والأنظمة وأهم الخصائص التي تميِّز كلًّا منها، ومتى يكون استخدام أحدها مناسبًا لك عما سواه. برامج وأنظمة إدارة المتاجر الرقمية إن المتاجر الرقمية التي سأتحدث عنها في هذا المقال من أمثلة Shopify وWooCommerce تعطيك ملكية متجرك في مقابل مبلغ مالي تدفعه لقاء استخدام خدماتها، سواء مرة واحدة أو بشكل شهري أو غير ذلك من طرق الدفع أو حتى بشكل مجاني أحيانًا، لكنك تكون المسؤول عن التسويق لمتجرك بنفسك، على خلاف مواقع مثل eBay أو Amazon التي لا تملك متجرًا فيها لنفسك، وإنما تدفع نسبة من أرباحك مقابل التسويق لك ومقابل سماحهم لك بعرض منتجاتك على الجمهور الذي يشتري منهم، لكنك لا تأمن أن يأتي يوم ويٌحظَر حسابك بسبب تقييمات من العملاء رغم ذلك. وتتنوع حالات استخدام تلك المتاجر من الشركات التي تبيع منتجات رقمية وتريد متاجر على مواقعها لأن أغلب عمليات الشراء لتلك المنتجات تتم على الإنترنت، إلى مواقع التسوّق وتجار التجزئة الذين يبيعون منتجاتهم –الرقمية أو الحقيقية- عبر الإنترنت لزيادة عمليات الشراء من خارج السوق المحلّي. وتتيح تلك البرامج والمنصّات لزائري المتجر -زبائنك في هذه الحالة- أن يختاروا المنتجات التي يريدونها، ويقارنوا بينها، ويقيِّموها ويضيفوها إلى سلّات التسوق الخاصة بهم، ثم تحسب لهم حاسبة في صفحة الدفع التكاليف النهائية بعد الضرائب والشحن وأي تكاليف أخرى. وسننظر الآن في بعض أشهر تلك الأنظمة كي نتعرف على مزاياها ومدى مناسبتها لتجارتك. Shopify تقدم منصة Shopify نظامًا سهلًا لإطلاق المتاجر الإلكترونية وإدارتها كي تبدأ مشروعك في أسرع وقت ممكن، فما عليك إﻻ تسجيل حساب جديد وإضافة المنتجات وأسعارها كي تبدأ البيع، ثم تضيف قليلًا من التخصيص لمتجرك كي يتوافق مع علامتك التجارية، كأن تغير من شكل ولون قالب التصميم الذي اخترته أثناء تسجيل حسابك، أو تختار قالبًا جديدًا من تشكيلة جاهزة من متجر Shopify، شيء يشبه قوالب ووردبريس تمامًا. كما يمكنك إضافة نطاقك الخاص ليكون عنوان المتجر، فبدلًا من العنوان الافتراضي الذي اخترناه لهذا الشرح (https://hsacadmy.myShopify.com)، فإن متجرك يجب أن يكون ممثلًا لعلامتك التجارية. ولا تقلق إن كنت ﻻ تدري كيف تخصص متجرك ولا ما الأمور التي يجب أن تنتبه إليها، فإن واجهة Shopify سهلة التصميم وتقودك مباشرة إلى إتمام الأجزاء الناقصة في حسابك أو متجرك خطوة بخطوة. مزايا Shopify دعم مباشر من اللحظة الأولى لاستخدامك، عبر واجهة المنصّة والرسائل البريدية. تخصيص الرسائل والفواتير بهويتك التجارية. تحليلات وتقارير لمتجرك عن سلوك عملائك مع المتجر والمنتجات المختلفة. إعادة المال للعميل في حالة إرجاع السلعة. مدونة لمتجرك. شهادة SSL مجانية. دعم لأكثر من منصة (ماك، ويندوز، أندرويد .. ). وجود متجر تطبيقات لإضافة أدوات تزيد من كفاءة متجرك. عيوب Shopify ثمن اشتراك الباقات مناسب لما تقدّمه، لكن قد تزيد التكلفة إن أردت إضافة بعض التطبيقات من متجر Shopify. توجيه العميل إلى صفحة دفع خاصة بـShopify عوضًا عن نطاقك الخاص. أبلغ بعض العملاء عن أوقات تعطلت فيها خوادم Shopify في ذروة مواسم الشراء. وتقدم Shopify ثلاث باقات لعملائها يختارون أيها تبعًا لحجم تجارتهم وما يحتاجون إليه، نستعرضها فيما يلي: Shopify Lite تناسب هذه الباقة أصحاب الأعمال الصغيرة الذين يرغبون في البيع على فيس بوك مثلًا ولديهم موقع قائم بالفعل يبيعون منه عبر إضافة أزرار للشراء، إذ أنها لا تعطيك متجرًا رقميًا كاملًا، بل الأدوات الأساسية التي تمكّن الناس من شراء ما تبيعه إضافة إلى طريقة لتحصيل ذلك المال في مقابل زهيد لا يتجاوز 9$، وقد أضيفت خاصية التحدث مع العملاء عبر برنامج ماسنجر في فيس بوك مؤخرًا إلى هذه الخطة، من أجل تواصل أسرع مع عملائك. ويجب أن تعلم أن هذه الباقة تتطلب أكثر من مجرد شراء استضافة، فهي موجّهة إلى من يريد إضافة إمكانية الشراء إلى كيان موجود بالفعل مثل مدونة أو موقع، لهذا تحتاج إلى موقع واستضافة ونطاق قبل دفع مالك في Shopify. Basic Shopify اشتراك هذه الباقة يقارب 30$، وهي مناسبة حين يزداد العمل في تجارتك الصغيرة وتبدأ في توظيف غيرك أو حين تبدأ تجارة مع واحد أو اثنين غيرك، إذ أنها تتيح لك إضافة حسابين غيرك لاثنين من العاملين معك، ولا تحدّك بعدد معين للمنتجات التي تبيعها أو حجم الملفات التي تتعامل معها. كما تقدم لك مزايا مثل شهادة SSL المجانية إضافة إلى موقع ومدونة، وأكواد للخصومات، ودعم على مدار الساعة، والإنشاء اليدوي للطلبات. Shopify تزيد تلك الباقة عن سابقتها في أنها ترفع عدد حسابات الموظفين إلى خمسة حسابات، وتقدم لك مزايا مثل بطاقات الهدايا واستعادة سلات الشراء والتقارير الاحترافية، في مقابل زيادة اشتراكك إلى نحو 80$. Advanced Shopify ترفع هذه الباقة عدد حسابات الموظفين التي يمكنك إنشاءها إلى 15 حسابًا، وتقدم لك أفضل خصم على تكاليف الشحن من بين الباقات الثلاث، وعرض تكاليف الشحن من الطرف الثالث مثل FedEx وغيرها، وصياغة التقارير المتقدمة، وذلك في مقابل زيادة اشتراكك إلى نحو 300$. خدمة نقاط البيع ولا تتوقف خدمات Shopify على التجارة الرقمية، فتستطيع شراء بعض العتاد لمتجرك الحقيقي مثل قارئات البطاقات البنكية وماكينات تحصيل الأموال التي يمكنك استخدامها بتوصيلها بهاتفك الذكي أو حاسوبك اللوحي، وقارئات barcode، وطابعات فواتير وغير ذلك، كي تبيع منتجاتك في متجرك الحقيقي أو في أي مكان تريد. 3dCart تعتمد 3dCart أسلوب تقديم البرنامج نفسه كخدمة (SaaS: Software as a Service) مثل Shopify، فهي تريحك من الأمور التقنية لمتجرك مثل الاستضافة وتحديث برمجيات الخوادم أو إدراة تلك الخوادم، ما يعني أنك لا تحتاج إلى توظيف مطور ويب في الغالب. وهي تقدم ثلاث باقات يُدفع اشتراكها بشكل شهري تبدأ من 30$، وذلك يجعلها مناسبة للأعمال الصغيرة والكبيرة على السواء، وحتى الباقة الأساسية منها تتضمن البيع في فيس بوك ومنتجات وسعة تخزين غير محدودتين، ومدونة جاهزة ومراجعات للمنتجات وحاسبات ضرائب، كما أنها تتكامل مع أمازون وeBay أيضًا، فهذا يجعلك تبدأ متجرك الرقمي الصغير بمزايا كثيرة كنت تظن أنك ستدفع الكثير من المال لقاءها. ملخص باقات 3dCart باقة Basic لقاء نحو 30$ شهريًا، تعطيك المزايا الأساسية إضافة إلى حسابين للموظفين. باقة Plus لقاء نحو 80$، تعطيك مزايا جديدة مثل التسويق بالبريد الإلكتروني وتقديم العروض الخاصة وحافظات لسلات الشراء، إضافة إلى خمس حسابات للموظفين. باقة Pro لقاء 230$، للشركات التي بدأت في التوسع والنمو، فتعطيك مزايا مثل حملات البريد ذات الردود الآلية، الشحن الآلي للمنتجات (في حالة شراء العميل للمنتج مرة بعد مرة، فيختار إرسال المنتج له بشكل آلي على الفترات الزمنية التي يرغب بها)، إضافة إلى مزايا جديدة تعِدُ 3dCart بقدومها إلى هذه الباقة قريبًا، مثل الطلبات المسبقة وإعلانات فيس بوك الديناميكية. تعطيك هذه الباقة 15 حسابًا للموظفين. مزايا 3dCart بيع منتجات رقمية وحقيقية. إمكانية إنشاء خصومات وهدايا. إنشاء قوائم انتظار للمنتجات التي يكثر الطلب عليها حتى تتوفر من جديد في المخزن. حاسبات شحن وضرائب. حصولك على مدونة لمتجرك. أدوات استيراد وتصدير من أجل إجراء تعديلات بالجملة أو نقل قواعد بياناتك. إمكانية البيع عبر نقاط البيع POS (مثل Shopify). قوالب بريدية كي تستخدمها في التسويق بالبريد الإلكتروني. مزامنة مخزنك مع قنوات بيعك في أمازون وeBay كي تدير متاجرك من مكان واحد. وإعداد متجر 3dCart لا يحتاج إلى خبرة برمجية، فهو مثل Shopify يقودك عبر خطوات بسيطة لإعداد متجرك، وإن كان يختلف عن Shopify في تصميم تلك الخطوات قليلًا حيث يضعهم لك بالترتيب في اللوحة الرئيسية. ويتابعك برسائل محادثات آلية مع ممثلي خدمة العملاء في كل قسم تدخله لأول مرة، وتستطيع الرد على تلك المحادثات إن شئت، وسيرد عليك أحد ممثلي خدمة العملاء الموجودين في أقرب فرصة (قد تصل إلى خمس ساعات حسب قولهم، لكنهم لم يردوا في أحد المرات التي راسلتهم فيها إلا بعد نحو اثني عشر ساعة تقريبًا). ولأنها قريبة من Shopify في نموذج عملها، فستجد هنا أيضًا متجر تطبيقات ملحقًا بها، تضيف منه تطبيقات تساعدك في التسويق بالبريد أو حساب الضرائب أو أنظمة الحسابات. عيوب 3dCart تدور أغلب المشاكل التي رأيتها في 3dCart حول خدمة العملاء السيئة، لكن تلك التقييمات والمشاكل تعود إلى أكثر من عام مضى (منذ 2016)، لذا فقد تكون تلك الخدمة قد تحسنت منذ ذلك الوقت، خاصة أني رأيت ردودًا لمؤسس 3dCart على كثير من تلك التقييمات التي مر عليها أكثر من عام أو عامين وهو يؤكد تجديدهم الكامل والجذري لقسم خدمة العملاء. وهكذا ترى أن 3dCart مناسبة أيضًا لجميع أحجام الشركات التي ترغب بوجود متاجر رقمية لها، والتي ليس لديها خلفية تقنية ولا تريد التفكير في أعباء الخوادم والاستضافات وغير ذلك، وإنما تود التركيز على البيع والشراء وزيادة أرباحها. Magento تأتي ماجنتو مع إصدار مجاني مفتوح المصدر يمكنك البدء باستخدامه مجانًا، لكن لا تتوقع نفس الدعم الذي تحصل عليه مع الإصدارات المدفوعة، وإنما عليك الاعتماد على البحث في مجتمعات المطورين المهتمين بماجنتو في الويب، أو في التوثيق الخاص بها أو دليل الاستخدام. وتثبيت هذه النسخة المجانية من ماجنتو يتطلب خلفية تقنية أو على الأقل معرفة بالتعامل مع سطر الأوامر وإدارة الخوادم، ويمكنك الاطلاع على هذه المقالة لمعرفة تفاصيل أكثر عن Magento، وعلى هذه لبيان كيفية تثبيتها على نظام تشغيل أوبنتو. مزايا Magento قابلية التخصيص العالية. سهولة زيادة حجم المتجر. إنشاء مجموعات مستخدمين من أجل التسويق الموجّه. عرض المنتجات المعروضة مؤخرًا ومقارنة المنتجات. عرض المنتجات المرتبطة لزيادة حجم التسوّق. حفظ سلة الشراء حتى بعد مغادرة الموقع. كتابة بيانات وصفية للمنتجات (meta data). إدارة عدة مواقع من مكان واحد. استيراد بيانات أو تصديرها بالجملة من خلال ملفات csv. ربط تحليلات جوجل بالمتجر. عيوب Magento فقر الدعم الفني، بما أن الخدمة مجانية، فستضطر إلى البحث بنفسك في جوجل ومنتديات الدعم عن حل مشاكلك. صعوبة التعود عليها، بما أنها تحتاج إلى خبرة برمجية. تقودك إلى إنفاق أموال كثيرة فيما بعد رغم توفير إصدار مجاني للتحميل، إذ أنك مسؤول عن حماية خوادمك بنفسك، وعن ضبط وإعداد المتجر، بل وشراء قوالب له أيضًا، ومن ثمّ توظيف مطور خبير بهيكلة ماجنتو كي يتعامل مع الطرف الخلفي للمتجر (الخوادم التي تستضيف متجرك). يقول بريت ويليامز -مؤلف أربعة كتب حول ماجنتو-: من يستخدم النسخة المجانية من ماجنتو فلا يتوقع أن يحصل على أي دعم تقني، إذ أنك تحصل على مقابل ما تدفعه. كما أن ماجنتو ليست بالخيار الرخيص، وستحتاج إلى توظيف مطوِّر ويب معتمد من ماجنتو، كما يجب أن تكون مستعدًا لإنفاق قرابة 10.000$ على الأقل في البداية ثم 200$ شهريًا للاستضافة. لذا يمكننا القول أن ماجنتو مناسبة للشركات المتوسطة إلى كبيرة الحجم، والتي لديها ميزانية تسمح بالإنفاق على تشغيل وصيانة الخوادم التي ستحمل متاجرها الرقمية. وهذا يقودنا إلى ذكر أنها ليست من فئة البرمجيات الخدمية Saas، وإنما تدفع أنت مقابل حق استخدامها، أي ثمن رخصتها، في مقابل البرمجيات الخدمية التي تدفع لها اشتراكًا شهريًا مقابل اهتمامهم بالجانب التقني كي تركّز أنت على تجارتك. OpenCart تصنّف منصة OpenCart أيضًا ضمن البرمجيات مفتوحة المصدر والتي توفّر نسخة مجانية للتحميل كسابقتها ماجنتو، وهي تشبهها أيضًا في ضرورة توفّر خلفية برمجية لمن يستخدمها، هذا يعني أنك بحاجة إلى مطور ويب أيضًا حال استخدامك لهذه المنصة إن لم تكن لديك معرفة تقنية بأدوات التعامل مع خوادم الويب ولغة مثل PHP وقواعد البيانات. مزايا OpenCart إضافة تصنيفات ومنتجات كما تشاء دون تقييد بعدد معين. تغيير اللغة التي تستخدمها، إذ أنها تدعم لغات متعددة يمكنك تحميلها وإضافتها. تغيير العملات التي تستخدمها في تسعير منتجاتك. إدارة عدة متاجر من لوحة تحكم واحدة. تهيئة صفحات متاجرك لمحركات البحث عبر تخصيص الوسوم الوصفية meta tags الخاصة بمنتجاتك. أدوات نسخ احتياطي لقواعد بياناتك. تقارير عن مبيعاتك والمنتجات التي استعرضها عملاؤك. مراجعات للمنتجات وتقييمات لها. إضافة منتجات رقمية قابلة للتحميل. ورغم مجانية OpenCart إلا أنك ستدفع ثمن النطاق وإيجار الاستضافة والأمان لبياناتك، وكذلك بالنسبة للقوالب التي يمكنك استخدامها لمتجرك، فهي متوفرة من طرف ثالث -themeforest مثلًا، وستكون محدودًا بالمنتديات التي تقدم نصائح وإجابات فنية للمشاكل التي ستواجهك بسبب مجانية المنصة التي لا تغطي تكلفة الدعم الفني، لكن يمكنك توظيف مطور من طرف ثالث تقترحه عليك OpenCart بمقابل مادي طبعًا. ويمكنك تجربة المنصة مجانًا عبر تحميلها بشكل كامل وتثبيتها، لكن إن كنت تود تجربتها على عجل فإن المنصة تتيح لك تجربتها مباشرة دون أي تفاصيل أو تعقيدات، يمكنك تجربتها فورًا من هنا. لكن هذه التجربة ليست كاملة، بمعنى أنك لا تستطيع إضافة منتج مثلًا، وإنما هي للعرض التوضيحي فقط لما ستكون عليه واجهة المتجر بالنسبة للعميل، ولوحة التحكم بالنسبة لمدير المتجر. عيوب OpenCart يمكن قول نفس عيوب Magento هنا: كونها مفتوحة المصدر أو مجانية التحميل يعني أنك ستعتمد على نفسك في الدعم الفني. حاجتها إلى الإضافات (Add-ons) كي تعمل بكفاءة يعني زيادة التكلفة والحاجة إلى توظيف مطور ويب من أجل التعامل مع الأمور الفنية. بطء التحديثات وقلة الخيارات والباقات التي تقدمها. تصلح منصة OpenCart للأعمال الصغيرة والمتوسطة، لذا أنصحك بها إن كنت قد جربت ماجنتو ولم تعجبك لكنك ما زلت تود استخدام منصة مفتوحة المصدر ومجانية. PrestaShop تصنّف منصة PrestaShop أيضًا ضمن المنصات مفتوحة المصدر، وتوفِّر خيار التحميل المجاني، لكن لعلك خمنت أن هذا لا يعني أنها مجانية تمامًا، فإضافة إلى التكاليف التي ستدفعها للاستضافة، فإنك مضطر إلى شراء عدة وحدات (modules) من أجل أن تجعل موقعك يعمل بشكل مثالي كمتجر إلكتروني، ويفضّل أن توظِّف مطور ويب إن لم تكن لك خلفية تقنية للتعامل مع الطرف الخلفي (backend) للمتجر. وتوفّر PrestaShop إمكانية استعراض نسخة نموذجية منها إن لم ترد تحميلها وتجربتها بنفسك كي ترى لوحة التحكم والواجهة الأمامية التي سيراها المستخدم، وأنصحك هنا أيضًا بتوظيف مطور ويب من أجل ضبط وإعداد prestashop من أجلك. مزايا prestashop رسائل متابعة مع العملاء يمكن تخصيصها بهويتك التجارية. تحليلات في الوقت الحقيقي realtime analytics (يمكنك استبدالها بخدمة google analytics). خيارات الدفع المتعددة التي يمكن دمجها من طرف ثالث. ضبط متجرك ليظهر بلغات متعددة (تدعم المنصة أكثر من 60 لغة وتقبل عملات متعددة). حرية في اختيار خدمة الشحن التي تناسبك. زيادة الزيارات الطبيعية Organic Visits إلى متجرك. ولأنها مجانية فهي تعتمد على الربح من الإضافات التي تضيفها إلى متجرك من أجل توسعة نشاطك التجاري، مثل الإضافة التي تربط متجرك بإنستجرام كي تنشر منتجاتك الجديدة هناك، أو إضافة ebay أو أمازون التي تسمح لك بالبيع هناك مباشرة وإدارة متجرك من prestashop، فتلك الإضافات تتراوح أسعارها من 30$ إلى 300$. لكن ستحتاج مرة أخرى إلى توظيف مطور من أجل حل أي مشكلة قد تطرأ نتيجة أي خلل يحدث في تكامل الإضافات إذ أن أغلب الإضافات التي ستستخدمها من طرف ثالث، ومن ثم لا تستطيع prestashop أن تقدم لك دعمًا فنيًا لكل حالة تواجهها. عيوب prestashop مشاكل تكامل الإضافات والوحدات التي تستخدمها مع بعضها، والتي تحتاج إلى معرفة تقنية وبعض البحث في منتديات الدعم الفني أو إلى توظيف مطور ويب. التكاليف الإضافية التي تدفعها بعد تثبيت المنصة على خادمك، فإضافة إلى تكاليف الاستضافة، هناك تكاليف الوحدات والإضافات التي ستدخلها على المتجر، والتي قد تفوق تكلفة المنصات الأخرى التي تعمل بشكل خدمي Saas. ضرورة الخبرة التقنية لضبط وإعداد المتجر والإضافات. قد تناسب هذه المنصة الشركات متوسطة الحجم إلى الكبيرة أكثر من ملاءمتها للشركات والأعمال الصغيرة، وأنصحك باستخدامها إن كنت تعرف لغات مثل PHP، CSS، HTML أو كنت مستعدًا لتوظيف مطور. WooCommerce على عكس الأنظمة السابقة والتي كانت منصات بحد ذاتها، فإن WooCommerce تأتي في هيئة ملحق (plugin) لموقع يدار بووردبريس، وهي مثالية لمن لديه موقع يديره باستخدام ووردبريس ويريد أن يربح منه بشكل مباشر عن طريق إضافة سلات التسوق وأزرار الشراء وغيرها. ويستخدم تلك المنصة أكثر من 12% من المواقع التي تستخدم أدوات للتجارة الرقمية، تليها ماجنتو بنسبة 11%، ثم تأتي بعدها Shopify بنسبة 8%. وتستطيع تثبيت WooCommerce بشكل مجاني من متجر ووردبريس، لكنك ستتحمل تكلفة النطاق والخادم، كما تحتاج إلى حساب wordpress.com من أجل استخدام المنصة، ثم هناك تكاليف الإضافات التي تختلف حسب نشاطك التجاري، والتي قد تصل أثمانها إلى مئات الدولارات أحيانًا، لكن قد تكون التكاليف الكلية أقل من خيارات مثل Shopify و3dCart بما أنك ستدفعها مرة واحدة فقط وليس بشكل شهري. ويمكنك قراءة المزيد عن WooCommerce في السلسلة المفصلة في الأكاديمية، والتي تشرح لك بأسلوب سهل ما هي WooCommerce وكيف تضيف المنتجات وإعدادات الشحن والضرائب والحسابات والواجهة البرمجية وانواع المنتجات وغيرها من تفاصيل هذه المنصة. مزايا WooCommerce تدعم بيع المنتجات الافتراضية والحقيقية أيضًا. تحديد عناوين عملائك من أجل نجاح عمليات الشحن وحساب الضرائب. نظام شراء سهل وذكي، لا يحتاج إلى إعادة تحميل الصفحة في كل مرة يضيف العميل منتجًا إلى سلة شرائه. إدارة مخزونك من المنتجات. عرض حاسبة لتكاليف الشحن في صفحة الدفع. تهيئة محتوى متجرك لمحركات البحث. التحليلات والتقارير التي تتابع أرباحك وطلبياتك (يمكنك دمج Google Analytics مجانًا). إنشاء خصومات على المنتجات. أداة Storefront Powerpack التي تتيح لك تعديل تصميم متجرك حتى لو لم يكن لديك خبرة برمجية. ويمكنك تثبيت إضافات من متجر WooCommerce إن احتجت إلى زيادة وظائف متجرك، مثل إضافة حاسبة ضرائب أو وسائل شحن لمنتجاتك أو غيرها. كما تدعم طرق الدفع الشهيرة مثل التحويلات البنكية والشيكات وpayPal وstripe وغيرها. عيوب WooCommerce الدعم المحدود، بسبب أنها مجانية، إلا أنك تستطيع فتح تذكرة في Woocommerce forums إن واجهتك مشكلة، يردون عادة في خلال بضعة أيام. صعوبة التعامل معها في البداية، إن لم تكن معتادًا على تصميم ولهجة ووردبريس في القوائم والأزرار. بطء تحديثات القوالب التي من خارج متجر woocommerce. تحمل المستخدم -الذي هو أنت- مسؤولية أمان الخوادم التي تحميل بيانات المتجر. استخدم منصة WooCommerce إن لم تكن لديك مشكلة في قضاء بعض الوقت في تخصيص وإعداد متجرك الرقمي وشراء بعض الإضافات التي يحتاجها متجرك، أو إن كنت تجرب جدوى نموذج ربحي لموقع قائم بالفعل تريد توسيع نشاطه ليبيع منتجاتك فيه وتخشى من دفع المال في منصة عالية التكلفة في البداية. وهي مناسبة للشركات الصغيرة ومتوسطة الحجم، ولن تجد صعوبة في استخدامها إن كنت معتادًا على ووردبريس، فعملية إضافة المنتجات تشبه كتابة تدوينة في موقعك، فلوحة التحكم لا تختلف كثيرًا عن لوحة تحكم ووردبريس. هذا لا يعني أن WooCommerce منصة تجارب فقط، وإنما هي مناسبة للأعمال الصغيرة أو التي لديها أذرع في العالم الرقمي وتريد استغلالها، مثل موقع أو مدونة تريد البيع من خلالها. نقل قاعدة بياناتك إذا كان لديك متجر بالفعل يدار بنظام ما وأردت التحوّل لاستخدام أحد الأنظمة التي ذكرناها هنا في المقال، أو كنت تفكّر في تجربة أحد تلك الأنظمة لكنك تخشى من الوقت والجهد الذي سيضيع في نقل قاعدة بياناتك إلى النظام الجديد، فلتعلم أن هناك شركات تقدم تلك الخدمة -أي نقل قاعدة بياناتك من نظام لآخر- في بضع ساعات، وينقلون لك كل شيء بما في ذلك تاريخ الطلبيات التي كانت في النظام الأول. والشركة التي نعرضها عليك في هذا المجال هي Cart2Cart، ولديهم حاسبة تحسب لك تكلفة نقل قاعدة بياناتك بناءً على عدد المنتجات والعملاء والطلبيات التي تريد نقلها، فتكلفة نقل قاعدة بيانات بها 1000 منتج و500 عميل و500 طلبية من Opencart إلى Magento تصل إلى 70 دولارًا، وفي أقل من ساعة واحدة. اختيار البرنامج المناسب قبل أن تختار برنامج لإدارة التسوّق في متجرك، عليك أن تجرّب الخيارات التي تناسب عملك وتجارتك حيث توفر عدة منصات نسخًا مجانية أو فترات تجريبية من منتجاتها كما رأينا في المقال، كي تضع يدك على العناصر التي تريدها وتحتاجها من الأداة التي ستستخدمها في النهاية، وتقيس تحقيق الأدوات التي ستجرّبها لتلك العناصر. ثم هناك اعتبارات أخرى تضعها في حساباتك، مثل إمكانية إنشاء العروض (offers)، والقسائم (coupons)، والصفحات والإعلانات بسهولة، وكذلك مدى سهولة إجراءات الشحن وإدارة الطلبيات، وهي أمور يجب أن تجرب المنصة بنفسك كي ترى مدى فعاليتها بالنسبة لحالتك. أما أهم سؤال يجب أن تجيب عليه هو هل شركتي يناسبها برنامج ذو رخصة أدفع ثمنه مرة واحدة، أم برنامج سحابي أدفع له اشتراكًا كل حين؟ فالحلول السحابية تأتي من شركات تعطيك النظام الذي ستدير به متجرك في مقابل اشتراك شهري أو سنوي، على أن تقوم هي على صيانة خوادمك التي تحمل بياناتك وبيانات عملائك، وتحدّثها بآخر إصدارات البرامج والإضافات التي تحتاجها، لتركّز أنت على إدارة عملك دون التفكير في أمور تقنية أو توظيف من يقوم عليها. إليك بعض المحاسن والعيوب للبرامج السحابية: محاسن الحلول السحابية تكلفة تشغيل أوليّة قليلة. التكاليف تشمل الاستضافة. سهولة التثبيت والإعداد. عيوب الحلول السحابية قد يصعب عليك إعداد موقعك إن لم تكن لديك الإضافات المناسبة. قد يزيد السعر مع زيادة الاستخدام. أغلب الإضافات والمزايا بنظام اشتراك شهري. لا تستطيع تغيير الشركات المستضيفة لبياناتك إن لم تعجبك. وعلى الناحية الأخرى فهناك شركات تقدم أنظمة تشتري ترخيص استخدامها أو توفره بشكل مجاني، لكن هذا يعني أنك ستضيف تكلفة الاستضافة وصيانة الخوادم وتحديث برامجها وغير ذلك. إليك بعض المحاسن والعيوب أيضًا لهذا النوع: محاسن الأنظمة ذات الرخصة مرونة وقابلية توسع عالية. توفّر الإضافات عادة لخطط الأسعار التي تدفع على مرة واحدة. لا حدود للتخزين ولا المنتجات ولا سعة الإنترنت المخصصة لك. حرية تغيير الشركات المستضيفة لبياناتك إن شئت. عيوب الأنظمة ذات الرخصة تثبيتها معقّد لمن ليس له خلفية أو خبرة بها، كما أنها تستغرق وقتًا أطول من الخدمات السحابية في الإعداد. ستحتاج إلى تحديثها باستمرار بنفسك. دعم فني أقل جودة. ستحتاج إلى توظيف مصممين ومطورين للقيام على تحديث النظام وضبطه وتهيئته. وهكذا يظهر أن الخدمات السحابية أسهل في الإعداد والاستخدام، لذا فإنها مناسبة للشركات الصغيرة والمتناهية الصغر، لكن اعلم أن التكلفة في تلك الخدمات قد ترتفع إلى الحد الذي يجعلك تدفع مالًا أكثر من لو كنت قد استخدمت برنامجًا بنظام رخصة الاستخدام، لكنك تدفع هنا ثمن صيانة وإعداد وتهيئة متجرك، حيث أنك لا تريد تحمل تكلفة المصممين أو المطورين الذين سيقومون على ضبط وتهيئة متجرك. خاتمة لقد وجّهنا هذا المقال إلى أصحاب المتاجر والشركات الصغيرة بشكل خاص، وباقي الشركات بشكل عام، ممن يرغبون بفتح متاجر رقمية لبيع منتجاتهم على الإنترنت سواء الرقمية منها أو الحقيقية كي يكون دليلًا لأشهر أنظمة إدارة المتاجر الرقمية، ومزايا استخدام نماذجها المختلفة. حقوق الصورة البارزة محفوظة لـ Freepik1 نقطة
-
إنّ من أكثر ما يجعل العمل مُمتعا هو أن تكون مُتحمسا له، ولكنه قد يصبح أكثر ما يضرنا إذا أصبح هذا الحماس بديلا عن المعرفة وأصبح طريقنا مليئًا بالفرضيات غير المختبرة والرؤية غير الواضحة، ماذا لو كانت أيضا بيئة العمل تؤمن بنظرية العبقري المبدع الذي يعلم كل شيء وتطلب من مصمميها ومطوريها بأن يكونوا هذا العبقري المثالي الذي يستطيع لوحده أن يؤدي وظائفهُ ويتقنها بأكمل وجه، مما يجعلها بيئة عمل غير واقعية تجعل من قول كلمة "لا أعرف" شيئا مستحيلًا. إن النتيجة النهائية لمثل هذه البيئات هو منتجات منفصلة عن الواقع ولا تُلبّي احتياجات ورغبات المستخدمين الحقيقية وبالتالي تصبح منتجات فاشلة لا يُوجد لها أيّ حصة من السوق. إداراك الحاجات والرغبات الحقيقية للناس هو الشّرط الأساسي للتصميم وكما يقول خبراء هذا المجال أن التصميم المتمحور على المستخدم User-Centered Design هو جوهر هذا العلم وأساسه. لذلك يجب ألا ننحاز لأنفسنا أو لعملنا أو مهما كانت انحيازاتنا في بناء منتجاتنا ونجعل تركيزنا هو المستخدم النّهائي. هذا وكيف إن كانت المشكلة الرئيسية عند المصممين والمطورين أثناء عملهم هو أنهم يبنون الأشياء لأنفسهم، حيث أنهم متعلقون في الأمور التقنية أكثر من غيرهم من الناس كما قال ذلك الكاتب الأمريكي Michael E. Gerber في كتابه أسطورة الريادي The E-Myth. هنا تظهر الحاجة الأساسية في فهم حاجات المستخدمين ورغباتهم، وحتى نحقّق ذلك لا بد لنا من عملية بحث مُمَنهجة لنتوصّل إلى نتائج يتم معالجتها، ونبني في ما بعد على أساسها منتجاتنا وبرامجنا. ما هو البحثفي البداية أرجو ألا تفزع من كلمة "بحث" وتنظر إليها على أنها تحتاج إلى وقت ودراسة وأموال حتى يكتمل البحث، فالبحث ببساطة هو تحقيق منظم للوصول إلى المعلومة. أنت تريد أن تعرف أكثر في موضوع معين لذلك أنت تتبع منهجاً معين لزيادة معرفتك في هذا الموضوع، هذا المنهج الذي ستتبعه لزيادة معرفتك يعتمد على من أنت وظيفيًا ومالذي تريد أن تعرفه. واطمئّن، فنوعية البحث المستخدمة هنا ليست بحث أساسي Pure Research معقّدة بمعنى أنه لن تكون مهمتك أن تعرف كيف تتم عملية التذكر في أعصاب الدماغ. في مجالنا هذا يتم الاستعانة بنوعين من الأبحاث للحصول إلى المعلومات هما: البحث الكمّي والبحث النّوعي، كما أن هذان البحثان أيضا هما البحثان اللذان يتم استعمالهما في إنشاء الشركات الناشئة، وهذا لاشتراك هذين المجالين في أنّهما يريدان بناء منتج يريده الناس ويحتاجونه. البحث الكمّي والنّوعيالبحث الكمّي Quantitative Research بحث منهجي للظواهر الاجتماعية من خلال الأساليب الإحصائية، الرياضية أو الحسابية، ويتم الاعتماد على البيانات بشكل رئيسي حتى يتم قياسها رقميا وبالتالي عند بداية فكرة جديدة لا نلجأ إليه لعدم وجود بيانات متعلقة بالمستخدمين وإنما يتم الاستعانة به بعد إصدار النسخة الأولية أو الحد الأدنى من المنتج القاعدي (Minimum Viable Product). البحث النّوعي Qualitative Research بحث يهدف إلى التعمق في فهم سلو الإنسان والأسباب التي دفعته للقيام بهذا السلوك وتكون عينته قليلة وطبيعة أسئلته بكيف، لماذا، وبأي طريقة. توجد طرق كثيرة لجمع البيانات منها المقابلات الفردية والجماعية، الملاحظة ومجموعات التركيز. يعتمد على فهم الناس بتعمق ولعدم وجود أي بيانات تتعلق بالمستخدمين عند بداية المشروع فعادة ما يتم البدء به. تكون نتائجه عبارة عن فرضيات يتم التحقق منها فيما بعد عن طريق البحث الكمي، كما يتم استخدامه أيضا عند بناء خصائص جديدة للمنتج أو عند وجود غموض في نتائج البحث الكمي. ماذا أريد من البحثالبحث هو أداة بمثابة ميكروسكوب تستطيع من خلالها النظر إلى الصورة كاملة مما تسهل عملية تخطيطنا وإدارتنا. وعند بناء المنتجات يتعين علينا القيام بأربعة بحوث. بحث المنظمة وأصحاب المَصلحةفي هذا البحث تكون الفئة المستهدفة في البحث هم أصحاب المصلحة وفريق العمل المُشترِك معك في بناء المنتج، ويكون هدفه الإجابة عن الأسئلة التالية: مالذي يريد تحقيقه صاحب المنتج وأصحاب العمل، من هم، وما هي أهدافهم؟ماهي التنكولوجيا المستخدمة في بناء المنتج، وما إمكانياتنا وقدراتنا؟بحث المستخدمهو البحث المتعلق بفهم المستخدمين وسلوكهم، ويكون هدفه الإجابه عن هذه الأسئلة: من سيستخدم المنتج، ما مميزاتهم، أعمارهم، جنسهم، هواياتهم، وما سلوكهم الحالي في استخدامهم للمنتج أو لحلول مشابهة؟مالذي يريد تحقيقه المستخدم من استخدامه للمنتج؟وفي حال كان المنتج تطويرًا لنسخة سابقة: ما هي الخصائص والوظائف الحالية أو التعقيدات التي تواجه المستخدم؟ما هي الخصائص والوظائف التي سوف يجدها المستخدم جيدة لو تم إضافتها؟البحث التقييّميإذا قمت ببناء منتجك أو برنامجك بناء على حاجات المستخدم فلا بد لك من التأكد من ذلك والتأكد ما إذا كان منتجك جاهزاً لإصداره للسوق أم لا، هل هو سهل الاستخدام وما هي عيوبه؟ هنا الهدف الرئيسي من البحث التقييمي. بحث المنافسينمن هم منافسيك؟ يجب عليك أن تعرفهم وتقيمهم وتعرف ما هي مُميزّاتهم، خصائصهم وما هو الجديد الذي ستضيفه في منتجك بعد معرفتك لمنافسينك. مع العلم بأن أصعب منتج منافس لك هو الذي يستخدمه الآن زبائنك المحتملين في المستقبل كما أن الناس كسولون بطبعهم ويكرهون تغيير عاداتهم فلذلك يجب عليك إضافة شيء مميز ورائع في منتجك يحبونه أكثر من كرهم لتغيير هذه العادة. التكلم بتفصيل عن كل هذه البحوث هو خارج نطاقنا هنا لكن سنكتفي بأهمهم وهو بحث المستخدم. بحث المستخدمإذا استطعنا أن نحدد إجابة للسؤال العملي المتعلق بالمنظمة أو الشركة وهو "ما الذي نريده من بناء هذا المنتج" نبدأ بعدها بالطرف الآخر من المعادلة وهو المستخدم وهدفنا كما قلنا أن نعرف ما الذي يريده المستخدمون من هذا المنتج. قد يبدو هذا السؤال بسيطاً وبديهيا لكن أكثر الأسئلة عمقا هي الأسئلة البديهيه. الإثنُوجرَافِي Ethnographyالبعض يسمي البحث النّوعي بالإثنوجرافي وهدفه فهم وتوثيق نشاطات، عقليات وسلوكيات مجموعة من الناس بعد أن يراها الملاحظ أو المراقب ويتم بطرق كثيرة أهمها المقابلة والاستفسار السياقي. المقابلة Interviewلقد ابتدأ العمل، استعد لمقابلة الناس المستهدفة ورتب لذلك وتذكر بأننا نريد أن نفهم السلوك فمثلا إذا كان كان منتجك هو بناء موقع إلكتروني لبيع تذاكر السينما فسنقوم باستهداف رواد السينما وليس محبي الأفلام. الدليلحضر دليل المقابلات بحيث يكون هو المرجع لجميع المقابلات، ومن أهم ما يجب أن يحتويه هذا المرجع هو: مختصر يوضح هدف الدراسة.الديموغرافيا (Demographics) وهي تختلف على اختلاف الدراسة وأهم ما تحتويه الاسم، العمر، الجنس، البلد، الوظيفة والتعليم.مجموعة من الأسئلة لتكسير الحواجز الجليدية في المقابلة، أنت لا تريد فقط أن تنتهي من مقابلتك أنت تريد أن تحصل على أصدق المعلومات لذلك لا بد من أن يخلو الجو من التوتر وتسود الراحة في المكان.الأسئلة الرئيسية في المقابلة وهي الأسئلة المتعلقة بموضوع الدراسة. تجنب أن تسأل أسئلة مثل "ما هو الحل برأيك" وذلك لأن المستخدم ليس مُصمما وغايته ببساطة أن يستخدم المنتج النهائي بسهولة ومتعة.بنية المقابلة (مع مثال توضيحي)المقدمةابدأ بتعريف نفسك مع ابتسامة وعبر عن امتنانك وشكرك له وقدر أنه يعطيك من وقته من أجل هذه المقابلة، خذ معلوماته الشخصية بطريقة مرنة وابدأ بتلطيف الجو في المقابلة واسأله أسئلة في خارج إطار الموضوع، عن تجربته وماذا يحب وما رأيه في موضوع معين بناء على سياق المقابلة وذلك لتكسير الحواجز قبل أن تبدأ في الأسئلة الأساسية في المرحلة التي بعدها. الرئيسيةهنا جوهر المقابلة، ستبدأ بالأسئلة الرئيسية، مثل: أخبرني عن أسبوعك بشكل عام؟ما مدى اهتمامك بالسينما؟هل تذهب للسينما في العطل الأسبوعية، أم لا يوجد وقت محدد؟كيف تتابع آخر الأفلام، وما نوعية الأفلام التي تحبها؟كيف تشتري تذاكرك، هل لديك مشكلة في الدفع عبر الإنترنت؟كم تقضي من الوقت متصلا بالإنترنت، وما هي وسيلة اتصالك به؟كيف تذهب للسينما، مع زوجتك وأولادك أو لوحدك؟ما هي المواقع التي تزورها في العادة؟وكما قلنا ركز على أن تكون الإجابات واقعية وأعر انتباهك لأي إجابة غريبة واستفهم عنها، حاول أن تكون مستمعا جيداً وتجنب التحدث عن نفسك كثيراً. كما أفضل أن تقوم بتدوين الإجابات بعد المقابلة مباشرة وذلك لتجنب تأثير هورثون (وهو أن سلوك الشخص قد يتغير إذا علم أنه مراقب وسُيقدم السلوك المتوقع تقديمه). الخاتمةاعمل نقلة لطيفة لإنهاء المقابلة واختم مثلا بقولك "انتهيت من الأسئلة، ألديك أي شيء لتضيفه أو أي تعليق بخصوص ما ناقشناه؟". الاستفسار السياقي Contextual Inquiryهي طريقة أخرى من طرق بحث الإثنوجرافي وهو شبيه بالمقابلة إلا أنه يأخذ شكلا أعمق ويختلف عنها بأنه يتطلب الذهاب إلى مكان الحدث مباشرة وأن تراقب المستخدم أثناء قيامه بعمله وتقوم بملاحظته لفهم الموضوع بدقة أكثر ولمعرفة حقيقة الموضوع. ذلك، لأنه في أحسن الظروف في المقابلة النظرية لن تستطيع أن تتذكر كل شيء كمُقابل ولن تدرك حقيقة الشيء إلا إذا قمت بمعاينته وتجربته. لعل أقرب مثال لهذا النوع من البحوث هي قصة إنتاج سيارة Toyota sienna minivan سنة 2004، تم توكيل إنتاج هذه السيارة وتصميمها لـ "يوجي يوكوفا" وكان السوق المستهدف لها هو أمريكا الشمالية التي لم يكون "يوجي" يسكنها أو عنده أي خبرة حقيقة فيها. هنا قام "يوجي" بالذهاب بنفسه إلى أمريكا الشمالية قاطعا بنفس السيارة ولكن بموديل السنة السابقة 2003 ولايات أمريكا الخمسون، أراضي كندا والمكسيك. كان هدف "يوجي" هو التحدث مع الناس مباشرة ومراقبتهم أثناء سياقتهم للسيارة ليقوم ببحثه في أرض الحدث مباشرة. بعد أن انتهى من جولته البحثية أنتج الموديل الجديد للسيارة وكانت النتيجة أن مبيعات السيارة لموديل 2004 زادت بنسبة أكثر60% عن السنة السابقة. الجانب العاطفي أثناء البحثالعواطف موضوع خصوصي جداً، كما يبدو أنه من وجهة النظر البسيطة أن هناك فجوة بينه وبين التكنولوجيا. لذا فمن الخطأ أن يتم طرحه بصورة مباشرة في المقابلة، هذا قد يسبب الإحراج للجميع والخطأ في النتائج. هنا يكمن دورك في أن تكون يقظا في أن تفهم الخبايا وأن تقرأ ما بين السطور. راقب أثناء قيامك بالاستفسار السياقي بتأثير الجمال والمتعة على المستخدمين وابحث أيضا في فرص زيادة تأثيرهما. اهتم بالهدف العاطفي من وراء استخدام المنتج، مثلا أنا سأقوم بشراء تذكرتين إلكترونيتين لي ولزوجتي في السينما لقضاء وقت رائع معها، هنا يكون الهدف هو السرور مع الزوجة أكثر من الاستمتاع بالفيلم، ماذا لو كان الهدف هو قضاء وقت الفراغ ليس إلا؟ هنا يكون الدافع هو الملل وليس الشغف في السينما. فهمك لهذه العواطف سيساعدك على تصنيف المستخدمين كما سيجعل من منتجك أكثر عمقاً وبساطة. لمزيد من القراءة كتاب The UX Bookكتاب Just Enough Researchمقال A Five Step Process For Conducting User Researchمقال 5Useful Lies to Tell User Research Participants1 نقطة
-
سنتعلم في هذا الدرس، بعض المعلومات عن تاريخ نظام ملفات EXT4 وعن ميزاته واستخدامه الأمثل، وسنناقش الاختلافات بينه وبين الإصدارات السابقة من أنظمة ملفات EXT. أريد في هذا الدرس تفصيل مواصفات أنظمة ملفات EXT، لكنني سأبدأ أولًا بالإجابة على التساؤل «ما هو نظام الملفات»، نظام الملفات يقوم بما يلي: تخزين البيانات: إذ إنَّ الغرض الرئيسي لأي نظام ملفات هو توفير مكان منظم ومُهيكل لتخزين البيانات والحصول عليها. توفير مجالات أسماء (namespaces): إذ يوفر نظام الملفات منهجية تنظيمية لتسمية وهيكلة البيانات. توفير نموذج أمني (security model): الذي يُعرِّف امتيازات الوصول إلى البيانات المخزنة. توفير واجهة برمجية (API): وهي الدوال (functions) التي تستخدم لتتعامل مع الكائنات الموجودة في نظام الملفات مثل المجلدات والملفات. توفير برمجيات لتطبيق المواصفات السابقة. سنركِّز في درسنا على أوّل عنصر من القائمة السابقة ونستكشف بنى البيانات الوصفية (metadata) التي توفر إطار العمل المنطقي (logical framework) لتخزين البيانات في أنظمة ملفات EXT. تاريخ نظام ملفات EXT صحيحٌ أنَّ نظام ملفات EXT قد كُتِبَ لأنظمة لينكس، لكن جذوره تتأصل في نظام تشغيل Minix ونظام ملفاته، والذي يسبق ظهور لينكس بخمس سنوات، إذ نُشِر أوّل مرة في عام 1987. سيسهل علينا فهم نظام ملفات EXT4 إذا نظرنا نظرةً شموليةً على تاريخ نظام ملفات EXT والتطور التقني الذي حدث لعائلة أنظمة ملفات EXT بدءًا من أصولها في نظام Minix. نظام ملفات Minix عندما كان Linus Torvalds يكتب نواة لينكس، احتاج إلى نظام ملفات لكنه لم يرغب بكتابة واحد، لذا ضمّن نظام ملفات Minix الذي كتبه Andrew S. Tanenbaum وكان جزءًا من نظام تشغيل Minix؛ والذي هو نظام تشغيل شبيه بِيونكس (Unix-like) كُتِبَ لأغراضٍ تعليمية، وكانت شيفرته المصدرية متوافرة مجانًا ومرخصة برخصة سمحت بتضمينها في أوّل نسخة من نواة لينكس. هذه هي بنية نظام ملفات Minix، والتي تتواجد أغلبية مكوناتها في القسم (partition) الذي يستعمل نظام الملفات السابق: قطاع الإقلاع (boot sector) الموجود في أوّل قطاع (sector) في القرص الصلب الذي يحتوي على نظام الملفات؛ يحتوي قطاع الإقلاع على سجل إقلاع صغير جدًا إضافةً إلى جدول الأقسام (partition table). أوّل قطاع في كل قسم يسمى قطاع superblock، الذي يحتوي على البيانات الوصفية التي تُعرِّف البنى الأخرى الموجودة في نظام الملفات وتحدد مكانها في القرص الفيزيائي. قطاع بقائمة مؤشرات الفهرسة (inode)، التي تحدد ما هي مؤشرات الفهرسة المستخدمة والمتاحة للاستخدام. مؤشرات الفهرسة، التي لها مساحة خاصة على القرص، وكل مؤشر فهرسة يملك معلومات عن ملف واحد، بما في ذلك مكان كتل البيانات (data blocks)، أي ما هي المناطق على القرص التي ترتبط بهذا الملف. قائمة بالمناطق (zone bitmap)، والتي تَتَبَّع مناطق البيانات المستخدمة والحرة. منطقة تخزين البيانات (date zone)، وهي مكان تخزين البيانات. سُيستعمل –لكلا نوعَي القوائم السابقين– بت (bit) وحيد لتمثيل منطقة بيانات أو مؤشر فهرسة واحد؛ فإذا كانت قيمة البت تساوي الصفر فهذا يعني أنَّ منطقة التخزين أو مؤشر الفهرسة حر ويمكن استخدامه، أما إذا كانت قيمة البت تساوي الواحد فهذا يعني أنَّ منطقة البيانات أو مؤشر الفهرسة قيد الاستخدام. حسنًا، ما هو «مؤشر الفهرسة» (inode)، إنه اختصارٌ للكلمة index-node، إذ إنَّ مؤشر الفهرسة هو كتلة موجودة على القرص مساحتها 256 بايت التي تخزِّن بيانات تصف الملف. هذه البيانات تتضمن حجم الملف، ومُعرِّف المستخدم (user ID) للمستخدم المالك للملف وللمجموعة المالكة، إضافةً إلى نمط الملف (أي أذونات الوصول)؛ مع تخزين ثلاث بصمات وقت (timestamps) التي تُحدِّد ما هو الوقت والتاريخ الذي تم الوصول إلى الملف آخر مرة، ومتى عُدِّل، ومتى تغيّرت البيانات الموجودة في مؤشر الفهرسة آخر مرة. يحتوي مؤشر الفهرسة على معلومات تُشير إلى مكان تخزين بيانات الملف على القرص الصلب، وهذه المعلومات هي قائمة بمناطق البيانات (أو كتل البيانات) في أنظمة ملفات Minix و EXT1-3. كان مؤشر الفهرسة في نظام ملفات Minix يدعم تخزين تسع كتل بيانات، سبعٌ منها مباشر واثنان ليستا مباشرتين؛ إذا أردت تعلم المزيد عن بنية نظام ملفات Minix فأنصحك بإلقاء نظرة على مستند PDF الآتي الذي يشرح ذلك بالتفصيل واقرأ لمحةً عامةً عن بنية مؤشرات الفهرسة في ويكيبيديا. EXT نظام الملفات EXT الأصلي (الذي يرمز اسمه إلى Extended) كتبه Rémy Card ونُشِرَ مع نواة لينكس في عام 1992 لتجاوز بعض محدوديات التخزين في نظام ملفات Minix، وكانت التغيرات البنيوية الرئيسية حدثت للبيانات الوصفية لنظام الملفات، والتي أصبحت مبنية على نظام ملفات Unix (UFS)، والذي أصبح معروفًا بنظام ملفات FFS (اختصار للعبارة Berkeley Fast File System). وجدتُ قدرًا ضئيلًا من المعلومات المنشورة عن نظام ملفات EXT التي يمكن التأكد منها، وأرجِّح ذلك بسبب المشاكل الكبيرة التي كان يواجهها هذا النظام، ولأن نظام ملفات EXT2 استبدله بعد فترةٍ قليلة. EXT2 نظام ملفات EXT2 كان ناجحًا جدًا، إذ استعمل في توزيعات لينكس لسنواتٍ عدِّة، وكان أوّل نظام ملفات تعاملتُ معه عندما بدأت باستخدام Red Hat Linux 5.0 في عام 1997. كان نظام ملفات EXT2 يملك بنية البيانات الوصفية الموجودة في نظام ملفات EXT نفسها، لكن نظام ملفات EXT2 كان متطلعًا للمستقبل، إذ ترك مساحةً كبيرةً بين بنى البيانات الوصفية لاستخدامها مستقبلًا. وكما في نظام ملفات Minix، امتلك EXT2 قطاع إقلاع في أوّل قطاع موجود على القرص الصلب الذي ثُبِّتَ عليه، والتي يحتوي على سجل إقلاع صغير جدًا وجدول أقسام، وكانت هنالك مساحة محجوزة بعد قطاع الإقلاع، والتي تمتد من قطاع الإقلاع إلى أوّل قسم في القرص الصلب. يستعمل مُحمِّل الإقلاع GRUB2 (أو GRUB1) هذه المساحة لتخزين شيفرة الإقلاع الخاصة به. المساحة الموجودة في كل قسم EXT2 تُقسَّم إلى مجموعات أسطوانية (cylinder groups) التي تسمح بإدارة جزيئية (granular management) للمساحة التخزينية. تُظهِر الصورة التالية البنية الأساسية للمجموعات الأسطوانية (والتي تكون مساحة كل واحدة منها –حسب خبرتي– حوالي 8 ميغابايت)، تذكر أنَّ واحدة تخزين البيانات في الأسطوانة هي الكتلة، والتي تساوي 4 كيلوبايت تقريبًا. أوّل قطاع في المجموعة الأسطوانية يسمى قطاع superblock، الذي يحتوي على البيانات الوصفية التي تُعرِّف البنى الأخرى التابعة لنظام الملفات وتحدد مكانها في القرص الفيزيائي. يمكن استبدال قطاع superblock معطوب باستخدام أدوات التعامل مع الأقراص مثل dd، وذلك باستعادة محتويات نسخة احتياطية من قطاع superblock، ولا يحدث ذلك عادةً، لكن منذ عدِّة سنوات حدث ذلك معي، واستطعت استعادة محتويات قطاع superblock من إحدى النسخ الاحتياطية، ولحسن الحظ كنتُ محتاطًا لهذا الأمر واستعملتُ الأمر dumpe2fs للحصول على بيانات الأقسام الموجودة في نظامي. ما يلي هو جزء من ناتج الأمر dumpe2fs، الذي يُظهِر البيانات الوصفية الموجودة في قطاع superblock، إضافةً إلى بيانات عن أوّل مجموعتين أسطوانيتين في نظام الملفات: # dumpe2fs /dev/sda1 Filesystem volume name: boot Last mounted on: /boot Filesystem UUID: 79fc5ed8-5bbc-4dfe-8359-b7b36be6eed3 Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir nlink extra_isize Filesystem flags: signed_directory_hash Default mount options: user_xattr acl Filesystem state: clean Errors behavior: Continue Filesystem OS type: Linux Inode count: 122160 Block count: 488192 Reserved block count: 24409 Free blocks: 376512 Free inodes: 121690 First block: 0 Block size: 4096 Fragment size: 4096 Group descriptor size: 64 Reserved GDT blocks: 238 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 8144 Inode blocks per group: 509 Flex block group size: 16 Filesystem created: Tue Feb 7 09:33:34 2017 Last mount time: Sat Apr 29 21:42:01 2017 Last write time: Sat Apr 29 21:42:01 2017 Mount count: 25 Maximum mount count: -1 Last checked: Tue Feb 7 09:33:34 2017 Check interval: 0 (<none>) Lifetime writes: 594 MB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 Required extra isize: 32 Desired extra isize: 32 Journal inode: 8 Default directory hash: half_md4 Directory Hash Seed: c780bac9-d4bf-4f35-b695-0fe35e8d2d60 Journal backup: inode blocks Journal features: journal_64bit Journal size: 32M Journal length: 8192 Journal sequence: 0x00000213 Journal start: 0 Group 0: (Blocks 0-32767) Primary superblock at 0, Group descriptors at 1-1 Reserved GDT blocks at 2-239 Block bitmap at 240 (+240) Inode bitmap at 255 (+255) Inode table at 270-778 (+270) 24839 free blocks, 7676 free inodes, 16 directories Free blocks: 7929-32767 Free inodes: 440, 470-8144 Group 1: (Blocks 32768-65535) Backup superblock at 32768, Group descriptors at 32769-32769 Reserved GDT blocks at 32770-33007 Block bitmap at 241 (bg #0 + 241) Inode bitmap at 256 (bg #0 + 256) Inode table at 779-1287 (bg #0 + 779) 8668 free blocks, 8142 free inodes, 2 directories Free blocks: 33008-33283, 33332-33791, 33974-33975, 34023-34092, 34094-34104, 34526-34687, 34706-34723, 34817-35374, 35421-35844, 35935-36355, 36357-36863, 38912-39935, 39940-40570, 42620-42623, 42655, 42674-42687, 42721-42751, 42798-42815, 42847, 42875-42879, 42918-42943, 42975, 43000-43007, 43519, 43559-44031, 44042-44543, 44545-45055, 45116-45567, 45601-45631, 45658-45663, 45689-45695, 45736-45759, 45802-45823, 45857-45887, 45919, 45950-45951, 45972-45983, 46014-46015, 46057-46079, 46112-46591, 46921-47103, 49152-49395, 50027-50355, 52237-52255, 52285-52287, 52323-52351, 52383, 52450-52479, 52518-52543, 52584-52607, 52652-52671, 52734-52735, 52743-53247 Free inodes: 8147-16288 Group 2: (Blocks 65536-98303) Block bitmap at 242 (bg #0 + 242) Inode bitmap at 257 (bg #0 + 257) Inode table at 1288-1796 (bg #0 + 1288) 6326 free blocks, 8144 free inodes, 0 directories Free blocks: 67042-67583, 72201-72994, 80185-80349, 81191-81919, 90112-94207 Free inodes: 16289-24432 Group 3: (Blocks 98304-131071) <snip> كل مجموعة أسطوانية لها قائمة مؤشرات الفهرسة الخاصة بها التي تستخدم لتحديد ما هي مؤشرات الفهرسة المستعملة والحرة في تلك المجموعة. تملك مؤشرات الفهرسة مساحةً خاصةً لها في كل مجموعة، وكل مؤشر فهرسة يحتوي على معلومات عن ملفٍ وحيد، بما في ذلك مكان كتل البيانات التي تتعلق بذاك الملف. أما قائمة الكتل فتَتَبّع كتل البيانات الحرة والمستخدمة ضمن نظام الملفات؛ لاحظ وجود قدر كبير من البيانات حول نظام الملفات في الناتج السابق، وستكون معلومات المجموعات طويلةً جدًا في أنظمة الملفات الكبيرة؛ إذ تتضمن البيانات الوصفية الخاصة بالمجموعة الأسطوانية قائمةً بجميع كتل البيانات الحرة فيها. يُطبِّق نظام ملفات EXT استراتيجيات لتوزيع البيانات التي تحرص على تقليل تجزئة الملف قدر المستطاع، وتقليل التجزئة سيُحسِّن من أداء نظام الملفات، وهذه الاستراتيجيات مشروحة في قسم EXT4 أدناه. أكبر مشكلة مع نظام ملفات EXT2 –التي واجهتني في بعض المناسبات– هي الزمن الطويل الذي يقدر بالساعات لاستعادة نظام الملفات بعد حدوث انهيار مفاجئ، لأنَّ برنامج fsck (اختصار للعبارة file system check) كان يأخذ وقتًا طويلًا للعثور على التضاربات في نظام الملفات وتصحيحها. ففي إحدى المرات أخذت استعادة القرص في أحد حواسيبي بعد حدوث انهيار ما يزيد عن 28 ساعة، وكان حجم الأقراص آنذاك قليلًا ويقدر ببضع مئات من الميغابايتات. EXT3 كان لنظام ملفات EXT3 هدفٌ وحيدٌ ألا وهو التغلب على مشكلة استغراق الأمر fsck وقتًا طويلًا لاستعادة بنية القرص المعطوبة بسبب حدوث إغلاق غير سليم الذي وقع أثناء عملية تحديث لأحد الملفات، فالتغيير الوحيد الذي طرأ على نظام ملفات EXT هو إضافة السجلات أو الصحائف (journal) التي تُخزِّن التعديلات مسبقًا قبل إجرائها على نظام الملفات؛ أما بقية بنية القرص فبقيت تماثل بنية نظام ملفات EXT2. بدلًا من كتابة البيانات إلى كتل البيانات على القرص مباشرةً كما في الإصدارات السابقة، فإن السجلات في نظام ملفات EXT3 تكتب بيانات الملف –إضافةً إلى البيانات الوصفية– إلى مكان مُحدَّد في القرص، وبعد أن تكتب البيانات بأمان على القرص، فيمكن أن تُدمَج أو تُضاف إلى الملف الهدف باحتمال فقدان البيانات بنسبة تقترب من الصفر. وبعد كتابة البيانات إلى كتل البيانات على القرص، فسيُحدَّث السجل (journal) لكي يبقى نظام الملفات بحالة مستقرة في حال حدوث فشل في النظام قبل كتابة جميع البيانات الموجودة في السجل على القرص. سيتحقق نظام الملفات من وجود تضاربات عند الإقلاع، وستُكتَب البيانات الموجودة في السجل إلى كتل البيانات الموجودة في القرص لإكمال التحديثات التي تستهدف ملفًا معينًا. يُنقِص استخدام السجلات من أداء كتابة البيانات، لكن هنالك ثلاثة خيارات متوافرة للسجلات التي تسمح للمستخدم بالاختيار بين الأداء وسلامة البيانات والحماية. أفضِّل سلامة البيانات على الأداء في الأنظمة التي أعمل عليها لعدم وجود نشاطات تحتوي على الكثير من الكتابة على الأقراص. تقلل ميزة السجلات من الوقت اللازم لتفحص القرص الصلب والبحث عن التضاربات بعد حدوث انهيارات من ساعات (أو حتى أيام) إلى دقائق قليلة (في أقصى الحالات). واجهتُ مشاكل كثيرة على مر السنين التي أدت إلى انهيار أنظمتي؛ لن أذكرها بالتفصيل لأن ذكرها سيتطلب كتابة مقالة كاملة، لكن يكفي القول أنَّ أغلبها قد حدث دون تدخل من المستخدم، كحدوث انقطاع في الكهرباء؛ ولحسن الحظ، قلَّلت أنظمة ملفات EXT التي تستعمل السجلات من زمن الاستعادة إلى حوالي الدقيقتين أو ثلاث دقائق؛ أضف إلى ذلك أنَّني لم أواجه مشاكل مع فقدان البيانات منذ استعمالي لنظام ملفات EXT3. ميزة السجلات الموجودة في EXT3 يمكن تعطيلها وسيعمل نظام الملفات مثل EXT2، لكن سيبقى السجل موجودًا إلا أنه فارغٌ وغير مستعمل. كل ما عليك فعله هو إعادة وصل (remount) القسم باستخدام الأمر mount مع تمرير خيار له لتحديد نوع نظام الملفات إلى EXT2. قد تتمكن من فعل ذلك من سطر الأوامر، اعتمادًا على نظام الملفات الذي تعمل عليه، لكن يمكنك تعديل الراية type في ملف /etc/fstab ثم تعيد إقلاع النظام. لا أنصحك بتاتًا بإعادة وصل نظام ملفات EXT3 كنظام ملفات EXT2 لأن ذلك سيجعل نظام ملفاتك عرضةً لفقدان البيانات وستأخذ عملية استعادته وقتًا أطول. يمكن تحديث نظام ملفات EXT2 موجود مسبقًا إلى EXT3 بإضافة سجل (journal) باستعمال الأمر الآتي: tune2fs -j /dev/sda1 حيث /dev/sda1 هو مُعرِّف القرص والقسم الذي تريد تحديثه؛ احرص على تعديل نوع نظام الملفات عبر تعديل قيمة الراية type في ملف /etc/fstab وإعادة وصل ذاك القسم أو إعادة إقلاع النظام لتأخذ التعديلات مجراها. EXT4 يُحسِّن نظام ملفات EXT4 من الأداء والموثوقية والقدرة التخزينية. فلتحسين الموثوقية (reliability) أضيفت بيانات وصفية وتدقيق لمجموع السجلات (journal checksums)؛ ولتحقيق متطلبات أنظمة المهام الحرجة (mission-critical) فتم تحسين بصمات الوقت لنظام الملفات لجعلها تُخزِّن بدقة تصل إلى النانو ثانية، وحُلَّت مشكلة «عام 2038» حتى عام 2446. تحولت آلية حجز البيانات من كتل ثابتة الحجم إلى امتدادات (extents)، إذ يمكن وصف الامتداد بأنه بداية ونهاية مكان موجود على القرص الصلب، وهذا يجعل من الممكن توصيف ملفات طويلة ومستمرة (فيزيائيًا) في مؤشر فهرسة وحيد، والذي يقلل عدد المؤشرات المطلوبة لوصف مكان تخزين جميع البيانات في الملفات الكبيرة؛ ويُطبِّق نظام ملفات EXT4 استراتيجيات لتوزيع البيانات التي تحرص على تقليل تجزئة الملف قدر المستطاع. يُقلِّل نظام ملفات EXT4 من تجزئة الملفات عبر جعل الملفات المُنشَأة حديثًا منتشرةً على القرص وليست متجمعةً في مكانٍ وحيدٍ في بداية القرص كما كانت تفعل أنظمة الملفات القديمة. تحاول خوازميات حجز مساحة الملفات أن تخزن الملفات بانتظام قدر الإمكان على المجموعات الأسطوانية، وإذا كان من الضرورية تجزئة الملف فستحاول جعل تلك القطع قريبةً من بعضها فيزيائيًا لتقليل زمن التأخير الناتج عن حركة رأس القراءة. هنالك استراتيجيات أخرى تستعمل لحجز مساحة تخزينية أكبر من اللازمة عند إنشاء الملفات الجديدة أو إضافة بيانات إلى ملفات موجودة مسبقًا، وهذا يساعد في زيادة مساحة الملف دون تجزئته إلى أكثر من جزء؛ أضف إلى ذلك أنَّ الملفات الجديدة لا توضع مباشرةً بعد الملفات الموجودة مسبقًا مما يمنع تجزئة الملفات الموجودة مسبقًا. وبوضع مكان التخزين على القرص الفيزيائي جانبًا: يستعمل نظام الملفات EXT4 عدِّة استراتيجيات مثل تأخير حجز المساحة للسماح لنظام الملفات بجمع جميع البيانات التي ستكتب على القرص قبل حجز المساحة التخزينية لها، مما يُحسِّن من احتمال حجز مساحة تخزينية متجاورة أو مستمرة. يمكن أن توصل (mount) أنظمة ملفات EXT القديمة مثل EXT2 و EXT3 كنظام ملفات EXT4 لتحسين الأداء قليلًا، لكن هذا يعني تعطيل بعض من أهم الميزات الجديدة لنظام ملفات EXT4، لذا لا أستحسن فعل ذلك. أصبح نظام ملفات EXT4 افتراضيًا في توزيعة فيدورا بدءًا من الإصدار 14؛ ويمكن تحديث نظام ملفات EXT3 إلى EXT4 باتباع التعليمات الواردة في توثيق فيدورا، لكن لن يكون الأداء ممتازًا بسبب بنى البيانات الوصفية لنظام EXT3 التي ما تزال موجودةً؛ وأفضل طريقة برأيي لتحديث نظام ملفات EXT3 إلى EXT4 هي أخذ نسخة احتياطية لجميع البيانات في القسم الذي تحاول ترقية نظام ملفاته، ثم استخدام الأمر mkfs لإنشاء نظام ملفات EXT4 فارغ في القسم، ثم استعادة جميع البيانات من نسخة احتياطية. inode مؤشر الفهرسة –كما شرحناه سابقًا– هو مكوِّن مهم من البيانات الوصفية في أنظمة EXT، يُظهِر الشكل الآتي العلاقة بين مؤشر الفهرسة وبين البيانات المخزنة على القرص الصلب، وفي هذه الحالة كانت البيانات مجزئة، لذا من غير المرجح أن تشاهد ملفًا موزعًا على كتل بيانات كثيرة، وفي الحقيقة تجزئة الملفات في أنظمة ملفات EXT قليلة جدًا كما سترى في بقية هذا القسم، لذا ستستخدم أغلبية مؤشرات الفهرسة مؤشرًا أو مؤشرين مباشرين إلى البيانات ولن تستعمل أيّة مؤشرات غير مباشرة. لا يحتوي مؤشر الفهرسة على اسم الملف، فالوصول إلى الملف يتم عبر قيود المجلد (directory entry)، وقيمة ذلك المؤشر هي رقم مؤشر الفهرسة، وكل مؤشر فهرسة في نظام الملفات له مُعرِّف ID ذي رقم فريد، لكن يمكن لمؤشرات الفهرسة الموجودة في أقسام أخرى على القرص الفيزيائي نفسه أو على الحاسوب نفسه أن تملك المعرف الفريد ذاته. وهذا ما يؤثر على الوصلات الصلبة (hard links)، لكن هذا النقاش خارج عن نطاق هذا الدرس. يحتوي مؤشر الفهرسة على البيانات الوصفية التابعة للملف، بما في ذلك نوعه والأذونات المسندة إليه وحجمه التخزيني، ويحتوي مؤشر الفهرسة على مساحة لخمسة عشر مؤشرًا التي تصف مكان وطول كتل البيانات الموجودة في قسم البيانات من المجموعة الأسطوانية، ويوفر اثنا عشر مؤشرًا منها وصولًا مباشرًا إلى كتل البيانات ويجب أن تكون كافيةً للتعامل مع معظم الملفات؛ لكن للملفات المجزأة كثيرًا، فمن الضروري الحصول على إمكانيات إضافية على شكل مؤشرات غير مباشرة، ولا تعد هذه المؤشرات على أنها مؤشرات فهرسة (inode)، لذا سأطلق عليها مصطلح «مؤشر» (node) للتفريق بينهما. المؤشر غير المباشر هو كتلة بيانات عادية في نظام الملفات التي تستخدم لوصف البيانات وليس لتخزين البيانات الوصفية، وبالتالي يمكن دعم أكثر من خمس عشرة مدخلةً (entries). فمثلًا، إذا كانت كتلة البيانات بحجم 4 كيلوبايت فيمكنها أن تدعم 512 مؤشرًا غير مباشر ذا 4 بايتات، مما يسمح باستعمال 12 مؤشرًا مباشرًا و 512 مؤشرًا غير مباشر = 524 مؤشرًا للملف الواحد. يجدر بالذكر أنَّ استعمال مؤشرين أو ثلاثة مؤشرات غير مباشرة هو أمرٌ مدعوم، لكن ليس من المرجح أن تصدف هذه الحالة معنا. تجزئة البيانات كانت تجزئة البيانات في أنظمة ملفات الحواسيب القديمة مثل FAT (بمختلف إصداراته) و NTFS مشكلةً كبيرةً تؤدي إلى أداء منخفض للأقراص، وأصبحت عملية إلغاء التجزئة محط أنظار الشركات وانتشرت برمجيات لإلغاء التجزئة تتراوح بين البرمجيات الفعالة جدًا إلى البرمجيات الشكلية. أنظمة الملفات المستعملة في لينكس تستعمل استراتيجيات تساعد في تقليل تجزئة الملفات الموجودة في القرص الصلب وتقلل تأثير التجزئة عندما تحدث. يمكنك استعمال الأمر fsck على أنظمة ملفات EXT للتحقق من حالة تجزئة نظام الملفات الكلية؛ فالمثال الآتي يتفحص مجلد المنزل لجهازي الشخصي، الذي كانت نسبة التجزئة فيه حوالي 1.5% فقط. احرص على تمرير المعامل -n لأنه يمنع fsck من اتخاذ أي إجراء على نظام الملفات التي يتفحصه. fsck -fn /dev/mapper/vg_01-home أجريتُ بعض الحسابات النظرية لتحديد إذا ما كانت عملية إلغاء تجزئة القرص ستسبب في تحسين ملحوظ للأداء؛ وصحيحٌ أنني افترضت بعض الفرضيات، وأخذتُ بيانات أداء القرص من قرص جديد من نوع Westren Digital بسعة 300 غيغابايت ذي زمن تحريك بين المسارات يقدر بقيمة 2 ملي ثانية؛ وكان عدد الملفات في هذا الملف مساويًا لعدد الملفات الموجودة في نظام في اليوم الذي أجريتُ فيه هذه الحسابات، وافترضتُ نسبةً كبيرةً من الملفات المجزئة (20%) التي ستجرى عليها عمليات يوميًا. عدد الملفات الكلي 271,794 نسبة التجزئة 5.00% الانقطاعات 13,590 نسبة الملفات المجزئة التي ستجرى عليها عمليات يوميًا 20% (فرضًا) عدد حركات البحث الإضافية 2,718 متوسط زمن البحث 10.90 ملي ثانية زمن البحث الإضافي اليومي 29.63 ثانية 0.49 دقيقة زمن الانتقال من مسار إلى آخر 2.00 ملي ثانية زمن الانتقال الإضافي اليومي 5.44 ثانية 0.091 دقيقة أجريتُ عمليتَي حساب لزمن البحث الإضافي اليومي، مرةً اعتمادًا على زمن الانتقال من مسار إلى آخر، وهذه هي الحالة الشائعة لأغلبية الملفات بسبب استراتيجيات تخزين الملفات التي تستعملها أنظمة ملفات EXT؛ ومرةً أخذتُ زمن البحث الإضافي اليومي، وبهذا أكون قد أخذت أسوأ حالة بالحسبان. وكما تلاحظ من الجدول السابق، إنَّ أثر التجزئة على أنظمة ملفات EXT الحديثة المستعملة على قرص صلب ذي أداءٍ متواضع هو أثرٌ ضئيل ويهمل لأغلبية حالات الاستخدام. يمكنك أن تضع أرقامًا من نظامك في ورقة عمل (spreadsheet) لترى أثر التجزئة في نظامك على الأداء. وصحيحٌ أنَّ العمليات الحسابية السابقة لا تمثِّل الأداء الفعلي، لكن قد تعطيك نظرة عامة عن التجزئة الموجودة في نظام الملفات عندك وأثرها النظري على أداء النظام. نسبة التجزئة في أغلبية الأقسام عندي تتراوح بين 1.5% إلى 1.6%؛ لكن لدي قسم نسبة تجزئته هي 3.3% لكنه قسمٌ كبيرٌ بسعة 128 غيغا بايت وفيه أقل من 100 ملف ISO حجمها التخزيني كبير جدًا؛ وكان علي توسعة هذا القسم عدِّة مرات على مر الوقت لأنه كان ممتلئًا طوال الوقت. لكن هنالك بعض بيئات العمل التي تتطلب ضمانةً لنسبة تجزئة أقل؛ ويمكن ضبط نظام ملفات EXT من مدير له خبرة ويمكنه تعديل المعاملات لتناسب نمط العمل الملائم. ويمكن فعل ذلك عند إنشاء نظام الملفات أو لاحقًا باستخدام الأمر tune2fs، ويجب أن تُختبَر نتائج كل عملية تعديل، وتُسجَّل النتائج وتُحلَّل للتأكد أنَّ الأداء مثالي في البيئة المستهدفة. وفي أسوأ حالة، التي لا يمكن تحسين الأداء فيها إلى الدرجة المطلوبة، فيمكن أن تكون أنظمة الملفات الأخرى ملائمة لنوع الأعمال المطلوب؛ تذكر أنَّ من الشائع استخدام أكثر من نظام ملفات في حاسوب واحد. بسبب النسبة الضئيلة من التجزئة في أغلبية أنظمة ملفات EXT، فليس من الضروري إجراء عملية إلغاء تجزئة؛ ولا توجد أداء آمنة لإلغاء التجزئة لأنظمة ملفات EXT؛ لكن هنالك عدِّة أدوات تسمح لك بالتحقق من تجزئة ملف معيّن أو تجزئة بقية المساحة الفارغة في نظام الملفات. هنالك أداة باسم e4defrag التي تستطيع إلغاء تجزئة ملف أو مجلد أو نظام ملفات بما تسمح به المساحة الفارغة المتبقية، وكما يوحي اسم هذه الأداة: فهي تعمل على الملفات الموجودة على نظام ملفات EXT4، ولها بعض المحدوديات. إذا كان من الضروري إجراء عملية إلغاء تجزئة كاملة لنظام ملفات EXT4، فهنالك طريقة وحيدة عملية ألا وهي نقل جميع الملفات من نظام الملفات الذي تريد إلغاء تجزئته، وتحرص على حذفها حذفًا تامًا بعد أن تُنسَخ بشكل آمن إلى مكانٍ آخر؛ ومن المستحسن زيادة مساحة القسم إن أمكن ذلك، لتجنب حدوث التجزئة مستقبلًا. يمكنك بعد ذلك أن تنسخ الملفات إلى القسم الجديد؛ يجدر بالذكر أنَّ الطريقة السابقة لا تضمن لك إلغاء التجزئة تمامًا. الخلاصة أنظمة ملفات EXT هي أنظمة الملفات المبدئية في أغلبية توزيعات لينكس لأكثر من عشرين عامًا، فهي تتسم بالثبات والموثوقية والأداء ولا تتطلب صيانة إلا قليلًا. جربتُ عدِّة أنظمة ملفات لكنني عدتُ دومًا إلى استخدام أنظمة ملفات EXT، وكانت أنظمة ملفات EXT تستعمل في جميع الأماكن التي عملتُ فيها التي تستعمل لينكس، ووجدتها مناسبةً لأغلبية الاستعمالات. الخلاصة أنَّ نظام ملفات EXT4 مناسب لأغلبية أنظمة لينكس إلا إذا كان هنالك سببٌ قويٌ يدفعنا لاستخدام نظام ملفات آخر. ترجمة –وبتصرّف– للمقال An introduction to Linux’s EXT4 filesystemلصاحبه David Both1 نقطة
-
ماذا تقصد بتحميل الجافا؟ إذا كنت تقصد تحميل حزمة الجافا لتشغيل البرامج المبنية على الجافا فعليك بتحميل حزمة JRE (Java SE Runtime Environment) أما إذا كنت تقصد تحميل حزمة الجافا للتطوير والبرمجة بلغة الجافا فعليك بتحميل الحزمة JDK (Java Development Kit) والتي تحتوي ضمنيا حزمة JRE يمكنك تحميل أي الحزم تشاء من هذا الرابط1 نقطة
-
نفس مشكلتك صديقي, وقد تم تجيد حسابين لي فيهما 97$ يريدون هوية أتمنى لو تتعامل حسوب بال #بتكوين لأنه الوحيد غير المحظور عندنا في سوريا و لدينا العديد من الاشخاص ذوي المهارة لا يستطيعون العمل على الانترنت.1 نقطة
-
أُنشئت لغة البرمجة Go لإنجاز العمل بسهولة، وهي ليست ضمن الاتجاهات الحديثة في علم الحاسوب، ولكنها أحدث وسيلة برمجية لحل المشاكل في الواقع بسرعة. تمتلك لغة Go مفاهيم مُشابهة للغات البرمجة الإجبارية Imperative Languages بالإضافة لثبات أنواع البيانات Static typing، وتعدّ كذلك سريعة في البرمجة Compilation وسريعة في التشغيل والتنفيذ، ومتوافقة مع المعالجات ذات الأنوية المتعددة بهدف الاستفادة منها بسهولة، كما أنها تمتلك الكثير من المزايا التي تساعد في البرمجة للأنظمة الكبيرة والمعقَّدة. تتمتع لغة Go بمكتبة معيارية عظيمة ومجتمع برمجي متحمس ونشط. في هذا المقال، سوف نشرح أساسيات لغة Go بطريقة سهلة وبسيطة، ونُعرج على بعض المفاهيم المهمة. الشفرة البرمجية الموجودة في هذا المقال مترابطة، ولكننا قسّمناها إلى أجزاء ووضعنا عناوين لهذه الأجزاء، كما توجد الكثير من التعليقات المباشرة على الشفرة البرمجية. المواضيع الأساسية التي يغطيها هذا المقال كالتالي: كتابة التعليقات. المكتبات واستيرادها. الدوال. أنواع البيانات. القيم الراجعة المسماة. المتغيرات والذاكرة. جمل التحكم. توليد الدوال. التنفيذ المؤجل. الواجهات. المُدخلات المتعددة. معالجة الأخطاء. التنفيذ المتزامن. الويب كتابة التعليقات لكتابة تعليق من سطر واحد // single line comment لكتابة تعليق بأكثر من سطر /* Multi- line comment */ المكتبات واستيرادها يبدأ كل ملف مصدري بالكلمة المفتاحية packag. تُستخدَم الكلمة المفتاحية main لتعريف الملف كملف تشغيلي وليس مكتبة. package main لاستيراد حزمة مكتبية في الملف نستخدم التعليمة Import بالطريقة التالية: import ( "fmt" // حزمة في المكتبة المعيارية للغة "io/ioutil" // تطبق دوال إدخال وإخراج m "math" //نستخدم الحرف m لاختصار اسم مكتبة الدوال الرياضية "net/http" // خادوم ويب "os" // دوال على مستوى نظام التشغيل مثل التعامل مع الملفات "strconv" // تحويلات نصية ) الدوال Functions تُعرَّف الدوال باستخدام كلمة func متبوعة باسم الدالة. تعدّ الدالة main خاصة، وهي المدخل للملف التنفيذي للبرنامج (لغة Go تستخدم الأقواس المزخرفة {} لتحديد الأجزاء/الكتل البرمجية). func main() { // لإخراج نص على وحدة الإخراج (العرض) الرئيسية stdout نستخدم الدالة Println الموجودة في مكتبة fmt fmt.Println("Hello world!") // استدعاء دالة من نفس الحزمة الحالية beyondHello() } تحتاج الدوال لأقواس تستقبل المعاملات Parameters، وحتى في عدم وجود معاملات فإن الأقواس مطلوبة. func beyondHello() { // تعريف متغير (لا بد من تعريف المتغير قبل استخدامه) var x int // إعطاء قيمة للمتغير x = 3 // التعريف القصير باستخدام := ويشمل تعريف المتغير, وتحديد نوعه وإعطاءه قيمة y := 4 // دالة ترجع قيمتين منفصلتين sum, prod := learnMultiple(x, y) // طباعة وإخراج بشكل بسيط ومباشر fmt.Println("sum:", sum, "prod:", prod) learnTypes() } يمكن أن توجد في تعريف الدوال معاملات وقيم مرجعة متعددة، فمثلا تأخذ الدالة learnMultiple أدناه معاملين x و y وترجع قيمتين sum و prod من نوع عدد صحيح Int. func learnMultiple(x, y int) (sum, prod int) { // نفصل بين القيم المُرجعة بفاصلة عادية return x + y, x * y } أنواع البيانات Data Types func learnTypes() { //التعريفات القصيرة عادة تؤدي الغرض المطلوب // تعريف متغير نصي باستخدام علامة التنصيص المزدوجة str := "Learn Go!" // تعريف متغير نصي باستخدام علامة التنصيص المنفردة s2 := `A "raw" string literal can include line breaks.` // تعريف متغير من نوع rune وهو عبارة عن مسمى آخر لنوع int32 ويحتوي المتغير من هذا النوع على يونيكود g := 'Σ' // تعريف عدد عشري Float f := 3.14195 // تعريف عدد مركب (عقدي)Complex c := 3 + 4i // تعريف المتغيرات باستخدام var var u uint = 7 //عدد طبيعي (صحيح موجب) var pi float32 = 22. / 7 //عدد عشري من 32 بت // طريقة التحويل باستخدام التعريف القصير (byte تعتبر مسمى اخر لنوع uint8) n := byte('\n') // المصفوفات لها حجم محدد وثابت في وقت الترجمة // تعريف مصفوفة من نوع int بحجم 4 عناصر وبقيمة أولية تساوي صفر var a4 [4]int // تعريف مصفوفة بحجم 3 عناصر بالقيم 3 و 1 و 5 a3 := [...]int{3, 1, 5} يقدّم Go نوع بيانات يُسمّى الشرائح Slices. الشرائح (Slices) لها حجم ديناميكي. المصفوفات والشرائح لها مميزات ولكن حالات الاستخدام للشرائح شائعة أكثر. تعرّف التعليمة التالية شريحة من النوع int // لاحظ الفرق بين تعريف المصفوفة والشريحة، حيث عند تعريف الشريحة لا يوجد رقم يحدد حجمها s3 := []int{4, 5, 9} //تعريف شريحة من نوع int بأربعة عناصر بقيم صفرية s4 := make([]int, 4) // تعريف فقط، ولا يوجد تحديد var d2 [][]float64 // طريقة تحويل النوع من نص لشريحة bs := []byte("a slice") بحكم طبيعة الشرائح الديناميكية، فإنه من الممكن إضافة عناصر جديدة للشريحة وذلك يتم باستخدام الدالة المضمنة append. نمرر أولا الشريحة التي نريد الإضافة عليها ومن ثم العناصر التي نريد إضافتها، أنظر للمثال بالأسفل. s := []int{1, 2, 3} s = append(s, 4, 5, 6) // ستُطبَع شريحة بالمحتويات التالية [1 2 3 4 5 6] fmt.Println(s) لإضافة شريحة إلى شريحة أخرى نمرر الشريحتين للدالة بدلا من تمرير عناصر منفردة، ونتبع الشريحة الثانية بثلاث نقاط كما في المثال التالي. s = append(s, []int{7, 8, 9}...) // سيتم طباعة شريحة بالمحتويات التالية [1 2 3 4 5 6 7 8 9] fmt.Println(s) تعرّف التعليمة التالية متغيرين p وq ليكونا مؤشّريْن Pointers على متغيّرين من نوع int يحويان قيمتين مُرجعتيْن من الدالة learnMemory: p, q := learnMemory() عندما تسبق النجمة مؤشرا فإن ذلك يعني قيمة المتغير الذي يحيل إليه المؤشر، أي في المثال التالي قيمتا المتغيريْن اللذيْن ترجعهما الدالة learnMemory: fmt.Println(*p, *q) الخرائط Maps في Go هي مصفوفات ترابطية يمكن التعديل عليها ديناميكيا وهي تشابه نوع القاموس او الهاش في اللغات الأخرى. /* هنا نعرف خريطة يكون مفتاحها من نوع نصي، وقيم العناصر رقمية. */ m := map[string]int{"three": 3, "four": 4} m["one"] = 1 تعدّ لغة Go المتغيرات غير المستخدمة خطأ. التسطير السفلي بالطريقة التالية يجعلك تستخدم المتغير ولكن تتجاهل قيمته في نفس الوقت: _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs تُستخدَم هذه الطريقة عادة لتجاهل قيمة راجعة من دالة، فمثلا تستطيع تجاهل رقم الخطأ الراجع من دالة إنشاء الملف os.Create والذي يفيد بأن الملف موجود مسبقا، وتفترض دائما أن الملف شيُنشَأ: file, _ := os.Create("output.txt") fmt.Fprint(file, "بالمناسبة، هذه هي دالة الكتابة في ملف") file.Close() fmt.Println(s, c, a4, s3, d2, m) learnFlowControl() } القيم الراجعة المسماة Named return values خلافا للغات الأخرى، من الممكن أن تكون للدوال قيم راجعة مسماة. حيث يتم إعطاء اسم للقيمة الراجعة من الدالة وذلك في سطر تعريف الدالة، وهذه الميزة تتيح الرجوع بسهولة من أي نقطة في الدالة بالإضافة لاستخدام كلمة return فقط دون ذكر شيء بعدها: func learnNamedReturns(x, y int) (z int) { z = x * y //هنا كتبنا كلمة return فقط وضمنيا نعني إعادة قيمة المتغير z return } ملاحظة: تعتمد لغة Go كثيرا على جمع الموارد غير المستخدمة Garbage collection. توجد في Go مؤشّرات لكن بدون إجراء عمليات حسابية عليها (تستطيع الخطأ في استخدام مؤشر فارغ ولكن لا تستطيع الزيادة على المؤشر). المتغيرات والذاكرة المتغيّران p وq أدناه هما مؤشّران على النوع int ويمثّلان قيمتين راجعتين في الدالة. يكون المؤشّران عند تعريفهما فارغين؛ إلا أن استخدام الدالة المُضمّنة new يجعل قيمة المتغيّر العددي الذي يحيل إليه المؤشّرp مساوية للصفر، وبالتالي يأخذ حيزا من الذاكرة؛ أي أن المؤشر p لم يعد فارغا. func learnMemory() (p, q *int) { p = new(int) // تعريف شريحة من 20 عنصر كوحدة واحدة في الذاكرة s := make([]int, 20) // إعطاء قيمة لأحد العناصر s[3] = 7 // تعريف متغير جديد محلي على مستوى الدالة r := -2 // إرجاع قيمتين من الدالة هما عبارة عن عناوين الذاكرة للمتغيرات s و r على الترتيب. return &s[3], &r } func expensiveComputation() float64 { return m.Exp(10) } جمل التحكم تتطلّب الجمل الشرطية وجود أقواس مزخرفة ولا تتطلب وجود أقواس هلالية. func learnFlowControl() { if true { fmt.Println("told ya") } if false { // Pout. } else { // Gloat. } نستخدم جملة switch في حال حاجتنا لكتابة أكثر من جملة شرطية متتابعة. x := 42.0 switch x { case 0: case 1: case 42: case 43: default: } كما الجملة الشرطية، فإن جملة for لا تأخذ أقواس هلالية.المتغيرات المعرفة في جملة for تكون مرئية على مستوى الجملة. for x := 0; x < 3; x++ { fmt.Println("iteration", x) } جملة for هي جملة التكرار الوحيدة في لغة Go ولها شكل آخر بالطريقة التالية: for { // تكرار لا نهائي // نستطيع استخدام break لوقف التكرار break // نستطيع استخدام continue للذهاب للتكرار القادم continue } تستطيع استخدام range للمرور على عناصر مصفوفة، شريحة، نص، خريطة أو قناة Channel تـعيد range قيمة واحدة عند استخدام قناة، وقيمتين عند استخدام شريحة أو مصفوفة أو نص أو خريطة. // مثال: for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} { // نطبع قيمة كل عنصر في الخريطة fmt.Printf("key=%s, value=%d\n", key, value) } استخدم علامة التسطير السفلي مقابل القيمة الراجعة إذا كنت تريد الحصول على القيمة فقط، كالتالي: for _, name := range []string{"Bob", "Bill", "Joe"} { fmt.Printf("Hello, %s\n", name) } نستطيع استخدام التعريف القصير مع الجملة الشرطية بحيث يُعرف متغير ومن ثم يُفحَص في جملة الشرط. نعرّف في ما يلي متغيرًا y ونقوم بإعطائه قيمة ومن ثم نقوم بوضع شرط الجملة بحيث يتم فصلهما ب فاصلة منقوطة. if y := expensiveComputation(); y > x { x = y } نستطيع تعريف دوال وهمية anonymous مباشرة في الشفرة البرمجية” xBig := func() bool { // عرّفنا المتغيّر x التالي قبل جملة switch السابقة return x > 10000 } x = 99999 // ترجع الدالة xBig الآن القيمة true fmt.Println("xBig:", xBig()) x = 1.3e3 // بعد تعديل قيمة x إلى 1.3e3 التي تساوي 1300 (أي أكبر من 1000) فإن الدالة xBig ترجع false fmt.Println("xBig:", xBig()) بالإضافة لما سبق، فإنه من الممكن تعريف الدالة الوهمية واستدعائها في نفس السطروتمريرها في معطى لدالة أخرى بشرط أن يتم استدعاؤها مباشرة وأن يكون نوع النتيجة متوافقا مع ما هو متوقع في معطى الدالة. fmt.Println("Add + double two numbers: ", func(a, b int) int { return (a + b) * 2 }(10, 2)) goto love love: learnFunctionFactory() // دالة ترجع دالة learnDefer() // التأجيل learnInterfaces() // التعامل مع الواجهات } توليد الدوال نستطيع التعامل مع الدوال ككائنات منفصلة، فمثلا من الممكن أن نقوم بإنشاء دالة وتكون القيمة الراجعة منها دالة أخرى. func learnFunctionFactory() { تعدّ الطريقتان التاليتان في طباعة الجملة متماثلتين، إلا أن الطريقة الثانية أوضح ومقروءة أكثر وهي الشائعة. fmt.Println(sentenceFactory("summer")("A beautiful", "day!")) d := sentenceFactory("summer") fmt.Println(d("A beautiful", "day!")) fmt.Println(d("A lazy", "afternoon!")) } المزخرفات Decorators موجودة في بعض لغات البرمجة، وموجودة بنفس المفهوم في لغة Go بحيث نستطيع تمرير معطيات إلى الدوال. func sentenceFactory(mystring string) func(before, after string) string { return func(before, after string) string { return fmt.Sprintf("%s %s %s", before, mystring, after) } } التنفيذ المؤجل نستطيع استخدام خاصية التأجيل في الدوال بحيث ننفّذ إجراءً قبل إعادة القيمة المرجعة، وفي حال كتابة أكثر من إجراء، فإن تنفيذ هذه الإجراءات يكون بطريقة عكسية، كما في وظيفة learnDefer: func learnDefer() (ok bool) { // تُنفَّذ التعليمات المؤجلة قبل أن ترجع الوظيفة النتيجة. defer fmt.Println("deferred statements execute in reverse (LIFO) order.") defer fmt.Println("\nThis line is being printed first because") // يُستخدَم تأجيل التنفيذ عادة لإغلاق ملف بعد فتحه. return true } الواجهات Interfaces نعرّف في ما يلي دالة باسم Stringer تحتوي على دالة واحدة باسم String ؛ ثم نعرّف هيكلا Struct من خانتين نوع int باسم x وy. type Stringer interface { String() string } type pair struct { x, y int } نعرّف في ما يلي دالة String على النوع pair، ليصبح pair تطبيقا Implementation للواجهة Stringer. يُسمى المتغيّرp أدناه بالمُستقبل. لاحظ كيفية الوصول لحقول الهيكل pair وذلك باستخدام اسم الهيكل متبوعا بنقطة ثم اسم الحقل. func (p pair) String() string { return fmt.Sprintf("(%d, %d)", p.x, p.y) } تُستخدَم الأقواس الهلالية لإنشاء عنصر من الهياكل Structs. نستخدم التعريف القصير (باستخدام := ) في المثال أدناه لإنشاء متغير باسم p وتحديد نوعه بالهيكل pair . func learnInterfaces() { p := pair{3, 4} // نستدعي الدالة String الخاصة بالنوع pair fmt.Println(p.String()) // نُعرف متغيرًا باسم i من نوع الواجهة المعرفة سابقا Stringer var i Stringer // هذه المساواة صحيحة، لأن pair تُطبق Stringer i = p /* نستدعي الدالة String الخاصة بالمتغير i من نوع Stringer ونحصُل على نفس النتيجة السابقة */ fmt.Println(i.String()) /* عند تمرير المتغيرات السابقة مباشرةإلى دوال الحزمة fmt الخاصة بالطباعة والإخراج، فإن هذه الدوال تستدعي الدالة String لطباعة التمثيل الخاص بالمتغير. */ // يعطي السطران التاليان نفس النتيجة السابقة للطباعة fmt.Println(p) fmt.Println(i) learnVariadicParams("great", "learning", "here!") } المدخلات المتعددة من الممكن أن نمرر معطيات متغيرة العدد للدوال. func learnVariadicParams(myStrings ...interface{}) { /* تمرّ جملة التكرار التالية على عناصر المعطيات المدخلة للدالة. التسطير السفلي هنا نعني به تجاهل المؤشر الخاص بالعنصر الذي نمر عليه. */ for _, param := range myStrings { fmt.Println("param:", param) } /* هنا نمرّر مدخلات الدالة ذات العدد المتغير كمعامل لدالة أخرى (للدالة Sprintln) */ fmt.Println("params:", fmt.Sprintln(myStrings...)) learnErrorHandling() } معالجة الأخطاء Errors Handling تُستخدَم الكلمة المفتاحية “ok,” لمعرفة صحة عبارة من عدمها. في حال حدوث خطأ فيمكننا استخدام err لمعرفة تفاصيل أكثر عن الخطأ. func learnErrorHandling() { m := map[int]string{3: "three", 4: "four"} if x, ok := m[1]; !ok { // ok هنا ستكون false لأن رقم 1 غير موجود في الخريطة m fmt.Println("no one there") } else { // x ستكون القيمة الموجودة في map fmt.Print(x) } /* هنا نحاول أن نقوم بعمل تحويل لقيمة نصية إلى عدد مما سينتج عنه خطأ, ونقوم بطباعة تفاصيل الخطأ في حالة أن err ليست nil */ if _, err := strconv.Atoi("non-int"); err != nil { fmt.Println(err) } learnConcurrency() } // المعطى c هنا من نوع قناة، وهو كائن لتأمين الاتصالات المتزامنة func inc(i int, c chan int) { // عندما يظهر عنصر من نوع قناة على الشمال، فإن العملية <- تعني إرسال c <- i + 1 } التنفيذ المتزامن Concurrency نستخدم الدالة السابقة لعمل إضافة عددية على بعض الأرقام بالتزامن. نستخدم make كما فعلنا في بداية المقال لإنشاء متغير دون تحديد قيمة له. func learnConcurrency() { // هنا نقوم بإنشاء متغير من نوع قناة وباسم c c := make(chan int) /* نبدأ بإنشاء ثلاثة دوال متزامنة للغة Go. الأعداد سيتم الزيادة عليهابالتزامن (وبالتوازي في حال كان الجهاز مُهيئاً لذلك). */ // كافة الإرسالات ستتجه لنفس القناة // كلمة go هنا تعني بدء دالة أو وظيفة جديدة go inc(0, c) go inc(10, c) go inc(-805, c) // ثم نقوم بعمل ثلاثة قراءات من نفس القناة وطباعة النتائج. /* لاحظ أنه لا يوجد تحديد ترتيب لوصول القراءات من القناة، ولاحظ أيضا أنه عند ظهور القناة على يمين العملية <- فهذا يعني أننا نقوم بقراءة واستقبال من القناة. */ fmt.Println(<-c, <-c, <-c) // قناة جديدة تحتوي على نص cs := make(chan string) // قناة تحتوي على قنوات نصية ccs := make(chan chan string) // إرسال قيمة 84 إلى القناة c go func() { c <- 84 }() // إرسال كلمة wordy للقناة cs go func() { cs <- "wordy" }() /* جملة Select تشبه جملة switch ولكنها في كل حالة تحتوي على عملية خاصة بقناة جاهزة للتواصل معها. */ select { // القيمة المُستلمة من القناة من الممكن أن تُحفظ في متغير. case i := <-c: fmt.Printf("it's a %T", i) case <-cs: fmt.Println("it's a string") // قناة فارغة ولكنها جاهزة للتواصل case <-ccs: fmt.Println("didn't happen.") } // برمجة الويب learnWebProgramming() } الويب نستطيع بدء خادوم ويب باستخدام دالة واحدة من حزمة http. نمرّر في المعامل الأول للدالة ListenAndServe عنوان TCP للاستماع له، والمعامل الثاني واجهة عبارة عن معالج http. func learnWebProgramming() { go func() { err := http.ListenAndServe(":8080", pair{}) // نطبع الأخطاء في حال وجودها. fmt.Println(err) }() requestServer() } // اجعل pair معالج http وذلك بواسطة تطبيق دالته الوحيدة المسماة ServeHTTP func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) { // تتبع الدالة Write للحزمة http.ResponseWriter ونستخدمها لإرجاع رد لطلب http w.Write([]byte("You learned Go in Y minutes!")) } func requestServer() { resp, err := http.Get("http://localhost:8080") fmt.Println(err) defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) fmt.Printf("\nWebserver said: `%s`", string(body)) } ترجمة – بتصرّف – للمقال Learn X in Y minutes Where X=Go.1 نقطة