چطور با توجه به جزئیات، شرلوک هولمز باگ‌یابی شویم

اگر بخواهید چیزی را پیدا کنید، در قدم اول باید بدانید که آن چیز دقیقاً چیست. درست مثل کارآگاه‌ها، متخصصان Testing هم وقتی دنبال باگ می‌گردند، یک سری تحقیق و تفحصات انجام می‌دهند. هر نوع باگی ویژگی‌های منحصر به فرد خودش را دارد. در تیم‌های توسعه نرم‌افزار، یک Software Tester باید همه این ویژگی‌های خاص باگ‌ها را بداند تا بتواند «مجرم» را شناسایی کند!

بیایید با چند نوع از باگ‌ها شروع کنیم که معمولاً شناسایی کردنشان سخت است اما رواج بسیار زیادی دارند:

باگ کارکردی (Functional Bug)

این باگ را وقتی می‌توانیم پیدا کنیم که همه کارکردهای سیستم را بررسی کرده، و مطمئن شویم که هرکدام همان کاری را می‌کنند که باید بکنند. اگر یک Function کار عجیب و غریبی بکند که در لیست کارهای مورد نیاز نبوده، این یک باگ محسوب می‌شود. مثال بزنم؛ فرض کنید دکمه‌ای در اپلیکیشن هست که قرار بوده پنجره A را باز کند؛ اما در عوض، این دکمه یا پنجره B را باز می‌کند یا اینکه کلا هیچ چیزی را باز نمی‌کند. این یک باگ کارکردی است.

اگر پیش‌نیازهای عملیاتی (Functional Requirements) وجود نداشته باشد، پیدا کردن این باگ سخت‌تر می‌شود. در چنین حالتی داشتن تجربه قبلی کار با یک نرم‌افزار مشابه، خیلی به کار می‌آید. یک راهکار دیگر برای پیدا کردن این باگ‌ها هم این است که تست‌های اکتشافی (Exploratory Testing) انجام دهید.

باگ رابط کاربری (User Interface Bug)

اگر همه موکاپ‌های صفحات نرم‌افزار را داشته باشید، پیدا کردن باگ‌های UI کار راحتی است. کل کاری که باید بکنید این است که مکان، شکل، رنگ و دیگر ویژگی‌های عناصر بصری را با موکاپ مقایسه کنید.

یک راه دیگر هم این است که همراه با موکاپ‌ها یا به جای آنها، یک سری دستورالعمل‌های دیزاین تحویل بگیرید. این دستورالعمل‌ها معمولاً استایل‌ها و عناصر دیگر را در حالت‌های مختلفشان توصیف می‌کنند؛ مثلا اینکه رنگ لینک در حالت اولیه، وقتی ماوس رویش هست، و بعد از کلیک کردن چه تفاوتی می‌کند.

اگر هیچگونه مستندسازی (Documentation) برای دیزاین انجام نشده، نگران نباشید. فقط با بررسی نرم‌افزار هم می‌شود بیشتر باگ‌های UI را پیدا کرد. دنبال خرابی Layout، بلوک‌ها (Blocks) یا المان‌های (Elements) روی هم افتاده، متن خارج از بلوک، و هر عنصر دیگری باشید که سر جایش نیست یا کلا ناپدید شده است. در حین پروسه باگ‌یابی، به زودی متوجه خواهید شد که اغلب باگ‌های UI وقت گشتن به دنبال باگ‌های کارکردی خودشان را نشان می‌دهند.

باگ‌های محلی‌سازی (Localization Bug)

پیدا کردن باگ‌های محلی‌سازی فقط وقتی لازم می‌شود که نرم‌افزارتان چند زبان مختلف را پشتیبانی کند، و/یا زمانی که قرار باشد افرادی از منطقه‌های زمانی (time zone) مختلف از آن استفاده کنند.

اولین چیزی که باید چک کنید، این است که آیا زبان‌های مختلف دارند به یک اندازه درست کار می‌کنند؟ متن همه المان‌های سیستم باید ترجمه شود. مستند‌سازی مفصل اینجا به کار می‌آید، اما اگر آن را نداشته باشید هم می‌توانید باگ‌ها را شکار کنید. باید بعد از اینکه زبان پیش‌فرض را تغییر دادید، همه المان‌ها را بررسی کنید. اگر بعضی از آنها ترجمه نشده‌ بودند، یک باگ دارید. در این مرحله از کار ممکن است بعضی باگ‌های UI را هم پیدا کنید؛ چون کلمات و عبارت‌های یکسان در زبان‌های مختلف ممکن است طولانی‌تر یا کوتاه‌تر باشند. در نتیجه متن ممکن است از بلوک بیرون بزند و یا اینکه کلا آن را خراب کند.

بسته به این که نرم‌افزارتان از چه نوعی است، ممکن است لازم باشد نحوه نمایش داده شدن زمان را هم چک کنید. به ترتیب نمایش داده شدن سال-ماه-روز و ساعت-دقیقه دقت کنید، چرا که ممکن است کشورهای مختلف در این ترتیب‌ها با هم فرق داشته باشند. بررسی کنید که نمایشگر ساعت با منطقه زمانی کشور مورد نظر تطابق داشته باشد. اگر قرار است امکان تغییر واحد پولی متناسب با کشور کاربر هم وجود داشته باشد، باید این امکان را هم چک کنید تا ببینید درست کار می‌کند یا نه.

باگ کاربردپذیری (Usability Bug)

اگر استفاده از نرم‌افزار راحت نباشد، احتمالا هیچ کس از آن خوشش نمی‌آید. چنین نرم‌‌افزاری هرگز معروف نخواهد شد. بنابراین باید به باگ‌های کاربردپذیری توجه ویژه‌ای داشته باشید.

اگر پیدا کردن یک Function (مثلا دکمه ثبت نام) برای کاربر خیلی طول بکشد، این قطعاً یک باگ کاربردپذیری است. رنگ‌های نامناسب هم باگ محسوب می‌شوند؛ مثلا وقتی که به خاطر زیادی روشن بودن رنگ بک‌گراند، کاربر نتواند متن را به خوبی ببیند، چشم‌هایش درد بگیرد، و نتواند به مدت طولانی از اپلیکیشن استفاده کند. یک باگ دیگر هم که خیلی هم پیش می‌آید، دکمه‌هایی هستند که کارکردشان برای کاربر دقیقا مشخص نیست: مثلا هیچ راهنمایی برایشان نشان داده نمی‌شود، تصویر آیکون معلوم نیست به چه چیزی اشاره دارد، و یا اینکه اسم آیکون کارکردش را دقیق بیان نمی‌کند.

در ادامه لیست، می‌خواهیم با باگ‌هایی آشنا شویم که شاید در اینترنت یا کتاب‌ها توضیح درست و حسابی در مورد آنها پیدا نشود؛ اما این به این معنی نیست که وجود ندارند:

باگ ادغامی (Integration Bug)

ادغام Componentهای نرم‌افزار فقط منحصر به سیستم‌های پیچیده نیست، بلکه در وبسایتی که خوب طراحی شده باشد هم انجام می‌شود.

اگر اطلاعات به خوبی از یک Component به دیگری منتقل نشود، این یک باگ است. مثال‌های زیادی برای چنین مسئله‌ای می‌شود زد.

مثلا یک وبسایت را تصور کنید که در آن صفحه A، اطلاعات B را دارد که قرار بوده به صفحه C منقل شوند. اگر اطلاعات B با اطلاعات موجود در صفحه C یکی نباشد، این یک باگ ادغامی است.

حالا یک سیستم بزرگ ERP (برنامه‌ریزی منابع سازمانی) را در نظر بگیرید که در آن Componentهای بسیاری با هم ادغام شده‌اند. فرض کنید در این سیستم یک قرارداد می‌سازیم و پروفایل فردی که قرارداد به او مربوط است را انتخاب می‌کنیم. اگر پروفایلی در سیستم وجود دارد ولی به طور خودکار وارد قرارداد نمی‌شود، این یک باگ است.

باگ آپدیت سیستم (System Update Bug)

به‌روزرسانی سیستم، بخش جدایی‌ناپذیر نرم‌افزارهای مدرن است. در این آپدیت‌ها معمولا چند Function جدید ارائه شده و چند باگ مهم رفع می‌شود، اما نکته اینجاست که ممکن است در خود فرآیند آپدیت هم باگی وجود داشته باشد. پیدا کردن این باگ‌ها خیلی سخت است، اما رایج‌ترین آنها معمولاً باعث می‌شوند کاربر همه تنظیماتی که انجام داده را از دست بدهد و یا اینکه کلا از حساب کاربری‌اش بیرون انداخته شود.

باگ صوتی (Audio Bug)

هر اپلیکیشنی صدا ندارد، اما آن اپلیکیشن‌هایی که نوتیفیکیشن می‌دهند یا صدا یکی از Functionهای اصلی‌شان است باید کاملاً از نظر صوتی چک شوند.

اولین چیزی که باید بررسی کنید این است که آیا اصلاً برنامه صدایی تولید می‌کند؟ اگر جواب مثبت است، باید مطمئن شوید که کیفیت صدا خوب است و وقفه یا خللی در وسط صداها پیش نمی‌آید. چک کردن شدت صدا (volume) را هم از یاد نبرید. حتماً بررسی کنید که آیا شدت صدای پیش‌فرض همانی است که قرار بوده باشد، و اینکه آیا بالا و پایین کردن شدت صدا آن را واقعا تغییر می‌دهد یا خیر.

باگ‌های Texture و Objectهای سه بعدی

این باگ در بازی‌های سه بعدی مثل MMORPG خیلی شایع است. بعضی وقت‌ها این نوع باگ‌ها را به سختی می‌شود پیدا کرد، زیرا ممکن است از نظر بصری قابل تشخیص نباشند. برای شکار آنها باید اول تفاوت بین باگ Texture و باگ Objectهای سه بعدی را بدانیم.

بیایید اول از باگ‌های سه بعدی شروع کنیم. مثلاً ممکن است شخصیت بازی بعد از انجام یک کار بخصوص یا رفتن به یک مکان خاص، ناگهان ناپدید شود. این اتفاق در نتیجه ناپایداری‌ها و Aliasهای ضعیف Objectها در این وضعیت/مکان بخصوص اتفاق می‌افتد. وجود textureهای روی هم ممکن است باعث شود که از این باگ غافل شوید. یک مثال دیگر برای این باگ، حالتی است که شخصیت بازی در یک جایی گیر افتاده، و Object‌هایی که سد راهش شده‌اند نمی‌گذارند از آنجا خارج شود.

از طرفی Texture صرفاً عکسی است که روی Object گذاشته می‌شود. اگر یک مانع نامرئی باعث شود که شخصیت بازی نتواند جلو برود، این یعنی این که آن Object دارای Texture نیست. بعضی وقت‌ها هم Texture هست، اما با Object مطابقت نمی‌کند.

باگ محتوا (Content Bug)

معمولاً این تیم کپی‌رایتینگ یا ویراستاری هستند که محتوای سایت را چک می‌کنند، زیرا آنها می‌دانند که دقیقاً چه مطلبی آنجا گذاشته شده است. با این حال، بعضی باگ‌های محتوا واضح‌تر از این هستند که نادیده گرفته شوند؛ مثلاً اشتباه شدن عنوان یا اسم شرکت. فقدان عکس یا لینک‌های اشتباه هم باگ محتوا محسوب می‌شوند.

در نهایت، بیایید با چند باگ نرم‌افزاری آشنا شویم که شاید مثل باگ‌های قبلی واضح و مشخص نباشند:

هایزن‌باگ (Heisenbug)

اسم این باگ از هایزن‌برگ (Heisenberg) می‌آید؛ یعنی‌کاشف اصل عدم قطعیت در مکانیک کوانتوم. هایزن‌باگ به آن خطاهایی اشاره دارد که مثلا وقت اجرا شدن نرم‌افزار در IDE دیده می‌شوند، اما وقتی برنامه با Debugger اجرا شود اثری از آنها نیست.

تصویر از: simonb.com

بورباگ (Bohrbug)

نام این باگ از مدل اتمی بور (Bohr) گرفته شده است. برخلاف هایزن‌باگ، بورباگ هر بار که یک شرایط بخصوصی پیش بیاید خودش را نشان می‌دهد. اما به عقب برگشتن در سیر وقایع و پیدا کردن عامل ایجاد کننده آن تقریباً غیرممکن است.

مندل‌باگ (Mandelbug)

این باگ به نام بنوا مندلبرو (Benoit Mandelbrot) نام‌گذاری شده است که پیشرفت‌های عظیمی در حیطه مطالعه فراکتال‌ها ایجاد کرد. مندل‌باگ خطایی است با دلیلی عمیقاً پیچیده و مبهم، آنقدر که این دلیل به نظر غیر منطقی و غیر قابل توضیح می‌رسد (دقیقاً «به نظر می‌رسد»). این باگ ممکن است به خاطر واکنش کند سیستم اتفاق بیفتد. یک نمونه از مندل‌باگ، خطایی هست که رخ داده، اما شما خیلی بعدتر از رخ دادنش از آن باخبر می‌شوید و برای همین پیدا کردن دلیل مشکل برایتان خیلی سخت می‌شود.

شرودین‌باگ (Schrödinbug)

اسم این باگ از آزمایش معروف گربه شرودینگر (Schrödinger) گرفته شده است. تصور کنید که برنامه‌ای دارید و این برنامه به خوبی دارد کار می‌کند. شما تصمیم می‌گیرید نگاهی به کد برنامه بیندازید. وقتی این کار را می‌کنید می‌بینید کد برنامه طوری است که قاعدتاً اصلاً نباید کار می‌کرده. از همان لحظه‌ای که این را می‌فهمید، برنامه از کار می‌افتد! در نهایت وقتی بلاخره کد را اصلاح کردید، برنامه دوباره شروع به کار می‌کند. به نظر غیرممکن می‌رسد، اما واقعیت این است که در عالم واقع چنین باگ‌هایی خیلی زیاد پیش می‌آیند.

ترجمه‌ای از:

How to Become the Sherlock Holmes of Bug Searching: Concentration on the Details By Andrew Smith @ DZone

کوئرامگ یک مجله تخصصی برای توسعه‌دهندگان است که هر هفته با مطلب‌هایی در زمینه تکنولوژی، رشد فردی و آینده برنامه‌نویسی به‌روزرسانی می‌شود. با عضویت در این خبرنامه، هر دو هفته یک بار خلاصه‌ای از جذاب‌ترین مطلب‌های کوئرامگ را در ایمیل خود دریافت کنید!

نوشته چطور با توجه به جزئیات، شرلوک هولمز باگ‌یابی شویم اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

اولین تجربه برنامه نویسی با کاتلین

یکی از ویژگی های من که هم خوبه هم بد این که دوست دارم همه چیز تست کنم خوب قاعدتا دنیای کامپیوتر و برنامه نویسی هم از  .این قاعده مثتسنی نیست

مدتی است زبان برنامه نویسی تازه ای پا به دنیای اندروید گذاشته و منم با خودم گفتم بد نیست تستش کنم و باهاش یه برنامه بنویسم و قصد دارم در این پست تجربه این کار با شما در میان بگذارم.

اولین کاری که من کردم باز کردن اندروید استادیو بود و زدن تیک استفاده از کاتلین در پروژه!

و همینجا بود که من به مشکل خوردم ! هیچی درست کار نکرد

برای رفع این مشکل من مجبور شدم مثل سابق یک پروزه اندرویدی با جاوا ایجا کنم و بعد یک اکتیویتی بسازم و اون جا تیک استفاده از کاتلین بزنم!!!!

یکی از اون حس های خوب موقع کار با کاتلین و اندرویند استادیو وقتی بود که کدی از جاوا کپی می کردم همه چیز خود به خود به کاتلین تغییر می کرد خیلی حال می داد.

اما خوب حالا پروژه کاتلینی ایجاد کردم اما مشکل این بود که کاتلین بلد نبودم پس رفتم به سایت

kotlinlang.org

بخش مستندات باز کردم و شروع به خوندن کردم تقریبا نصف روز طول کشید تا مستندات تموم بشه شباهت بسیار زیادی بین جاوا و کاتلین  وبقیه زبان های برنامه نویسی هست کهکار راحت میکنه.

اما تفاوت ها ساختار for , while و switch  که حتما باید بهش نگاه بندازید .

بهترین ویژگی کاتلین عدم استفاده از سیمی کالن بود.

راحت نویسی کاتلین خیلی حس خوبی می ده که واقعا دوستش داشتم

لامبدا بسیار کاربدیه اما یه مقداری درکش سخت شده چون حالت های متفاوتی داره و خیلی کامله حتما با دقت بخونیدش بعدش لذت بخش می شه

به جای اینترنفیس های تک متدی می تونید یک تابع به عنوان متغییر تعریف کنید ( مثل c++ زمانی که از اشاره گر ها استفاده می کنید یا حتی php ) و با لامبدا تابع تعریف کنید  که ساختار جالبی می شد و از نظر عملکرد تفاوت با اینترفیس تک تابعی نداره فقط کد نویسی کمتری داره.

یکی دیگه از ویژگی خوبش ولی اذیت کنندش Nullable safe بودنش  که راه حل های متفاوتی برای یک مشکل ارایه داده ( که هر کدوم باید به جای خودش استفاده بشه) اما واقعا یکی از مشکلات برنامه نویسی من حل کرد که مرتب در ازتباط با سرور باید نال بودن چک می کردم ( برای این کار من با استفاده از ارث بری که کلاس والد برای اکتیویتی درست می کردم که کد کمتری بنویسم ولی کاتلین اینم نداشت.)

تفاوت بعدی که خیلی متفاوت بود انواع لیست در کاتلین که حتما باید بخونیدش اگرمی خواید به کاتلین واقعی ( نه ترکیبی از جاوا و کاتلین ) کد بزنید

یکی دیگه از ویژگی های کاتلین هوش اندریود استادیو بود ( می دونم ربطی به هم ندارن)!!!!! اما این سازگاری کار براتون خیلی راحت می کنه.

اما نتیجه گیری :

در کل استفاده از کاتلین حس خوبی بهم داد همون حس استفاده ار وسایل نو  که همه ما تجربه اش کردیم.
فعلا قصد دارم از این ابزار نواستفاده کنم که ببینم ایا جاوا شامل این ضرب المثل می شه که می گه :
نو بیاد به بازار کهنه می شه دل آزار

اگر دل آزار شد بهتون می گم!

اگر خواستید نظر بدید و عضو ویرگول نبودید می توانید در وبلاگ من بدون عضویت نظرتون بگید

http://karimiblog.ir/blog/2019/01/اولین-تجربه-برنامه-نویسی-با-کاتلین/

نوشته اولین تجربه برنامه نویسی با کاتلین اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

آموزش زبان برنامه‌نویسی Rust – قسمت۸: Borrowing

با مالکیّت، مهم‌ترین و خاص‌ترین ویژگی زبان Rust، در جلسه‌ی پیش آشنا شدیم. حالا می‌خواهیم ببینیم که چطور می‌توانیم مقادیر را به توابع ارسال کنیم، بدون اینکه مالکیّت آن‌هارا منتقل کنیم.
در این جلسه می‌خواهیم درمورد referencing صحبت کنیم. یکی از پرکاربردترین بخش‌ها در هر برنامه‌ی کامپیوتری که مشکلات کار با آن بیشترین زحمت و زمان‌را از برنامه‌نویس‌ها می‌گیرید.
مشکلاتی که می‌خواهیم با کمک Rust برای همیشه حلشان کنیم.

مشکل چیست؟

آخرین چیزی که در جلسه‌ی پیش دیدیم کد زیر بود:

fn main() {
    let mut a = String::from("hello");
    a = i_am_owner(a);
    println!("a in main function: {}", a);
}
fn i_am_owner(input: String) -> String {
    println!("The input value is: {}", input);
    return input;
}

دیدیم که با دادن متغیّر a به تابع i_am_owner به عنوان پارامتر ورودی،‌ مالکیّت (Ownership) این متغیّر به آرگومان ورودی تابع منتقل می‌شود و ما دیگر نمی‌توانیم از آن در scopeی که تابع فراخوانی شده است استفاده کنیم.
برای رفع این مشکل، همانطوری که در تکّه کد بالا می‌بینید، در پایان تابع i_am_owner دوباره همان String را خروجی داده‌ایم و درون تابع main، متغیّر a را برابر خروجی این تابع قرار داده‌ایم تا مالکیّت داده را دوباره به آن بازگرداینم.
حالا می‌خواهیم ببینیم که چطوری می‌توانیم بدون انتقال مالکیّت یک مقدار، امکان استفاده از آن‌را به یک تابع بدهیم.

به مالکیّت من دست نزن!

بیایید کد بالا را کمی تغییر بدهیم. کد زیر را با دقّت نگاه کنید:

fn main() {
    let a = String::from("hello");
    i_am_owner(&a);
    println!("a in main function: {}", a);
}
fn i_am_owner(input: &String) {
    println!("The input value is: {}", input);
}

در اینجا ۴ تا تغییر رخ‌داده است:
۱-متغیّر a لازم نیست دیگر تغییر کند. به همین خاطر با پاک‌کردن mut در تعریف آن دوباره این متغیّر را immutable کرده‌ایم. (اگر مفاهیم mutable و immutable را فراموش کرده‌اید، با کلیک روی این نوشته به قسمت مربوط به آن بروید و خیلی سریع این مفاهیم را به‌خاطر بیاورید.)
۲)نوع ورودی تابع i_am_owner را تغییر داده‌ایم. حالا به جای String، پارامتر input از نوع String& است.
۳)هنگام فراخوانی i_am_owner در خط دوم تابع main، دیگر a را برابر خروجی این تابع قرار نداده‌ایم. چون در این کد دیگر مالکیّت مقدار آن به تابع منتقل نشده است که لازم باشد آن‌را پس‌بگیریم.
۴)به جای اینکه a را به عنوان ورودی به تابع بفرستیم، مقدار a& را واردش می‌کنیم. اینطوری دیگر مالکیّت این متغیّر به پارامتر ورودی تابع منتقل نمی‌شود. امّا چرا؟ بیایید دقیق‌تر نگاه‌کنیم.

Reference

وقتی که علامت & پشت یک نوع یا متغیّر قرارمی‌گیرد، یعنی داریم از یک reference صحبت می‌کنیم.
در حقیقت reference به یک مقدار اشاره می‌کند.
یک کارت ویزیت را تصوّر کنید. روی آن کارت، آدرس محل کار کسی که کارت‌را به شما داده است نوشته شده است. این کارت یک رفرنس به آن محل کار است.
ما ورودی تابع i_am_owner را از String به String& تغییر داده‌ایم. پس از حالا به بعد این تابع به جای اینکه کل یک String را به عنوان ورودی بگیرد، یک رفرنس به آن‌را قبول می‌کند. بنابراین مالکیّت String ورودی دیگر به آن منتقل نمی‌شود و رفرنس گرفته شده هم با تمام شدن scope این تابع، بدون هیچ مشکلی پاک می‌شود.
اینطوری مقدار اصلی دست‌نخورده باقی می‌ماند و همچنان متعلّق به متغیّر اصلی است (اگر مفهموم scope در Rust را فراموش کرده‌ای، با کلیک روی این نوشته یک نگاه سریع به آن بیندازید و بعد برگردید).
هروقت که پشت یک مقدار &را بگذاریم، یک رفرنس به آن می‌گیریم. حالا می‌توانیم بدون هیچ مشکلی آن رفرنس را به عنوان ورودی به هر تابعی بدهیم.
پارامتر ورودی تابع، یعنی input، یک رفرنس به متغیّر a است.
اتّفاقی که با دادن رفرنس a به تابع i_am_owner به عنوان ورودی می‌افتد شبیه شکل زیر است (تصویر از این آدرس برداشته شده است):

پارامتر ورودی تابع، یعنی input، یک رفرنس به متغیّر a است. متغیّر a هم، همانطوری که در قسمت قبل دیدیم، خودش یک اشاره‌گر به بخشی از حافظه در heap است.
بنابراین می‌بینید که drop شدن input پس از پایان‌یافتن scope تابع، آسیبی به متغیّر a و مقدارش نمی‌زند.

Dereferencing

متضاد رفرنس دادن، dereferencing نامیده می‌شود. یعنی به مقداری که reference دارد به آن اشاره می‌کند دسترسی پیدا می‌کنیم.
برای دسترسی به مقدار یک رفرنس، باید قبل از آن علامت * را قرار بدهیم. البته همانطوری که دیدید ما اینجا این کار را نکردیم. چون خود rust به خاطر ویژگی Smart pointers می‌تواند تفاوت استفاده از یک رفرنس یا مقدارش‌را تشخیص بدهد.
بعداً مفصلاً به این ویژگی خواهیم پرداخت، فعلاً کافی است بدانید که می‌توانستیم تابع‌را به شکل زیر هم بنویسیم و فعلاً این دوتا با هم تفاوتی ندارند:

fn main() {
    let a = String::from("hello");
    i_am_owner(&a);
    println!("a in main function: {}", a);
}
fn i_am_owner(input: &String) {
    println!("The input value is: {}", *input);
}

خب حالا دیدید که چگونه از رفرنس‌ها برای عدم انتقال مالکیّت استفاده کردیم؟ به این کار در Rust اصطلاحاً borrowing یا همان قرض‌گرفتن می‌گویند.
همانطوری که ما در دنیای واقعی وقتی چیزی می‌خواهیم آن‌را «قرض»می‌گیریم، در اینجا هم وقتی بخش دیگری از برنامه به یک مقدار نیاز دارد، آن مقدار را به او قرض می‌دهیم.
وقتی که ماشینتان‌را به کسی قرض می‌دهید، همچنان شما مالک آن ماشین هستید. اینجا هم مالک آن مقدار همچنان متغیّر اصلی است و دیگران صرفاً به صورت قرضی دارند از آن مقدار استفاده می‌کنند.
خب حالا بیایید ببینیم اگر بخواهیم مقداری که قرض‌گرفته‌ایم را تغییر بدهیم چه اتّفاقی می‌افتد؟

fn main() {
    let a = String::from("hello");
    i_am_owner(&a);
    println!("a in main function: {}", a);
}
fn modifier(reference: &String) {
    reference.push_str(" a new string to push to the old one");
}

اینجا درون تابع modifier می‌خواهیم یک string دیگر را به String اوّلیّه که به عنوان ورودی گرفته‌ایم اضافه کنیم.
وقتی که می‌خواهیم برنامه‌را کامپایل کنیم با ارور زیر مواجه می‌شویم:

error[E0596]: cannot borrow immutable borrowed content `*reference` as mutable
 --> src/main.rs:8:5
  |
۷ | fn modifier(reference: &String) {
  |                        ------- use `&mut String` here to make mutable
۸ |     reference.push_str(" a new string to push to the old one");
  |     ^^^^^^^^^ cannot borrow as mutable

همانطوری که در متن ارور نوشته شده است، ما نمی‌توانیم از یک رفرنس immutable به عنوان یک رفرنس mutable استفاده کنیم.
یعنی نمی‌توان مقداری که به عنوان مقدار immutable قرض‌گرفته شده است را به عنوان یک مقدار mutable استفاده کرد و آن‌را تغییر داد.
اگر دوباره به مثال ماشین برگردیم، یعنی شما نمی‌توانید تودوزی ماشینی که صرفاً برای یک مسافرت یک روزه قرض‌گرفته‌اید را تغییر دهید.
خب حالا اگر بخواهیم مقدار منتسب به یک رفرنس‌را تغییر بدهیم باید چه کار کنیم؟

ساخت رفرنس mutable

یادتان هست برای اینکه بتوانیم یک متغیّر را تغییر بدهیم چه کار می‌کردیم؟ با افزودن کلمه‌ی کلیدی mut به تعریف آن متغیّر، آن‌را تبدیل به یک مقدار mutable می‌کردیم.
حالا برای اینکه بتوانیم مقداری که یک رفرنس به آن اشاره می‌کند را تغییر بدهیم، احتمالاً باید کاری مشابه انجام بدهیم.
بیایید اوّل ببینیم اگر صرفاً خود متغیّر اوّلیّه را mutable کنیم، آیا امکان تغییردادن داده‌ی آن با استفاده از رفرنسی که از آن داریم وجود دارد یا نه؟
کد زیر را ببینید:

fn main() {
    let mut a = String::from("hello");
    modifier(&a);
    println!("a in main function: {}", a);
}
fn modifier(reference: &String) {
    reference.push_str(" a new string to push to the old one");
}

در این کد صرفاً کلمه‌ی کلیدی mut را به تعریف متغیّر a اضافه‌کرده‌ایم تا این متغیّر mutable شود و بتوانیم مقدار آن‌را تغییر بدهیم.
اگر این کد را کامپایل کنیم، کامپایلر Rust به ما warning و ارور زیر را برمی‌گرداند:

warning: variable does not need to be mutable
 --> src/main.rs:2:9
  |
۲ |     let mut a = String::from("hello");
  |         ----^
  |         |
  |         help: remove this `mut`
  |
  = note: #[warn(unused_mut)] on by default

error[E0596]: cannot borrow immutable borrowed content `*reference` as mutable
 --> src/main.rs:9:5
  |
۷ | fn modifier(reference: &String) {
  |                        ------- use `&mut String` here to make mutable
۸ |
۹ |     reference.push_str(" a new string to push to the old one");
  |     ^^^^^^^^^ cannot borrow as mutable

اوّل از همه برویم سراغ warning. این اخطار می‌گوید که لزومی ندارد که متغیّر a را mutable کنیم. به علاوه به عنوان راهنمایی از ما می‌خواهد که کلمه‌ی mut را از تعریف آن حذف کنیم.
چرا چنین چیزی را از ما می‌خواهد؟ چون هیچ‌کجا مقدار این متغیّر تغییر نکرده است. پس انگار تغییری که ما می‌خواستیم روی رفرنس آن بدهیم مورد قبول Rust نیست.
در اروری که بعد از آن اخطار به ما داده شده است، همان چیزی تکرار شده که در مرحله‌ی قبل دیدیم. یعنی هنوز هم رفرنس ما immutable است، هرچند که خود متغیّر را mutable کردیم.
حالا بیایید یک راه دیگر را امتحان کنیم. این بار به جای اینکه متغیّر را mutable کنیم، رفرنس آن‌را mutable می‌کنیم:

fn main() {
    let a = String::from("hello");
    modifier(&mut a);
    println!("a in main function: {}", a);
}
fn modifier(reference: &mut String) {
    reference.push_str(" a new string to push to the old one");
}

برای اینکه یک رفرنس mutable داشته باشیم، کافی است بعد از علامت & کلمه‌ی mut را اضافه کنیم و بعد از آن type یا نام متغیّر را قرار دهیم.
حالا اگر بخواهیم این برنامه‌را کامپایل کنیم چه اتّفاقی می‌افتد؟

error[E0596]: cannot borrow immutable local variable `a` as mutable
 --> src/main.rs:3:19
  |
۲ |     let a = String::from("hello");
  |         - consider changing this to `mut a`
۳ |     modifier(&mut a);
  |                   ^ cannot borrow mutably

باز هم به ارور خوردیم.
همانطوری که در خط اول ارور گفته شده است، ما نمی‌توانیم یک متغیّر immutable را به عنوان یک متغیّر mutable قرض بدهیم. به همین خاطر کامپایلر از ساخته‌شدن چنین رفرنسی جلوگیری می‌کند.
امّا وسط پیام ارور، کامپایلر برای ما یک راهنمایی قرار داده است. کامپایلر از ما خواسته است که متغیّر a را هم به عنوان یک متغیّر mutable تعریف کنیم. از آنجایی که هیچ پیام خطایی درمورد اضافه بودن رفرنس mutable وجود ندارد، پس احتمالاً نیمی از راه را دست آمده ایم.
بیایید این بار بدون اینکه رفرنس‌را تغییر بدهیم، صرفاً متغیّر a را mutable کنیم:

fn main() {
    let mut     a = String::from("hello");
    modifier(&mut a);
    println!("a in main function: {}", a);
}
fn modifier(reference: &mut String) {
    reference.push_str(" a new string to push to the old one");
}

حالا بیایید این کد که در حقیقت ترکیبی از دو تلاش قبلیمان است را کامپایل و اجرا کنیم:

a in main function: hello a new string to push to the old one

برنامه به خوبی کامپایل شد و بدون مشکل خروجی ای که می‌خواستیم را تولید کرد.
بنابراین برای اینکه بتوانیم از طریق رفرنس‌دهی یک مقدار را تغییر دهیم، باید از رفرنس‌های mutable استفاده کنیم. خلاصه‌ی همه‌ی کارهایی که در این بخش برای ساخت یک رفرنس mutable کردیم می‌شود:
۱)متغیّر اصلی باید mutable باشد.
۲)خود رفرنس هم باید mutable باشد. برای این کار باید بعد از علامت & کلمه‌ی mut را قرار دهیم.
خب حالا که دیدیم چطوری می‌توان یک رفرنس mutable ساخت، ببنیم که چطوری می‌شود به یک مقدار چندین رفرنس داد.

رفرنس‌دهی چندگانه

امیدوارم که عنوان این بخش به اندازه‌ی کافی ترسناک باشد تا حواستان‌را کامل به این مبحث جمع کنید. چیزی که می‌خواهیم ببینیم خیلی ساده است، امّا موقع نوشتن برنامه خیلی‌هارا به دردسر می‌اندازد و زمان می‌برد تا برنامه‌نویس به این مفهموم عادت کند.
بیایید اوّل یک برنامه‌ی خیلی ساده را درنظر بگیریم.
در این برنامه ما می‌خواهیم یک String را همراه با دو متن مختلف نمایش بدهیم. برای هرکدام از این شیوه‌های نمایش هم یک تابع جداگانه داریم.
همانطوری که بالاتر دیدیم، برای این کار باید از رفرنس‌ها استفاده کنیم تا مالکیّت مقدار اوّلیّه منتقل نشود و بتوان آن را به تابع‌های دیگر هم داد.
کد زیر چیزی است که داریم:

fn main() {
    let a = String::from("hello");
    let reference1 = &a;
    let reference2 = &a;
    ali(reference1);
    hossein(reference2);
    println!("a in main function: {}", a);

}

fn ali(original_text: &String) {
    println!("Ali says: {}", original_text);
}

fn hossein(text: &String) {
    println!("{} hossein", text);
}

اگر این برنامه‌را کامپایل و اجرا کنیم، بدون هیچ مشکلی خروجی‌ای که انتظارش را داریم تولید می‌شود:

Ali says: hello
hello hossein
a in main function: hello

حالا فرض کنید که می‌خواهیم یک تابع سومی هم داشته باشیم. قرار است تابع mohammad ورودی‌ای که می‌گیرد را تغییر بدهد و به آخر آن علامت ! را اضافه کند.
برای این کار برنامه‌ی زیر را می‌نویسیم:

fn main() {
    let mut a = String::from("hello");
    let reference1 = &a;
    let reference2 = &a;
    let reference3 = &mut a;
    ali(reference1);
    mohammad(reference3);
    hossein(reference2);
    println!("a in main function: {}", a);
}
fn ali(original_text: &String) {
    println!("Ali says: {}", original_text);
}
fn hossein(text: &String) {
    println!("{} hossein", text);
}
fn mohammad(original_input: &mut String) {
    original_input.push_str("!");
}

خب حالا اگر این برنامه‌را بخواهیم کامپایل کنیم چه اتّفاقی می‌افتد؟

error[E0502]: cannot borrow `a` as mutable because it is also borrowed as immutable
  --> src/main.rs:14:27
   |
۱۲ |     let reference1 = &a;
   |                       - immutable borrow occurs here
۱۳ |     let reference2 = &a;
۱۴ |     let reference3 = &mut a;
   |                           ^ mutable borrow occurs here
...
۱۹ | }
   | - immutable borrow ends here

error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/main.rs:18:40
   |
۱۴ |     let reference3 = &mut a;
   |                           - mutable borrow occurs here
...
۱۸ |     println!("a in main function: {}", a);
   |                                        ^ immutable borrow occurs here
۱۹ | }
   | - mutable borrow ends here

خب با یک ارور بلندبالا مواجه شدیم. بیایید قدم به قدم با ارور جلو برویم و ببینیم که چه اتّفاقی افتاده است.
اوّل ارور این متن نوشته شده است:

cannot borrow `a` as mutable because it is also borrowed as immutable

کامپایلر به ما می‌گوید که نمی‌تواند یک رفرنس mutable به متغیّر a اضافه کند، چون پیش از آن، و البته به صورت همزمان (در یک scope)، رفرنس‌های immutable به این متغیّر ساخته شده است.
در دو بخش بعدی ارور هم کامپایلر به ما نشان می‌دهد که مشکل کجای کد رخ‌داده است:

--> src/main.rs:14:27
   |
۱۲ |     let reference1 = &a;
   |                       - immutable borrow occurs here
۱۳ |     let reference2 = &a;
۱۴ |     let reference3 = &mut a;
   |                           ^ mutable borrow occurs here
...
۱۹ | }
   | - immutable borrow ends here

اینجا کامپایلر به ما نشان می‌دهد که ابتدا یک immutable borrow رخ داده است، یعنی یک رفرنس immutable به متغیّر a ساخته شده است، و بعد یک mutable borrow.

در بخش بعدی هم کامپایلر توضیحات مشابهی می‌دهد.

امّا چرا کامپایلر Rust به ما اجازه‌ی ساخت رفرنس mutable را همراه رفرنس‌های immutable نمی‌دهد؟

محدودیت‌های ساخت رفرنس

زبان Rust به ما اجازه نمی‌دهد که وقتی که داریم از یک رفرنس mutable استفاده می‌کنیم، رفرنس دیگری داشته باشیم.
محدودیت ساخت رفرنس‌های متعدد به یک داده زمانی اجرایی می‌شود که هر۲ شرط زیر برقرار باشند:
۱) دو یا چند اشاره‌گر (رفرنس) به صورت هم‌زمان به یک داده دسترسی داشته باشند.
۲) حدّاقل یکی از این اشاره‌گرها برای نوشتن روی داده استفاده شوند (رفرنس mutable).

امّا چرا این حالت مشکل‌زا است و Rust جلوی اتّفاق افتادنش را می‌گیرد؟

Data Race

وقتی که چند رفرنس immutable به صورت همزمان به یک داده اشاره می‌کنند مشکلی ایجاد نمی‌شود. هرکدام می‌توانند بدون اینکه خللی به کار دیگران وارد کنند داده‌را بخوانند.
امّا وقتی که بیش از یک رفرنس داریم و حدّاقل یکی از آن‌ها mutable است قضیه فرق می‌کند.
فرض کنید که تنها یک اشاره‌گر برای نوشتن داریم و بقیه‌ی رفرنس‌ها immutable هستند. بخش‌هایی از کد که دارند از این رفرنس‌های immutable استفاده می‌کنند، انتظار آن‌را ندارند که داده وسط کارشان تغییر کند. امّا بخشی از برنامه که توانایی نوشتن روی داده را دارد، می‌تواند در حین کار آن‌ها داده‌را تغییر بدهد و کارشان‌را خراب کند.
حالا اگر بیش از ۱ اشاره‌گر نویسنده داشته باشیم قضیه بدتر می‌شود. در این حالت هر رفرنس mutable هم می‌تواند کار بخش‌هایی که صرفاً دارند داده‌را می‌خوانند خراب کند، و هم می‌تواند با قراردادن داده‌های خود مابین داده‌های رفرنس mutable دیگر، داده‌های آن‌را هم خراب کند.
به این حالت اصطلاحاً data race می‌گویند. data race یکی از بدترین باگ‌هایی است که می‌تواند در یک برنامه ایجاد شود و پیداکردن آن بسیار سخت است.
زبان Rust برای اینکه مطمئن شود هرگز data race رخ نمی‌دهد، به شما اصلاً اجازه‌ی این‌را نمی‌دهد که به صورت هم‌زمان یک رفرنس mutable ایجاد کنید و درکنارش رفرنس‌های دیگری هم داشته باشید.
این‌طوری وقتی برنامه با موفّقیّت کامپایل شد، می‌توانید مطمئن باشید که در آن data race وجود ندارد.
علاوه‌بر حالتی که دیدیم، اگر برنامه‌ای بنویسید که مثلاً دوتا mutable reference هم داشته باشد باز با اروری مشابه چیزی که دیدیم مواجه می‌شوید.

معنی هم‌زمان بودن اشاره‌گرها

باید به کلمه‌ی هم‌زمان بودن در اوّلین شرط از شرایط محدودیت‌های ساخت رفرنس خیلی دقّت کنید.
ما زمانی دوتا رفرنس به صورت هم‌زمان داریم که آن‌ها درون یک scope واحد تعریف شده باشند.
مثلاً در همین برنامه‌ای که بالاتر نوشتیم، متغیّرهای reference1، reference2 و reference3 همه در scope تابع main قرار دارند. پس ما به صورت هم‌زمان ۳ تا رفرنس به متغیّر a داریم.
حالا به برنامه‌ی زیر که دقیقا‌ً همان کاری را می‌کند که انتظار داشتیم برنامه‌ی قبلی انجام بدهد نگاه کنید:

fn main() {
    let mut a = String::from("hello");
    ali(&a);
    mohammad(&mut a);
    hossein(&a);
    println!("a in main function: {}", a);
}
fn ali(original_text: &String) {
    println!("Ali says: {}", original_text);
}
fn hossein(text: &String) {
    println!("{} hossein", text);
}
fn mohammad (original_input: &mut String) {
    original_input.push_str("!");
}

اگر این برنامه‌را کامپایل و اجرا کنیم می‌بینیم که دقیقاً همانطوری که انتظارش‌را داشتیم کار می‌کند و خروجی زیر را تولید می‌کند:

Ali says: hello
hello! hossein
a in main function: hello!

امّا چرا این کار کرد و برنامه‌ی قبلی نه؟
پاسخ در همان کلمه‌ی هم‌زمان است. اینجا هم ما ۳ رفرنس مختلف به متغیّر a داریم که یکی از آن‌ها mutable است. امّا این بار این ۳ رفرنس هم‌زمان ایجاد نشده اند. چون هرکدام مربوط به یک scope مختلف هستند.
یعنی رفرنس اوّل متعلّق به scope تابع ali است، دومی متعلّق به scope تابع mohammad و سومی هم متعلّق به تابع hossein.
علاوه بر اینکه این ۳ رفرنس متعلّق به scope های مختلف هستند، این برنامه‌ هم به صورت sequential اجرا می‌شود نه parallel. یعنی هرکدام از این توابع پس از تمام شدن تابع قبلی فراخوانی می‌شوند، نه هم‌زمان با اجرای آن‌ها. پس هرگز اینجا data race ایجاد نمی‌شود.
به همین خاطر است که کامپایلر Rust این بار اجازه‌ی داشتن چندین رفرنس‌را به یک مقدار می‌دهد.
این نکته شمارا از خیلی از اشتباهات آینده مصون می‌کند، البته اگر آن‌را همیشه به خاطر داشته باشید.

رفرنس‌های آویزان!

به عنوان آخرین بخش این آموزش به یکی دیگر از مشکلاتی که در دیگر زبان‌ها هنگام استفاده از رفرنس‌ها ایجاد می‌شود می‌پردازیم.
Dangling reference به رفرنسی گفته می‌شود که به جایی از حافظه اشاره می‌کند که دیگر داده‌ای که انتظارش می‌رود در آنجا نیست.
این اتّفاق زمانی می‌افتد که با آزاد شدن حافظه، آن مکان الان به جای دیگری اختصاص پیدا کرده است یا اینکه دیگر داده‌های قبلی به خاطر free شدن به صورت valid در آن‌جا قرار ندارند.
مثلاً برنامه‌ی ساده‌ی زیر را به زبان c درنظر بگیرید:

#include 
#include 
char* dangle_generator() {
    char * a = (char*) malloc(sizeof(char) * 10);
    a = "hello";
    free(a);
    return a;
}

int main() {
    char* b = dangle_generator();
    printf("%s", b);
    return 0;
}

اگر این برنامه‌را کامپایل کنید هیچ مشکلی رخ نمی‌دهد. حالا سعی کنید برنامه‌ی کامپایل شده را اجرا کنید:

munmap_chunk(): invalid pointer
Aborted (core dumped)

موقع اجرا به مشکل بدی خوردیم. وجود dangling reference ها درون برنامه می‌تواند همه‌چیز را خراب کند، و مثل اکثر باگ‌های مربتط با اشاره‌گرها، پیداکردن مشکل هم کار خیلی سختی است.
حالا بیایید مشابه برنامه‌ی بالا را به زبان Rust بنویسیم:

fn main() {
    let b = dangle_generator();
    println!("a in main function: {}", b);
}
fn dangle_generator() -> &String {
    let a = String::from("hello");
    &a
}

حالا اگر این برنامه‌را کامپایل کنیم با چه چیزی روبه‌رو می‌شویم؟

error[E0106]: missing lifetime specifier
 --> src/main.rs:6:26
  |
۶ | fn dangle_generator() -> &String {
  |                          ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
  = help: consider giving it a 'static lifetime

باز هم مثل همیشه کامپایلر همیشه در صحنه‌ی Rust وارد عمل می‌شود و به شما یک پیام خطای دقیق و کامل می‌دهد.
ابتدای پیام خطا مربوط به ویژگی lifetime زبان Rust می‌شود که فعلاً با آن کاری نداریم و بعداً به صورت مفصّل درموردش صحبت می‌کنیم‌، امّا در بخش help پیغام خطا به ما می‌گوید که چه مشکلی پیش‌آمده است.
متن ارور می‌گوید که در انتهای تابع می‌خواهیم یک مقدار قرض‌گرفته شده را برگردانیم (یعنی یک رفرنس)، امّا مقداری برای قرض‌گرفتن وجود ندارد.
حالا این یعنی چی؟ متغیّر a یک متغیّر محلّی درون تابع dangle_generator است. بنابراین با به انتها رسیدن scope این تابع، این مقدار هم drop می‌شود و دیگر در دسترس نیست. حالا ما داریم تلاش می‌کنیم یک رفرنس به مقداری که از بین خواهد رفت‌را برگردانیم. یعنی می‌خواهیم به چیزی که اصلاً دیگر وجود ندارد رفرنس بدهیم.
اینجا Rust از به وجود آمدن یک dangling reference جلوگیری می‌کند.
پس یکی دیگر از کرامات زبان Rust این است که وقتی برنامه کامپایل شد، می‌توانید مطمئن باشید که هیچ باگی مربوط به dangling reference ها درونش وجود ندارد.
اگر بخواهیم این مشکل به وجود نیاید، کافی است به جای رفرنس، کل مقدار را از تابع خروجی بدهیم. این‌طوری مالکیّت آن مقدار منتقل می‌شود و همه‌چیز به خیر می‌گذرد.

در قسمت بعدی درمورد slicing صحبت می‌کنیم. آخرین ویژگی‌ای که مستقیماً به بحث مالکیّت (Ownership) مربوط می‌شود.
با دانستن آن عملاً اطّلاعات لازم را برای کار با مهم‌ترین ویژگی زبان Rust پیدا می‌کنیم، می‌توانیم به مفاهیم مهم و پرکاربرد دیگر بپردازیم و به نوشتن برنامه‌های کامل به این زبان نزدیک شویم.
اگر سؤالی درمورد این مفهوم داشتید می‌توانید در قسمت نظرات بیان کنید. شاید سؤال شما سؤال دیگران هم باشد. خوشحال می‌شوم که با همدیگر عمیق‌تر یادبگیریم.

این نوشته برای اوّلین بار خیلی وقت پیش در وبلاگ شخصی من منتشر شده است. برای دیدن این مطلب در آنجا، خواندن قسمت‌های جدیدتر و مطالب دیگری که در ویرگول منتشر نمی‌کنم، روی این نوشته کلیک کنید.

اگر قسمت قبلی‌را نخوانده‌ای همین حالا به آنجا برو تا با Ownership، مفهوم بنیادی زبان Rust آشنا بشوی.

اوّلین بار است که این مجموعه‌ی آموزشی‌را می‌بینی؟ با کلیک روی این نوشته به اوّلین قسمت آن برو و شروع به یادگیری کن.

نوشته آموزش زبان برنامه‌نویسی Rust – قسمت۸: Borrowing اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

آیا دوره‌های آموزشی بسیار طولانی میتوانند مفید باشند؟

نکاتی درباره‌ی بهترین و موثرترین دوره‌های آموزشی

میخواهیم برای یادگیری یک تخصص اقدام کنیم، اما با لیست بلند بالایی از منابع آموزشی مختلف مواجه میشویم.
انتخاب بین یکی چندین منبع آموزشی که در اختیار داریم، انتخابی بسیار سخت است. در این مقاله، با ویژگی‌های بهترین و موثرترین دوره‌های آموزشی آشنا میشیم. در انتهای یاد میگیریم که کدام دوره‌های آموزشی مفید و کدام بدردنخور هستند و باید از آن‌ها دوری کنیم. با من همراه باشید 🙂

http://aparat.com/v/uxNQ7

۶، ۶۰، یا ۶۰۰ ساعت؟ کدام دوره‌ی آموزشی را انتخاب کنم؟

ممکن است برای شما هم پیش بیاید. میخواهید شروع به یادگیری یک تخصص کنید و با چندین دوره‌ی آموزشی مختلف مواجه میشوید:

  • یک دوره‌ی جمع و جور ۶ ساعته
  • یک دوره ی ۶۰ ساعته
  • یک دوره‌ی ۲ ساله و ۶۰۰ ساعته!

در تصمیم گیری نهایی دچار مشکل شده‌اید و نمیدونید که کدام یک از این دوره‌های آموزشی رو انتخاب کنید و یادگیری رو شروع کنید. در این مقاله میخوایم در خصوص این موضوع صحبت کنیم که بهترین دوره‌های آموزشی چه ویژگی هایی دارند.

سوال‌هایی که باید از خودمان بپرسیم

قبل از اینکه شروع کنیم به انتخاب یک منبع آموزشی و یادگیری، باید یک سری سوالاتی رو از خودمان بپرسیم:

تمام ساعت آموزشی دوره مفید است؟

مهم‌ترین سوالی که وجود دارد این است. آیا تمام آن ۶۰ تا ۶۰۰ ساعت آموزش مفید است؟

به شخصه در دوره‌های چند ده ساعته‌ای شرکت کردم که در آن‌ها مدرس بیش از ۱۰ ساعت فقط منتظر بود که یک فایل دانلود شود، یک نصب یک برنامه اتفاق بیفتد، یا اینکه ۲۰ دقیقه کد را بالا و پایین کند تا باگ کدی که نوشته‌ را پیدا کند.

اصلی‌ترین دلیلی که باعث زیاد شدن ساعات یک دوره‌ی آموزشی میشود، معمولا این است که آن دوره‌ی آموزشی وقت های مرده و تلف شده‌ی بسیاری دارد.

حوصله داریم؟ سنگ بزرگ نشونه‌ی …

سوال بعدی این است، که آیا اصلا ما حوصله‌ و وقت دیدن چند ده ساعت آموزش را داریم یا خیر.

ضرب المثلی وجود دارد که میگوید: «سنگ بزرگ نشانه‌ی نزدن است»

اگر یک دوره‌ی آموزشی ۶۰ ساعته را تهیه کنید، همش باید نگران این باشید که چه زمانی از سال، وقت کافی برای دیدن این ۶ ساعت آموزش پیدا خواهید کرد. و از آنجایی که هیچوقت سر شما خلوت تر نخواهد شد، هیچوقت آن‌ دوره‌ی آموزشی را شروع نخواهید کرد و تخصصی که آرزو داشتید را کسب نخواهید کرد.

میشه توی زمان کمتری همین هارو یاد گرفت؟

سوال مهم بعدی این است. آیا میشود همین مباحث رو توی ۱۰ ساعت یاد گرفت؟

وقت ما مهم‌ترین دارایی ما است و هیچوقت نمیتوانیم ‌آن‌را به هیچ صورتی برگردانیم. وقتی که یک دوره‌ی آموزشی از شما چند ده ساعت زمان میگیرد، اما به اندازه چند دقیقه به شما اطلاعات و تخصص میدهد، باید به عنوان یک فردی که زمانش برایش مهم است، بهمان بر بخورد.

همیشه باید به دنبال بالابرن کارکرد و بازدهی خودمان باشیم. همانطور که یک دونده‌ی سرعت سعی میکند همیشه مسافت بیشتری را در زمان کمتری طی بکند، ماهم باید سعی بکنیم کارهای بیشتری را با کیفیت عالی و در زمان کم انجام دهیم. فقط در این صورت است که میتوانیم در دنیای امروز با سرعت سرسام آور رشد دانش و اطلاعات در دور رقابت باقی بمانیم.

آیا واقعا به ۶۰ ساعت دانش نیاز داریم؟

نکته‌ای که باید دقت کنیم این است که آیا اصلا به چند ده ساعت آموزش نیاز داریم؟

شاید بخواهیم فقط بصورت مقدماتی با یک موضوع آشنا بشیم یا اینکه یک بخش خاص از یک موضوع رو یاد بگیریم. آیا واقعا نیازه که ۶۰ ساعت آموزش در خصوص اون تهیه کنیم؟

برای مثال ممکنه شما طراحی وب با HTML و CSS رو بلد باشید و فقط بخواید در خصوص طراحی وب واکنش گرا تخصص پیدا کنید. برای این موضوع نیاز نیست ۶۰ ساعت آموزش ببینید و یک آموزش چند ساعته شما را به حد خوبی از تخصص خواهد رساند.

چرا یاد نمیگیرم؟ / چرا پیشرفت نمیکنم؟

اگه نتونیم یک فرایند یادگیری موثر داشته باشیم، اینجوری کلافه میشیم

وقتی که شروع به یادگیری یک تخصص میکنیم و در ابتدا بسیار باانگیزه و خوشحال هستیم و برنامه ریزی میکنیم که در ۶ ماه آینده یکی از متخصص ترین افراد باشیم.

اما بعد از مدتی انگیزه خود را از دست میدهیم و با این سوال مواجه میشویم که چرا یاد نمیگریم و پیشرفت نمیکنیم. در ادامه‌ میخواهیم درباره‌ی چند دلیل اصلی عدم یادگیری و پیشرفت صحبت کنیم.

مثلا میخوایم PHP یاد بگیریم

فرض کنید که میخواهیم شروع به یادگیری زبان برنامه نویسی PHP کنیم. قبل از هرچیز نیاز داریم به منابع آموزشی. به همین منظور:

  • دوره‌ی مهدی خسروی رو میخریم
  • دوره‌ی خسرو مهدوی رو دانلود میکنیم
  • ۴۰ تا مقاله رو بوک مارک میکنیم
  • توی ۵ تا کانال و گروه تلگرامی عضو میشیم
  • ۱۰ تا کتاب انگلیسی رایگان دانلود میکنیم
  • ۵ تا دوره‌ی انگلیسی لیندا رو از دوستون میگیریم
  • یه کتاب خیلی خوب از نمایشگاه کتاب میخریم
  • یه پلی لیست خوب از یوتیوب پیدا میکنیم، و نهایتا میگیم: خببببب،‌ حالا میخوام یادگیری رو شروع کنم

اما با یک سوال بزرگ مواجه میشیم: کدوم یکی از اینهارو اول شروع کنم؟ کدومشون برای یادگیری بهتره؟

مشکل اصلی: تعدد انتخاب

یکی از بزرگترین مشکلاتی که هنگام شروع یادگیری یک تخصص جدید ممکنه با آن مواجه شویم، تعدد انتخاب یا سرریز شدن اطلاعات است. آنقدر اطلاعات و کتاب و دوره در دسترس داریم که نمیدانیم کدام را برای شروع انتخاب کنیم.

مهم‌ترین تصمیمی که در این حالت میتوانیم بگیریم این است که از بین تمام منابع آموزشی، فقط یکی را انتخاب کنیم و بقیه را از دسترس خارج کنیم. اینگونه شاید بتوانیم یک دوره‌ی آموزشی را کامل نگاه کنیم و به انتها برسانیم.

وقت ما ارزشمند است

نکته‌ای که در خصوص دوره‌های بلند مدت و چند ده ساعته‌ی آموزشی وجود دارد، این است که اکثر آن‌ها ارزش زمانی که برایشان میگذاریم را ندارند. باید بدانیم که وقت ما ارزشمند است و نباید آن‌را با مشاهده‌ی یک دو‌ره‌ی مثلا ۶۰ ساعته که بیش از ۱۰ ساعت آن بی استفاده است، هدر دهیم.

همانطور که گفتیم، همیشه باید به دنبال این باشیم که کارهای بیشتری را با کیفیت بیشتر در مدت زمان کمتری انجام دهیم.

قانون ۲۰ ساعت

جاش کافمن، بسیار دوست داشتنی، باحال و خلاق هست. حتما نام او را در گوگل جستجو کنید.

اخیرا کتاب بسیار خوبی که متاسفانه هنوز به فارسی ترجمه نشده را خواندم. کتاب The First 20 Hours از Josh Jaufman، در این کتاب ایده‌های فوق العاده‌ای برای یادگیری سریع مطرح شده است.

آقای کافمن در این کتاب بر این عقیده است که برای یادگیری یک مهارت در حدی که بتوانیم از آن لذت ببریم، ۲۰ ساعت تمرین درست و اصولی کافی است.

دقت کنید که واژه‌ی «لذت بردن» در جمله‌ی بالا بسیار مهم است. با ۲۰ ساعت تمرین ما هرگز نمیتوانیم به یک فرد بسیار متخصص در یک مهارت تبدیل شویم. اما میتوانیم آن مهارت را در حدی یاد بگیریم که از آن لذت ببریم. پس هرگز نیاز نیست ۶۰ ساعت یا بیشتر از زمانمان را در یک دوره‌ی آموزشی هدر دهیم. فقط کافی است که اگر میخواهیم از یک مهارت لذت ببریم، ۶۰ ساعت اصولی و درست در آن مهارت یاد بگیریم و تمرین کنیم. در آینده حتما خلاصه‌ای از این کتاب را با شما به اشتراک خواهم گذاشت.

اکثر مدرسان برنامه نویسی: من اینقدر بلدم که میتونم …

متاسفانه کاری که اکثر مدرسان برنامه نویسی میخواهند انجام دهند تدریس نیست، بلکه فقط اثبات خودشان به عنوان یک برنامه‌نویس حرفه‌ای است.

به جرئت میتوانم بگویم ۹۰ درصد اشخاصی که به زبان فارسی در حال آموزش برنامه نویسی هستند، تمام سعی خود را میکنند که برنامه نویسی را بسیار سخت و پیچیده جلوه دهند. آن‌ها در آموزش‌هایشان یک کار بسیار ساده را، بسیار سخت میکنند و برای یک فرایند ساده، گاهی چند صد خط کد مینویسند.

اکثرا در صحبت‌هایشان در کلمه‌های انگلیسی با یک لحجه‌ی عجیب و غریب استفاده میکنند و همگی ادعا میکنند که از ۵ سالگی برنامه نویس بوده‌اند. از تمام برنامه نویسان دیگر ایراد میگیرند و بزرگترین شرکت‌های دنیا را نقد میکنند.

این افراد فقط به یک دلیل این کار را انجام میدهند. به این دلیل که این پیام را منتقل کنند که:

من فردی بسیار حرفه‌ای هستم و در برنامه نویسی و آموزش بهترین میباشم. چون سخت ترین مباحث را بلدم و میتوانم کارهای بسیار عجیب و غریبی با برنامه نویسی انجام دهم. بیایید و از آموزش‌های من استفاده کنید.

اما متاسفانه این افراد، یک اصل بزرگ که انیشتین به خوبی به آن اشاره کرده است را فراموش کرده‌اند:

بهترین مدرس‌های و دوره‌های آموزشی در دنیا چه ویژگی‌هایی دارند؟

از آ‌ن‌جایی که همیشه علاقه به یادگیری مباحث جدید دارم و هرروز بهترین منابع آموزشی دنیا را بررسی میکنم، به چند وجه مشترک بین تمام آموزش‌ها و آموزش‌دهنده‌های حرفه‌ای پی برده‌ام که در زیر میخواهیم درباره‌ی آن‌ها صحبت کنیم:

بسیار ساده

یکی از مهم‌ترین نکاتی که بین تمامی آموزش‌های حرفه‌ای وجود دارد،‌ این است آن‌ها بسیار ساده و قابل فهم برای همگان هستند.

ساده بودن را با ارائه‌ی نکات پیش افتاده و ساده اشتباه نگیرید. حرفه‌ای‌ترین مدرس‌ها کسانی هستند که میتوانند سخت‌ترین مفاهیم را بسیار ساده مطرح کنند تا دانشجوها انگیزه ادامه‌ی یادگیری را پیدا کنند.

بسیار کوتاه

کوتاه بودن دوره‌‌های آموزشی یکی دیگر از ویژگی‌هایی است که بین اکثر آموزش‌های حرفه‌ای مشترک است. مخصوصا اگر دوره‌های سایت Lynda را مشاهده کرده باشید، به ندرت دوره‌‌ای طولانی‌تر از ۶-۷ ساعت پیدا میکنید و اکثر دوره‌ها میانگین زمانی ۳ ساعت را دارند.

بسیار خاص

یکی از ویژگی‌های دوره‌های آموزشی خوب این است که بسیار خاص هستند. به این معنی که به یک تخصص خاص در یک حیطه اشاره میکنند. برای مثال اگر شما بخواهید طراحی وب را یاد بگیرید، باید چندین دوره‌ی مختلف و جدا را شرکت کنید:

  • آموزش HTML5
  • آموزش CSS3
  • آموزش طراحی وبسایت واکنش گرا
  • آموزش جاوا اسکریپت
  • آموزش جی کوئری
  • ترکیب جاوا اسکریپت و جی کوئری برای ساخت وبسایت
  • و…

ترکیب این چند دوره‌ی آموزشی، در نهایت از شما یک طراح وب حرفه‌ای میسازد. چون هرکدام از این دوره‌ها کوتاه و خاص هستند، پیگیری و مشاهده‌ی آن‌ها کار راحتی است.

کاملا عملی

در اکثر دوره‌های بین المللی، تئوریات و تاریخچه ها اصلا جایی ندارد. همان ابتدا سلام میکنند، خود را معرفی میکنند و مستقیم به سراغ کدنویسی میروند. تمرین هایی کاملا عملی دارند و همه چیز را عملی و پروژه محور ارائه میکنند. در صورتی که در اکثر دوره‌های فارسی زبان، شما چندین ساعت فقط درباره‌ی تاریخچه‌ی تغیر و تحولات آن زبان برنامه نویسی باید اطلاعات بی استفاده دریافت کنید!!!

حواسمون به اینا باشه:

وقتی که قصد انتخاب یک دوره‌ی آموزشی رو داریم، باید مراقب یک سری نکات و جملات خطرناک باشیم که برای آموزش و یادگیری ما سم هستند.

صفر تا صد

هرجا کلمه‌هایی مثل صفر تا صد، کامل‌ترین و چیزهایی شبیه به آن‌را دیدید فورا فرار کنید. برنامه نویسی، طراحی و کلا هر تخصصی دیگری هیچ انتهایی برای آن وجود ندارد و اگر کسی ادعا کرد که میخواهد صفر تا صد یک تخصص را به شما بیاموزد، یک لبخند بزنید و سریعا از او دوری کنید.

پیشنهاد میکنم مقاله برنامه نویسی چیست؟ را هم حتما مطالعه کنید.

۶۰۰ ساعت آموزش کاربردی

ممکن است دوره‌های آموزشی بلند مدت بسیار خوب و حرفه‌ای هم داشته باشیم. اما صرفا اینکه یک دوره‌ی آموزشی چند ده ساعته یا بسیار طولانی است، دلیلی برای خوب بودن آن دوره‌ی آموزشی نیست.

همانطور که گفتیم اگر یک دوره‌ی آموزشی بسیار بلند مدت دیدید، باید حواستان را بیشتر جمع کنید و بیشتر به آن شک کنید.

بهترین و باسوادترین برنامه نویس ایران

اگر اهل پیگیری فوتبال باشید، احتمالا میدانید که بهترین فوتبالیست‌ها، نمیتوانند بهترین مربی‌های فوتبال باشند. همینطور ممکن است یک فرد در دوران فوتبال خودش زیاد درخشان بازی نکند، اما در دوران مربی‌گری بسیار حرفه‌ای باشد.

این موضوع این نکته را دربر دارد که همانطور که یک فوتبالیست حرفه‌ای، شاید نتواند یک مربی حرفه‌ای باشد، یک برنامه نویس حرفه‌ای هم شاید توانایی تدریس حرفه‌ای نداشته باشد.

بسیار خوب است که یک برنامه نویس پروژه‌هایی بزرگ را انجام داده باشد و یا در چند شرکت بزرگ برنامه نویسی کد زده باشد، اما این موضوع صرفا به این دلیل نیست که او یک مدرس حرفه‌ای است.

علی دایی نمونه موفق یک فوتبالیست و مربی خوب. اما آیا همه میتوانند مثل او هم در فوتبال بازی کردن درخشان باشند و هم در مربی گری؟ )

تدریس و توانایی انتقال مفاهیم، خود یک تخصص است که متاسفانه بسیاری از مدرسان ما از آن محروم هستند.

پس صرف اینکه یک فرد یک برنامه نویس حرفه‌ای است، دلیل نمیشود که آموزش‌هایی حرفه‌ای هم داشته باشد. توانایی تدریس فرد را بررسی کنید و اگر با شیوه‌ی تدریس او راحت بودید، آن زمان اقدام به شروع یادگیری از او کنید.

میانبر، ترفند، راز و…

هروقت در هر دوره‌ی آموزشی کلماتی مثل میانبر، ترفند، راز و کلماتی از این دست دیدید، سریعا از آن آموزش دوری کنید. در کسب تخصص، هیچ چیزی به نام میانبر یا راز وجود ندارد.

بله، کسب تخصص سخت است و بله، باید برای یادگیری یک تخصص زمان کافی بگذارید. هیچ میانبر و راه کوتاهی وجود ندارد.

حرف آخر 🙂

تمام این حرف‌ها را زدیم که فقط به یک نکته حواسان باشد: زمان ما ارزشمند و منابع ما محدود است. باید مراقب باشیم که وقت و پولمان را در جایی درست هزینه کنیم تا بتوانیم بهترین بازدهی را داشته باشیم. در آینده در خصوص یادگیری برنامه نویسی و رو‌ش‌های آن مطالب دیگری را با شما به اشتراک خواهم گذشت.

نظر شما دربا‌ره‌ی دوره‌های آموزش ناکارآمد چیست؟ آیا تجربه‌ی ناموفقی در خصوص انتخاب اشتباه یک دوره‌ی آموزشی اشتباه داشته‌اید؟

منبع: یادیفای

نوشته آیا دوره‌های آموزشی بسیار طولانی میتوانند مفید باشند؟ اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

چطور پروژه برنامه نویسی بگیریم؟

خیلی از افرادی که مشغول کار برنامه نویسی هستند همیشه از کم بودن تعداد پروژه برنامه نویسی،مشتری کم و یا نبود مشتری ناراضی هستند.در این مقاله می خواهیم با روش های ساده و کاربردی گرفتن پروژه برنامه نویسی آشنا شویم.

اگر برنامه نویسی را به تازگی شروع کرده باشید باید به چند مورد توجه داشته باشید.یکی از این موارد داشتن رزومه کاری مناسب است،برای داشتن روزمه کاری کامل و خوب می توانید با انجام پروژه های برنامه نویسی رایگان یک رزومه مناسب برای خود ایجاد کنید.هر وقت رزومه داشته باشید گرفتن سفارش پروژه برنامه نویسی خیلی راحتر می شود. چون کسی که میخواهد به شما سفارش دهد رزومه و نمونه کارهای شما رو می بیند.

دقت داشته باشید داشتن مهارت برنامه نویسی و تحلیل پروژه های یکی از مهمترین مواردی است که باید به آن توجه ویژه داشته باشید.(شما می توانید برای افزایش مهارت برنامه نویسی خود از دوره های آموزشی کدفرند استفاده کنید).

۱.گرفتن پروژه از وب سایت های برون سپاری (فریلنسرینگ)

یکی از بهترین روش برای گرفتن سفارش پروژه برنامه نویسی است استفاده از اینترنت است یعنی شما میتوانید با استفاده از اینترنت به بازاری وصف ناشدنی دست پیدا کنید. فقط باید بدانید چطور و چگونه این کار رو انجام دهید.وب سایت های مانند پارسکدرز برای این منظور استفاده کنید.

روش دیگر این است در گوگول جستجو کنید، با جستجو میتوانید تعداد زیادی پروژه پیدا کنید.یک کار دیگر استفاده از انجمن های برنامه نویسی و مهم ایران است. یا میتوانید در سایت هایی که پروژه های برنامه نویسی رو مختلف در آن ها  ثبت می شود و با استفاده رزومه و قیمت مناسب و رقابتی تر پروژه رو قبول کنید.

۲٫گرفتن پروژه از شرکت ها

بعد از اینکه یک رزومه خوب و قابل قبول برای خود ایجاد کردید به شرکت های برنامه نویسی سر بزنید و رزومه و نمونه کارهای خود رو ارائه دهید و اگر باهاشون صحبت کنید احتمال گرفتن پروژه برنامه نویسی به شدت بالا است. در ابتدا شاید پیشنهاد شرکت (هزینه) برای انجام پروژه کم باشد اما به صرفه است چون شما در ابتدای راه هستید.

۳.گرفتن پروژه از دوستان و آشنایان

بعد از اینکه در مورد گرفتن سفارش پروژه برنامه نویسی از شرکت ها صحبت کردیم حال میخواهیم یک روش دیگر برای گرفتن سفارش پروژه برنامه نویسی رو معرفی کنیم. یکی دیگر از روش ها این است که به دوستان و آشنایان بسپارید که اگر پروژه ای چیزی بود شما رو خبر کنند.البته یک نکته مهم رو در نظر بگیرید که هر کسی رو دیدید بهش نگید چون پرستیژ و اعتبار خودتون رو زیر سوال میبرید.

۴.ایجاد برندینگ شخصی

(منبع)وقتی شما به عنوان یک فریلنسر فعالیت می‌کنید, جریان درآمد شما تنها با انجام پروژه‌ها تأمین می‌شود. یعنی وقتی مشغول کار برروی یک پروژه نیستید, پولی هم در نخواهید آورد. از طرف دیگر برندینگ کاری وقت گیر و هزینه بر است. شما برای اینکه برند خودتان را به وجود بیاورید باید وبلاگ نویسی کنید, در شبکه‌های اجتماعی فعال باشید, برای شبکه سازی در رویدادهای مختلف مشارکت کنید و صدها کار دیگر که وقت و هزینه‌ی زیادی را از شما طلب می‌کند.

با هزینه‌های روزافزون زندگی, کمتر فریلنسری حاضر می‌شود که به برند سازی بپردازد. نتیجه‌ی این کار هم مشخص است. وقتی کسی شما را به عنوان یک برند شخصی نمی‌شناسد, پروژه‌ای هم به شما نخواهد داد. یعنی باید مدت زمان بیشتری را در جستوجوی مشتری بگذرانید و حتی گاهی با قیمتی کمتر از ارزش واقعی کارتان پروژه‌ها را انجام بدهید.

نوشته چطور پروژه برنامه نویسی بگیریم؟ اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

منابع آموزش آنلاین برنامه‌نویسی به زبان فارسی

منابع زیادی برای یادگیری برنامه‌نویسی به زبان انگلیسی وجود دارد، اما در این پست به برخی از سایت‌های آموزشی آنلاین به زبان فارسی پرداخته‌ایم.

سایت مکتب‌خونه

مکتب‌خونه بزرگ‌ترین رسانه دیجیتال آموزش مجازی در ایران است که در بیش از ۶ سال فعالیت خود توانسته است خدمتی بزرگ در جهت دسترسی ایرانیان و فارسی زبانان سراسر دنیا به آموزش با کیفیت فارسی ارائه دهد. هدف مکتب‌خونه در دسترس قرار دادن آموزش با کیفیت بالا برای همه‌ی فارسی زبانان است. ما اعتقاد داریم که هیچ‌کس نباید به خاطر هیچ‌چیز از لذت یاد گرفتن محروم شود. نباید سن و سال یا مکان و موقعیت و امکانات مالی افرادی را از یادگیری و موفقیت باز دارد.

آدرس: http://maktabkhooneh.org

سایت کارادمی

کارادمی فراتر از یک آموزش خطی و از پیش تعیین شده است. اکثر فارغ‌التحصیلان دانشگاه‌ها طی دوره تحصیلی خود مهارت‌هایی که نیاز بازار کار است را آموزش نمی‌بینند و به همین منظور فرآیند استخدام برای جوانان به یک چالش بزرگ تبدیل شده است.

این شکاف آموزشی تنها به دانشگاه‌ها محدود نمی‌شود و حتی در اکثر شرکت‌ها هم کارآموزان با آموزش تجربی و عملی رو به رو نمی‌شوند و چالش‌های کار واقعی را لمس نمی‌کنند.

یکی از راه‌کارهای حل این چالش شرکت در دوره‌های کوتاه و فشرده‌ای به نام بوت‌کمپ می‌باشد. تفاوت این دوره‌ها به دیگر دوره‌های آموزشی در عملی بودن و ایجاد فضای حرفه‌ای کار است. دوره‌های جدی و پر از چالش برای این که کارآموزان بتوانند در سطح بازار ایران و جهان حرفی برای گفتن داشته باشند.

بوت‌کمپ‌های کارادمی هم مهارت‌های فنی و هم مهارت‌های نرم را در حوزه فناوری اطلاعات به صورت عملی و پروژه‌ای به علاقه‌مندان طی دوره مشخص (اغلب ۳ ماه) آموزش می‌دهد و فارغ‌التحصیلان این بوت‌کمپ قادر به پیدا کردن شغل مورد علاقه خود طی زمان اندک می‌باشند.

آدرس: https://karademy.ir

سایت فرانش

فرانش ( کائسنا قدیم) یک وبسایت آموزش آنلاین ویدیویی تخصصی (مشابه سایت خارجی لیندا) می‌باشد که در امر مهارت‌آموزی اقدامات زیادی را صورت داده است. بیش از هزاران دوره آموزشی در قالب طراحی و گرافیک، برنامه‌نویسی، شبکه، حوزه کسب و کار و غیره ارائه کرده است. یک استارتاپ پرآینده با رشدی سریع و پر از چالش‌های نو و جذاب برای کسی که قصد پیشرفت دارد و از روزمرگی فراری است.

این وبسایت در طی یک سال و نیم فعالیتش توانسته به یکی از پیشتازان آموزش آنلاین ایران تبدیل شود. فرانش در جشنواره وب و موبایل ۹۴ نیز به عنوان بهترین وبسایت آموزش آنلاین ایران انتخاب شد و اعضای تیم هم در طی این مدت همراه فرانش پیشرفت کرده‌اند و متخصص تر شده‌اند.

آدرس: https://faranesh.com

سایت فرادرس

یکی از بزرگترین پروژه‌های آموزش آنلاین دانشگاهی و تخصصی می‌باشد. گامهای نخست راه اندازی پروژه فرادرس، در سال ۱۳۸۷ با ارایه آموزش‌های مرتبط با هوش مصنوعی و برنامه‌نویسی برداشته شد. فرادرس، پس از مدت کوتاهی، در زمستان ۱۳۹۰، توانست عنوان بهترین پروژه آنلاین آموزشی ایران به انتخاب کاربران را در چهارمین جشنواره وب ایران کسب کرده و در ادامه به صورت گام به گام، مسیر تبدیل شدن به بزرگترین پلتفرم دروس دانشگاهی کشور را طی کرد.

هدف فرادرس ایجاد دسترسی آسان، همیشگی و همگانی به دانش آکادمیک و تخصصی می‌باشد. ارائه آموزش‌های ویدیویی و فیلم‌های آموزشی هوش مصنوعی، کامپیوتر، برق، مکانیک، عمران و سایر رشته‌های مهندسی از جمله عناوینی است که به آن فرادرس پرداخته است.

آدرس: https://faradars.org

برای مطالعه پست‌های بیشتر ما را در وبلاگ کارادمی و یا در ویرگول دنبال کنید.

نوشته منابع آموزش آنلاین برنامه‌نویسی به زبان فارسی اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

سلام METEOR : آشنایی و معرفی این فریمورک

آشنایی با فریم ورک METEORJS

سلام دوستان ویرگولی. توی این مقاله قصد دارم یک فریم ورک جدید تحت NodeJS معرفی کنم. اسم این فریمورک Meteor هست که تو ایران تقریبا ناشناخته محسوب میشه. من خودم به تازگی با این فریمورک دوست داشتنی آشنا شدم و سعی دارم که بگم چرا Meteor فوق‌العاده هست و چرا باید ازش استفاده کرد.

من در این پست سعی میکنم مقاله هایی که خوندم رو با تجربه خودم مخلوط کنم تا یک دید خوب نسبت به Meteor برای شما بسازم. در مقالات بعدی سعی میکنم کامل موارد و آموزش های مختلف در این باره را توضیح دهم.

مثل ماکارانی پختن، شروع به کار کنید

شما برای شروع کار با Meteor تنها اگر syntax های جاوااسکریپت بلد باشید کافیست. به علاوه یک ایده کلی راجع به دیتابیس ها. با دونستن این دو مورد به شما قول میدم میتونید تو ۲ روز در حین یادگیری اپلیکیشنی که با ابزار های دیگه در صورتی که مهارت کامل را داشته باشید حداقل یک هفته طول میکشه رو بنویسید.

یک بار بنویسید، چند خروجی بگیرید

اگر قرار باشه یک اپلیکیشن تک صفحه ایی و یا یک اپلیکیشن realtime و یا اینکه یک اپلیکیشن با ReactNative بنویسید قاعدتا کار سخت و دشواری میشه. (خداییش سخته :|‌ )

اما در METEOR این قاعده برعکس هست. با Meteor خیلی سخته اپلیکیشنی بنویسید که این ویژگی ها رو نداشته باشه!!! یعنی به صورت پیش فرض هست و اگر قصد غیر فعال کردن داشته باشید باید یک سری مراحل اضافه انجام دهید.

بذارید دقیقا همین عنوان را یک بار دیگه تکرار کنم و یک بار دیگه توضیح بدم.

وب از شما اندروید، iOS و دسکتاپ از Meteor

بر خلاف موضع گیری الکی علیه اپلیکیشن های hybrid تو جامعه توسعه دهنده های ایرانی من معتقدم واسه اکثر استارتاپ ها اپلیکیشن های Hybrid بهترین گزینه هست. راجع به خود موبایل اپلیکیشن های Meteor کافیه بگم که با توجه به cordova ای که داخل خود Meteor به صورت بومی وجود داره برای ساخت اپلیکیشن های موبایل کافیه دو دستور خیلی خیلی ساده در ترمینال وارد کنید. مثلا:

meteor run android
meteor run ios

همه چیز جاوا اسکریپت

اگر شما توسعه دهنده جاوااسکریپت نباشید ممکنه این براتون ترسناک باشه. اما باز هم این اطمینان را میدم که شما برای کار کردن با همه چیز Meteor به همون اندازه به جاوا اسکریپت نیاز دارید که هر وب سایت دیگه‌ای رو بخواید با زبان های دیگه بنویسید. مسلما اگر میخواهید بهتر از Meteor استفاده کنید باید جاوا اسکریپت کار خفنی بشید ولی برای شروع اگه چیزی از Async یا callback یا حتی ES6 و چیز های مشابه ندونید هیچ مشکلی واستون پیش نمیاد فقط کافیه syntax اولیه رو بدونید.

خب پس با Meteor شما تمام Server ، Client و دیتابیستون رو با جاوا اسکریپت مینویسید.

مثل برق، سریع‌ توسعه دهید

نمیدونم به نظرتون Authentication کار سختیه یا نه! ولی فک میکنم اونقدر کار سخت و درگیر کننده ای هست که تعداد زیادی BaaS برای اینکار به وجود آمده، این کار در Meteor با یک کد در ترمینال انجام میشود. بعد از اجرا شما یک سیستم کاربری کامل با پسورد hash شده، تایید ایمیل،‌ فراموشی ایمیل و … دارید.

کد اجرا در ترمینال:

meteor add accounts-password

امنیت

باید بگم Meteor یک فریمورک Full-stack هست و به عنوان DBMS از MongoDB استفاده میکند و به صورت پایه از RDBMS ها در مقابل injection ها امنیتی خیلی بالاتری دارد. همینطور به خاطر معماری MVVM و دیتابیس سمت کلاینت و تخصص افراد کمی در این فریمورک هک کردن یک اپلیکیشن Meteor کار سخت تری از یه اپلیکیشن با فریمورک های دیگه هست.

نوشته سلام METEOR : آشنایی و معرفی این فریمورک اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

۵ زبان برنامه نویسی برتر در حوزه بلاک‌چین

بلاک چین چشم مشتاقان زیادی را در سراسر دنیا به خود خیره کرده است تا این فناوری بتواند با از بین بردن سیستم‌های ثابت که تراکنش‌های مالی بر اساس آنها در سراسر دنیا انجام می‌شود به جای آنها جایگزین شود.در این مقاله می خواهیم با ۵ زبان برنامه نویسی برتر در حوزه بلاک‌چین آشنا شویم(دوره های آموزش برنامه نویسی کدفرند).

بلاک چین چیست؟

بلاک چین (Blockchain) از دو کلمه Block (بلوک) و Chain (زنجیره) ایجاد شده است. این فناوری در حقیقت زنجیره‌ای از بلوک‌هاست.به طور کلی بلاک چین یک نوع سیستم ثبت اطلاعات و گزارش است.تفاوت آن با سیستم‌های دیگر این است که اطلاعات ذخیره شده روی این نوع سیستم، میان همه اعضای شبکه به اشتراک گذاشته می‌شوند و با استفاده از رمزنگاری امکان حذف و دستکاری اطلاعات ثبت شده تقریبا غیرممکن است.

بیت کوین اولین کاربرد از این فناوری بود و از بلاک چین برای ذخیره اطلاعات دارایی کاربران بهره برد. اگر بلاک چین یک سیستم عامل باشد، بیت کوین نرم افزاری روی این سیستم عامل است.

تکنولوژی بلاک چین قطعا یک اختراع فوق العاده است. اما سوالی که برای همه مردم پیش می آید این است: واقعا بلاک چین چیست؟! بلاک چین یک اوراق بهادار دیجیتالی غیر متمرکز است. با استفاده از توزیع (و نه کپی) اطلاعات دیجیتال تکنولوژی بلاک چی در واقع زیرساخت ایجا یک نوع اینترنت جدید را ایجاد کرده است.

این تکنولوژی که در اصل وام گرفته شده از ارز دیجیتال و بیت کوین است، در حال یافتن کاربردهای دیگر برای این پتانسیل از تکنولوژی است. بیت کوین به عنوان طلای دیجیتال شناخته می شود.فناوری در حال فراهم آوردن فرصت‌های زیادی برای برنامه نویسان و گسترش دهندگان این صنعت است تا بر روی آن سرمایه گذاری کنند.

بهترین زبان برنامه نویسی بلاک چین

چندین زبان برنامه نویسی وجود دارند که می‌توانند برای ایجاد اپلیکیشن هایی برای بلاک چین کمک کنند می‌توان از زبان‌های قدیمی مانند ++C، جاوا (Java) و پایتون (Python) استفاده کرد یا دیگر زبان‌هایی مانند Simplicity و Solidity که جدید هستند و برای بلاک چین اختصاصی شده‌اند.

۱.زبان سی پلاس پلاس (++C)

این برنامه به عنوان مشتقی از زبان برنامه نویسی C ساخته شده است. زبان روندگرای ++C بر اساس زبان داده‌گرای C نوشته شده است. شاید همین بزرگ‌ترین تفاوت بین این دو زبان باشد. ++C اطلاعات و عملکرد آنها را به داده‌ها تبدیل می‌کند که می‌توان آنها را به راحتی در برنامه‌های دیگر مورد استفاده قرار داد. این زبان برنامه نویسی بلاک چین اجازه می‌دهد تا مدیریت مؤثرتری بر روی حافظه وجود داشته باشد.

بلاک چین به بسیاری از کاربران و ماینرها اجازه می‌دهد تا به صورت سیستماتیک و همزمان عمل کنند. ++C اپلیکیشنهایی را ایجاد می‌کند که نه تنها بین نقاط پایانی بلکه در پروسه انجام تراکنش سریع‌تر عمل می‌کنند. به همین علت است که پروژه‌های بلاک چین مانند بیت کوین اتریوم و ریپل همگی با زبان ++C نوشته شده‌اند.(دوره های آموزش برنامه نویسی کدفرند).

۲.زبان جاوا (Java)

جاوا به عنوان زبان جهانی اینترنت بسیار اهمیت دارد. زبان برنامه نویسی بلاک چین زبانی قدیمی و برای ایجاد پیج های اینترنتی فعال بسیار مفید است. همچنین برای ایجاد بلاک چین‌های ساده و تغییرناپذیر نیز کاربرد دارد. تغییر ناپذیری باعث می‌شود که هیچ کس نتواند اطلاعات یک بلوک را تغییر دهد هر بلوک تازه که بلاک چین اضافه می‌شود.

اطلاعات بلوک قبلی به اضافه اطلاعات بلوک جدید را در اختیار دارد. هر تغییری که در یک بلوک ایجاد شود باعث ایجاد تغییر جدیدی در بلوک‌های کناری آن هم خواهد شد، و تا زمانی که اطلاعات آن بلوک با دیگر بلوک‌ها هماهنگ نشده باشد نمی‌تواند به زنجیره اضافه شود در نتیجه بلاک چین به این وسیله تغییر ناپذیر شده است.

۳.زبان پایتون (Python)

زبان پایتون به وسیله یک برنامه نویس هلندی به نام گویدو وان روسام (guido van Rossum) در سال ۱۹۹۱ ابداع شد. هدف او تولید زبان برنامه نویسی آسان و مینی مالیستی بود. ترکیب و منطق این برنامه، نشان از روحیه بلندپرواز، ابداع کننده آن دارد. در نتیجه پایتون در زمینه توسعه نرم افزارها و وب، زبانی برتر است. این زبان در میان متخصصان کامپیوتری و دانشمندان زمینه دیتا بسیار معروف است. همچنین یکی از زبان‌های برتر برنامه نویسی بلاک چین است.

۴.زبان سیمپلیسیتی (Simplicity)

سیمپلیسیتی یک زبان برنامه نویسی بلاک چین است که برای تنظیم قراردادهای هوشمند به کار می‌رود. این زبان برنامه نویسی بلاک چین به گفته راسل اوکانر (Russell O’Connor) سازنده این برنامه بسیار ساده است. این زبان برای بهبود زبان‌های پایه‌ای ارزهای دیجیتال مانند بیت کوین و اتریوم به کار برده می‌شود.

در این زبان از تجزیه و تحلیل استاتیک برای جلوگیری از هنگ کردن برنامه‌ها هنگام آنالیز و محاسبات استفاده می‌شود. اوکانر و کمپانی او یعنی بلاک ‌استریم (blockstream) امیدوار هستند که این زبان، پس از آنکه آزمایشش را کاملاً پس داد در بیت کوین مورد استفاده قرار بگیرد.

۵.زبان سالیدیتی (Solidity)

و در آخر زبان برنامه نویسی سالیدیتی،این زبان برنامه نویسی بلاک‌چین از سطح بالایی برخوردار است و بر پایه قرارداد تنظیم شده است. حروف آن مشابه با حروفی هستند که در جاوا مورد استفاده قرار می‌گیرند. بخش‌های هم مانند متغیرها، کلاس‌ها و عملکردهای خود را از جاوا برداشت کرده است.

یادگیری این زبان برای برنامه نویسان بسیار آسان است. زبان سالیدیتی توضیحاتی در مورد اینکه چطور کدهایش عمل می‌کنند را برای کسانی که علاقه‌مند به آموختن آن باشند توضیح داده است این توضیح ممکن است در ابتدا کمی مشکل به نظر بیاید.

با این حال مشکل فقط برای کسانی وجود دارد که با زبان‌های مدرن برنامه نویسی آشنایی ندارند. به عنوان یک زبان جدید در برنامه نویسی سالیدیتی در حال پیشرفت و معروفیت است. افزایش اعداد و منابع در این زبان نشان دهنده آن است که این زبان به طور اختصاصی برای برنامه‌های تکنولوژیک طراحی شده و به منظور بهبود عمل کرده بلاک چین به کار می‌رود

(برای یادگیری زبان های برنامه نویسی اشاره شده در بالا می توانید از دوره ای آموزشی کدفرند استفاده کنید).

نوشته ۵ زبان برنامه نویسی برتر در حوزه بلاک‌چین اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

اهمیت یادگیری زبان برنامه نویسی C برای برنامه نویسان

برنامه نویسان به دو دسته تقسیم می شوند؛ آنهایی که یک زبان را به صورت پایه ای یاد میگیرند تا با استفاده از لایبرری ها و فریمورک ها صرفاً تسک های یک پروژه را به اتمام برسانند، و آنهایی که کنجکاو هستند تا از روش کار لایبرری ها و فریمورک های مورد استفاده خود درک کامل پیدا کنند.

برنامه نویسان مصرف گرا، به اصطلاح «استک آورفلویی»

مشکلی که این روزه گریبانگیر توسعه دهنده ها شده، مصرف گرایی آنها است. این رویکرد باعث شده تا خلاقیت و پیشرفت دنیای توسعه نرم افزار کم شود و «جستجو کردن» به جای همراهی با «فکر کردن»، به سمت تصاحب جایگاه «فکر کردن» برود.

تقصیر ما یا دوستان ناباب؟

نمی شود تاثیر رقابت استارت آپ ها را بی ربط به این ویروس دانست و تمام قصور را از چشم برنامه نویس ها دید. با این حال، در هر زمینه ای در آخر، این برنامه نویس ها هستند که اجازه می دهند این فضا ایجاد شود. اگر برنامه نویسی نبود که با چشمان بسته به بحث های فنی، تصمیم به استفاده از کد های دیگران بگیرد، توقع کارفرما ها نیز معقول تر بود.

چرا C یاد بگیریم؟

از بحث اصلی دور نشویم. یادگیری یک زبان میان-سطح مانند C برای برنامه نویسانی که حتی از زبان هایی همچون جاوا استفاده می کنند نیز اهمیت دارد. یادگیری مسئله مهم و اساسی ای همچون مدیریت حافظه، تفاوت حافظه استک و هیپ مموری، عدم وجود لایبرری هایی که با ۵ خط کد قابلیت بازنویسی دارند، که در جامعه جاوا اسکریپت به وفور دیده می شود؛ برنامه نویس را وا می دارد تا کمی دانش، حتی تکراری، تولید کند تا درک بهتری از ساز و کار نرم افزار خود که قرار بود حکم فرزند او را دارد داشته باشد، پیدا کند.

کلاه خود را قاضی کنید

چطور می شود تا این حد از فرزند خود بی شناخت بود و بی اهمیت از کنارش رد شد؟ وردپرس که خود خانه مشوق تمام درگ اند دراپ ها و کپی پیست ها است جمله شیرینی را شعار خود کرده است که می گوید «کد شعر است» و برداشت من این است که توسعه دهنده قرار است از سرودن آن و تماشای آن لذت ببرد، نه اینکه صرفا تسک خود را از روی دیوار اتاق یا جیرا به عنوان «انجام شده» علامت بزند.

سر آخر

اگر برنامه نویسی بخواهد که توانایی حل مسائلی به غیر از مسائل روزمره و مرتبط با فیلد خاص شغل فعلی خود را داشته باشد، و نرم افزار های اکستندبل (توسعه پذیر از جهت نرم افزاری) و اسکلبل (توسعه پذیر از جهت افزایش توانایی پاسخگویی به حجم بیشتر درخواست و کاربر) تولید کند، باید به چم و خم توسعه نرم افزار در زبان نیمه-ابتدایی ای چون زبان C مسلط باشد. چون به حتم این تسلط در هر زبان دیگری راه گشای حل مسائل و درک بهتر وی از محصول تولیدی خود می شود.

نوشته اهمیت یادگیری زبان برنامه نویسی C برای برنامه نویسان اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

CSS Reset چیست؟ راهنما و آموزش کامل CSS Reset

اگر تجربه‌ی طراحی صفحات وب را داشته باشید، حتما به این مورد برخورد کرده‌اید که شکل ظاهری وبسایت شما در مرورگرهای مختلف به شکل های مختلفی نمایش داده میشود. برای مثال سایتی که شما طراحی کرده‌اید، در مرورگر گوگل کروم به یک شکل نمایش داده میشود و در مرورگر فایرفاکس به شکل دیگری. راه حل این موضوع استفاده از CSS Reset ها است. در این مقاله و فایل آموزشی بصورت کامل بررسی میکنیم که CSS Reset چیست و چطور میتوان از آن‌ CSS Reset ها استفاده کرد.

CSS Reset چیست

برای درک کامل CSS Reset ها و رسیدن به پاسخ سوال CSS Reset چیست ، فیلم آموزشی زیر میتواند بسیار مفید باشد

https://www.aparat.com/v/ba3W4

انواع مرورگرها

همانطور که میدانید ما انواع مختلفی از مرورگرها داریم. ممکن است شما به عنوان یک طراح وب یا برنامه نویس وب، از مرورگرهای مختلفی مثل گوگل کروم، فایرفاکس، اینترنت اکسپلورر، سافاری و… استفاده کنید.

هرکدام از مرورگرهای موجود، یک سری استایل های پیشفرضی دارند که روی تگ های HTML اعمال میکنند. برای مثال گوگل کروم و فایرفاکس، مقادیر مختلفی از margin ها، padding ها و… را روی تگ های HTML اعمال میکنند.

این استایل های پیشفرضی که توسط مرورگرها روی تگ های مختلف HTML اعمال میشود، باعث میشود که نحوه‌ی نمایش صفحه‌ی وب طراحی شده توسط شما در مرورگرهای مختلف بصورت های متفاوتی باشد. زیرا استایل های پیشفرض مرورگرها با هم متفاوت است.

چرا باید از CSS Reset ها استفاده کنیم؟

برای اینکه بتوانید این استایل های پیشفرض مرورگرها را از بین ببرید و خنثی کنید، باید از CSS Reset ها استفاده کنید. در واقع اگر بخواهیم بگوییم که CSS Reset چیست ، میتوانیم این تعریف را داشته باشیم:

CSS Reset چیست : CSS Reset ها به شما کمک میکنند که استایل های پیشفرضی که مرورگرها روی تگ های مختلف اعمال میکنند را خنثی کنید و از بین ببرید. این موضوع باعث میشود که صفحه‌ی وب طراحی شده توسط شما در نهایت روی تمامی مرورگرها، به یک شکل نمایش داده میشود.

در واقع CSS Reset ها به شما کمک میکنند که طراحی یکسانی در تمام مرورگرها داشته باشید.

شاید برایتان سوال پیش بیاید که CSS Reset چیست ؟ آیا یک روش کدنویسی است؟ یا یک کتابخانه است؟

CSS Reset فقط چند خط کد ساده‌ی CSS است. شما چند خط کد ساده‌ی CSS را وارد پروژه‌ی خود میکنید. همین. بعد از آن، تمامی استایل های پیشفرض مرورگرها خنثی میشود.

CSS Reset چیست و دقیقا چه کاری میکند؟

قبل از اینکه بخواهیم روش استفاده از CSS Reset را یاد بگیریم، در زیر میخواهیم یک صفحه‌ی وب را در دو حالت بررسی کنیم. حالت اول، وقتی CSS Reset روی آن صفحه‌ وب تنظیم نشده است و حالت دوم وقتی که CSS Reset رو آن تنظیم شده است.

یک صفحه‌ی وب ساده بدون استفاده از CSS Reset شکلی شبیه به زیر خواهد داشت:

اما وقتی CSS Reset را وارد یک صفحه‌ی وب میکنید و از آن استفاده میکنید، صفحه‌ی وب‌تان شبیه عکس زیر میشود:

همانطور که در تصویر بالا میبینید، بعد از استفاده از CSS Reset ها، چند اتفاق برای سایت شما می‌افتد:

  1. همه‌ی padding ها و margin های پیشفرض مرورگر ها از بین میرود
  2. همه‌ی استایل های متون مثل سایز، رنگ، کلفتی متن و… از بین میرود
  3. و بطور خالی صفحه‌ی وب شما خالی از هرگونه استایل پیشفرض میشود.

بعد از استفاده از CSS Reset ها، شما میتوانید بدون دخالت استایل های پیشفرض مرورگرها، اقدام به طراحی صفحات وب خودتان کنید. صفحات وبی که در همه‌ی مرورگرها به یک شکل نمایش داده میشود، زیرا استایل های پیشفرض مرورگرها را با استفاده از CSS Reset ها خنثی کرده‌ایم.

روش استفاده از CSS Reset ها

برای اسفتاده از CSS Reset ها کافیست چند خط کد ساده‌ی CSS را که از قبل نوشته شده است را وارد فایل استایل خود کنید.

برای اینکار ابتدا کد زیر را کپی کنید (منبع):

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
 border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
  display: block;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
 quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
 content: '';
  content: none;
}
table {
  border-collapse: collapse;
  border-spacing: 0;
}

سپس یک فایل مثلا با نام reset.css بسازید و این کد ها را در آن قرار دهید.

کار تمام است. الان فقط کافی است که این فایل را با استفاده از یک خط کد HTML ساده، در قسمت تگ فایل HTML خود وارد کنید تا استایل های CSS Reset لود شود:

با استفاده از اینکار میتوانید کاری کنید که تمام استایل های پیشفرض مرورگرهای مختلف خنثی شود.

در این مقاله بصورت خلاصه سعی کردیم به سوال CSS Reset چیست پاسخ دهیم. برای درک عمیق این مطلب، پیشنهاد میکنیم که حتما فیلم آموزشی موجود در ابتدای این مقاله را مشاهده بفرمایید تا خیلی دقیق متوجه شوید که CSS Reset چیست و چطور میتوانید از آن استفاده کنید.

منبع: یادیفای

نوشته CSS Reset چیست؟ راهنما و آموزش کامل CSS Reset اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی