الگوریتم ها هسته اصلی توسعه موفق و کارآمد هستند. در حین یادگیری کدنویسی از آنها استفاده خواهید کرد، در مصاحبه های فنی از شما در مورد آنها سؤال می شود و احتمالاً بخشی از کار توسعه روزانه شما خواهند بود.
یادگیری الگوریتم های رایج به صورت جداگانه مفید است، اما چیزی که حتی بهتر است عادت کردن به تفکر الگوریتمی است. اگر بتوانید مغز خود را برای درک و پیروی از منطق الگوریتمی آموزش دهید، نوشتن الگوریتم های خود بسیار شهودی تر خواهد شد.
در اینجا برای توضیح تفکر الگوریتمی و نحوه حل مشکلات با این روش، Ethan Urie از Learn to Be a Developer است.
آن را دور کن، ایتان!
افشا: من برای برخی از منابع ذکر شده در این مقاله یک وابسته مفتخر هستم. اگر محصولی را از طریق پیوندهای من در این صفحه خریداری کنید، ممکن است کمیسیون کمی برای معرفی شما دریافت کنم. با تشکر!
آیا الگوریتم ها شما را مضطرب می کنند؟ آیا آنها برای شما پیچیده و خیلی سخت به نظر می رسند؟ یا مطمئن نیستید که آنها چه هستند؟
اگر هر یک از این چیزها را احساس می کنید، یا احساس می کنید که نمی توانید یک توسعه دهنده واقعی باشید مگر اینکه آنها را بدانید، تنها نیستید.
الگوریتمها و ساختار دادهها از مشکلات دنیای توسعه نرمافزار هستند. برنامهنویسهای تحصیلکرده سنتی احتمالاً در یک یا دو کلاس در مورد آنها آموزش داده میشوند و توسعهدهندگان خودآموخته یا بوتکمپ اغلب اصلاً در معرض آنها نیستند.
با این حال، برای اکثر توسعه دهندگان مبتدی، الگوریتم ها و ساختارهای داده منبع بسیاری از اضطراب و نشانگان فریبنده هستند.
کسب اطلاعات بیشتر: بهترین IDE برای کاربران مک
استفاده از تفکر الگوریتمی برای سرگرمی و سود
اما بیشتر سود.
الگوریتمی فکر کردن یک تغییر ذهنی از نحوه تفکر ما به عنوان مردم است. این بیشتر یک روش سیستماتیک برای فکر کردن از طریق مشکلات و راه حل ها به روشی است که شبیه نحوه کار یک کامپیوتر است.
اما این به طرز شگفت انگیزی دشوار است. همه ما به طور ناخودآگاه میانبرها، مفروضات و قوانین سرانگشتی ایجاد کرده ایم که از آنها برای کمک به حل مشکلات روزمره بدون فکر کردن به آنها استفاده می کنیم.
به عنوان مثال، کار ساده مرتب سازی 10 عدد را انجام دهید. همانطور که پیش میآید، میتوانیم به آنها نگاهی بیندازیم، خیلی سریع بگوییم ترتیب باید چگونه باشد، و اعداد را به درستی مرتب کنیم.
با این حال، ما عادت نداریم که فرآیند فکر خود را به مراحل جداگانه تقسیم کنیم و آن را به آنچه رایانه ها می توانند انجام دهند ترجمه کنیم. به عنوان مثال، رایانه ها نمی توانند برای یافتن یک کلمه بر اساس املای آن، به نقاط کلی در فرهنگ لغت بپرند. یک کامپیوتر باید دستورالعملهای بسیار مشخصی در مورد اینکه از کجا شروع کند داشته باشد (به علاوه آنها نمیتوانند اعداد واقعا تصادفی را انجام دهند).
مثال دیگر جستجوی نام در دفترچه تلفن یا کلمه ای در فرهنگ لغت است. ما به عنوان انسان عموماً می دانیم، با توجه به نام یا کلمه، تا چه اندازه به کتاب نیاز داریم تا جستجوی خود را شروع کنیم – اگر با A شروع شود، از همان ابتدا شروع می کنیم. اگر نام/کلمه با M شروع شود، به وسط کتاب و غیره می پریم.
برای توسعهدهندگان مبتدی، شکستن این فرآیند فکری و ترجمه آن به مراحل قابل محاسبه دشوار است، زیرا رایانهها معمولاً نمیتوانند انواع قضاوتها را درباره جایی که در لیست شروع کنند، انجام دهند.
پس چگونه الگوریتمی فکر می کنید؟!
مانند همه مهارت ها، این مهارت قابل یادگیری است و فقط به تمرین نیاز دارد. این مانند درک نحوه سازماندهی کد در کلاسها در طراحی شیگرا (OOD) است. شما تمام تلاش خود را می کنید و راه حل را برای بهبود نقاط ضعفی که بعداً پیدا می کنید تکرار می کنید.
با این حال، مانند OOD، دستورالعمل هایی وجود دارد که می تواند به شما کمک کند سریعتر به آنجا برسید.
در اصل، تفکر الگوریتمی تفکر در مورد چگونگی حل یک مسئله به روشی سیستماتیک است. این در مورد:
- تعریف مشکل به وضوح
- مشکل را به بخش های کوچک و ساده تقسیم کنید
- برای هر قسمت از مسئله راه حل را تعریف کنید
- پیاده سازی راه حل
- کارآمد کردن آن (در نهایت)
اما، صبر کنید، الگوریتم دقیقا چیست؟
همچنین، چرا باید اهمیت بدهم؟
قبل از شروع یادگیری در مورد الگوریتم ها، من از آنها می ترسیدم. من احساس کردم که آنها پیچیده، سخت برای یادگیری، و به شدت ریاضی است. الگوریتمها پیچیده و فراتر از توانایی من برای درک احساس میشدند. من تقریباً مطمئن بودم که دانستن آنها مهم است (مطمئناً مهم به نظر می رسیدند)، اما بهترین راه برای یادگیری بیشتر در مورد آنها را نمی دانستم.
با توجه به اینکه دائماً درباره الگوریتمهای جدید شرکتهای فناوری مانند الگوریتمهای جستجوی جدید گوگل و بهینهسازی رتبه صفحه یا الگوریتمهای اوبر برای یافتن بهترین سفر میشنویم، منطقی است.
ما سوالات الگوریتم را در مصاحبه های تخته سفید می شنویم و تجربه می کنیم. به طور مداوم در مورد اهمیت و پیچیدگی آنها به ما می گویند … اما بیشتر توسط افرادی در رسانه ها که چیز زیادی در مورد آنها نمی دانند.
شاید نگرانی شخصی من به این دلیل بود که کلمه “الگوریتم” بسیار شبیه “لگاریتم” بود که الگوریتم ها را با ریاضیات و مفاهیم دشوار مرتبط کردم.
مطمئن نیستم، اما اکنون که میدانم آنها واقعاً چه هستند، میخواهم به شما کمک کنم تا بر هر ترس، عدم اطمینان و شک در مورد آنها غلبه کنید.
“الگوریتم” یک اصطلاح کلی است که به نظر من وزن زیادی در توسعه نرم افزار دارد.
حقیقت ساده این است که الگوریتم ها فقط راه هایی برای انجام کارها هستند. آنها فرآیندهایی برای حل یک نوع مشکل هستند.
- پیدا کردن کلمه در فرهنگ لغت
- مرتب کردن لیستی از اعداد
- ایجاد دنباله فیبوناچی
- پیدا کردن اعداد اول
- پخت کیک
- شستشوی لباس
- درست کردن ساندویچ کره بادام زمینی و ژله
اکنون، انصافاً، بسیاری از الگوریتمهایی که این روزها خبرساز میشوند، چشمگیر و پیچیده هستند و به دانش عمیق تئوری علوم کامپیوتر، یادگیری ماشین و ریاضیات نیاز دارند. من مطمئنا اکثر آنها را نمی فهمم.
با این حال، فقط به دلیل وجود الگوریتمهای دشوار به این معنا نیست که همه الگوریتمها آنقدر پیچیده هستند.
برای شروع به تفکر الگوریتمی، میتوانید به یکی از دو روش به چالشها فکر کنید، حل مسئله و ایجاد راهحل.
تمایل طبیعی ما به عنوان توسعه دهندگان این است که ابتدا راه حل را بسازیم. با این حال، من در واقع از شروع با شکستن مشکل و تنها پس از ایجاد راه حل دفاع می کنم.
شکستن یک مسئله برای توسعه یک الگوریتم
اگر به طور طبیعی با حل مشکل شروع نمی کنید، نگران نباشید. حل کردن یک مشکل در ابتدا برای اکثر توسعه دهندگان و توسعه دهندگان مشتاق، از جمله من، به طور طبیعی اتفاق نمی افتد.
با این حال، صرف زمان برای تجزیه و تحلیل یک مشکل به ما کمک می کند تا مشکل را بهتر درک کنیم و ببینیم که چگونه راه حل ها به طور طبیعی از این درک سرچشمه می گیرند.
این امر به ویژه برای جلوگیری از غرق شدن در هنگام مواجهه با مشکل جدیدی که خارج از منطقه راحتی شما است مفید است.
مشکل جستجوی کلمه “bumfuzzle” را در فرهنگ لغت در نظر بگیرید (bumfuzzle به معنای “گیج کردن” است). در این مورد، بیایید فرض کنیم که فرهنگ لغت فهرستی از کلمات است، به معنای کلی و انگلیسی زبان کلمه “list”.
برای مشکلات جستجو، معمولاً باید بدانیم
- از کجا و چگونه جستجو را شروع کنیم
- چه زمانی و چگونه جستجو را متوقف کنیم
- چگونه دو آیتم لیست را با هم مقایسه کنیم تا مشخص کنیم کدام یک “قبل از” دیگری است
- وقتی هنوز کلمه ای را پیدا نکرده اید چگونه به جستجو ادامه دهید
هر چه یک الگوریتم بهتر باشد، زمان کوتاهتر بین یک و دو است و تعداد دفعات کمتری برای انجام شماره سه و چهار نیاز دارید.
برای مشکل جستجوی فرهنگ لغت خود، می توانیم سه گلوله بالا را گسترش دهیم و مشکل را به موارد زیر تقسیم کنیم:
- ترتیب مورد انتظار کلمات (به عنوان مثال، حروف الفبای انگلیسی)
- نحوه مقایسه دو کلمه مختلف و تعیین اینکه کدام یک باید قبل از دیگری باشد – مربوط به نقطه یک
- چگونه می دانیم که کلمه را پیدا کرده ایم
- چگونه بفهمیم این کلمه در فرهنگ لغت نیست
ما فرض می کنیم که نکات یک و دو با استفاده از الفبای انگلیسی برای ترتیب رعایت می شود و به راحتی می توانیم ترتیب کلمات را بر اساس ترتیب حروف الفبای آنها تعیین کنیم.
که دو مورد آخر باقی می ماند.
به طور طبیعی، ما می دانیم که زمانی کلمه را پیدا کرده ایم که کلمه در موقعیت جستجوی ما دقیقاً مشابه کلمه جستجوی ما باشد. اکثر زبان های برنامه نویسی این روزها می توانند تشخیص دهند که آیا دو کلمه یکسان هستند یا اینکه یکی از نظر حروف الفبا “قبل از” کلمه دیگری است. به طوری که از آن مراقبت می شود.
در مورد مورد چهار، اگر به انتهای جستجو برسیم و هنوز کلمه ای را پیدا نکرده باشیم، می دانیم که در لیست نیست. با این حال، این فرض میکند که ما سایر قسمتها را به درستی انجام دادهایم.
شروع
حال، چگونه میتوانید در وهله اول فکر کردن به این مشکلات را شروع کنید؟ باید از جایی شروع کنی، درسته؟
برای شروع کار بر روی یک مشکل، فکر کردن در ابتدا با استفاده از یک مجموعه نمونه بسیار کوچک از داده ها مفید است. اندازه باید به اندازه کافی آسان باشد تا بتوانید فکر کنید و در صورت لزوم بنویسید یا بکشید.
در ریاضیات، فرآیند اثبات از طریق استقراء وجود دارد. این ایده این است که اگر بتوانید ثابت کنید که یک فرمول ریاضی برای یک مورد 1 مورد کار می کند، و می توانید فرض کنید که برای n-1 مورد (که n تعدادی ناشناخته است) درست است، سپس، سعی کنید آن را برای یک مورد ثابت کنید. برای n مورد اگر فرمول برای n مورد کار می کند، پس فرمول باید برای هر تعداد آیتم کار کند.
با استفاده از این مفهوم برای الگوریتم ما: اگر بتوانیم آن را با 1 مورد در فرهنگ لغت درست کار کنیم، و سپس آن را با 10 مورد درست کنیم، احتمالاً میتوانیم آن را برای هر تعداد مورد کار کنیم. برای تأیید، در نهایت آن را با موارد بسیار بیشتری آزمایش خواهید کرد.
این تجمع آهسته به شما کمک می کند تا جزئیات را درک کنید و تله های ظریف مشکل را بیابید.
ساخت یک الگوریتم خوب
احتمالاً برای شما بسیار وسوسه انگیز است که با تلاش برای ایجاد راه حل شروع کنید. منم همینطورم ایجاد یک راه حل برای یک مشکل، کل نقطه کدنویسی برای شروع است، بنابراین منطقی است که بخواهیم بلافاصله وارد آن شویم.
من مواردی داشتم که خیلی سریع مشکل را حل کردم و چند روز کار کردم قبل از اینکه متوجه شدم نمیتوانم آنطور که فکر میکردم حلش کنم، زیرا متوجه نشدم که کد موجود روی مشکل چه تاثیری گذاشته است. مثل این است که نیمی از پخت کیک را طی کرده و متوجه شوید که تمام مواد لازم را ندارید، یا برای درست کردن آن باید یک تکنیک خاص هم زدن را بدانید.
من راه سختی را آموخته ام: اگر مشکلی را به طور کامل درک نکنیم، بهترین راه حل را نخواهیم ساخت – یا شاید هم بسازیم، اما رسیدن به آن زمان بیشتر طول می کشد.
اکنون، در نهایت (من عملاً میتوانم آهی با آرامش شما را بشنوم)، شما آماده شروع ساختن راهحل هستید، زیرا مشکل را تجزیه کردهاید تا تکههای آن را درک کنید.
در این مرحله به ساختن یک راه حل در بخش ها می پردازیم. هر بخش از راه حل به یک یا چند بخش از مشکلاتی که شما شناسایی کرده اید می پردازد.
نحوه ایجاد راه حل در حال حاضر، تا حدودی انعطاف پذیر است. برای من، من دوست دارم ابتدا ساده ترین و ساده ترین قسمت را بسازم، بنابراین موفقیت و چارچوبی برای ساخت بقیه راه حل ها داشته باشم.
در مورد جستجوی فرهنگ لغت، ممکن است راه حل را به این صورت بسازم:
- حلقه (یا تابع بازگشتی) را بنویسید
- کدی را بنویسید تا در صورت یافتن کلمه از حلقه/بازگشت خارج شوید
- اگر کلمه ای پیدا نشد و کل فرهنگ لغت را جستجو کردید، کدی را بنویسید تا از حلقه خارج شوید
- کدی را بنویسید که تصمیم میگیرد اگر کلمه پیدا نشد اما فرهنگ لغت تمام نشد چگونه جستجو شود
- موارد لبه، مشکلات شرایط مرزی و سایر جزئیات را برطرف کنید (مثل اینکه اگر یک لیست خالی را پاس کنید چه اتفاقی می افتد؟)
الگوریتمهای جستجو و مرتبسازی مکانهای خوبی برای شروع به کار گرفتن تفکر الگوریتمی هستند، زیرا مرتبط هستند، نسبتاً مستقل هستند، ترسیم و گامبهگام آسان هستند و در پیچیدگیهای زیادی ایجاد میشوند.
دنیای واقعی ™
اگرچه این فرآیند اغلب برای اکثر وظایف توسعه در دنیای واقعی کمتر آشکار است.
در اکثر مشاغل توسعهدهنده، شما در حال رفع نقص در یک پایگاه کد موجود یا اضافه کردن ویژگیها به آن هستید.
شما همچنان باید یک مشکل را به کوچکترین قسمت های آن تقسیم کنید و شروع به ساختن راه حل به صورت تکه تکه کنید تا به هر یک از آن قسمت ها رسیدگی کنید. اما احتمالاً شامل طراحی کلاسها، روشهای آنها و گره زدن همه آنها با هم خواهد بود.
همانطور که به آرامی از کوچک و ساده به بزرگ و پیچیده تبدیل میشوید، هر مرحله را قابل مدیریت و جدا نگه میدارید. شما تغییرات را به آرامی وارد می کنید و بنابراین وقتی همه چیز گلابی شکل می شود، دلایل احتمالی کوچک هستند و به راحتی کشف می شوند.
همچنین، مهم است که به خاطر داشته باشید که ممکن است در ابتدا ندانید چگونه یک اصلاح یا ویژگی را پیاده سازی کنید. در واقع، این احتمال وجود دارد که در ابتدا ندانید چگونه آن را اجرا کنید. این امر به ویژه در صورتی صادق است که در حال اضافه کردن ویژگیها یا رفع نقص در یک پایگاه کد موجود هستید، که در اکثر مشاغل توسعهدهنده بسیار رایج است.
من مواردی داشتهام که روزها یا حتی هفتهها را صرف کارهای مختلف کردهام تا مشخص کنم چگونه میتوانم یک ویژگی یا یک اصلاح را پیادهسازی کنم. در پایان، من چیزی دارم که کار می کند، اما زشت و ناکارآمد بود. اما این آزمایش به من این دانش را داد که به عقب برگردم و کد را به روشی بسیار تمیزتر و کارآمدتر بازنویسی کنم.
به خودتان اجازه آزمایش راهحلها را بدهید و این واقعیت را بپذیرید که احتمالاً باید چندین بار تلاش کنید تا آن را به کار ببندید، سپس حتی بیشتر برای اینکه آن را کارآمد و تمیز کنید.
چگونه در تفکر الگوریتمی بهتر شویم
یکی از سوالات قدیمی. چگونه در هر مهارتی بهتر شویم؟
پاسخ ساده – و آزاردهنده – تمرین است. مانند OOD و برنامه نویسی به طور کلی، تجربه چالش ها و یادگیری از آنها احتمالاً بهترین راه برای بهتر شدن است.
اما میتوانید با یادگیری الگوریتمهای موجود و پیادهسازی آنها به زبانهای مختلف یا روشهای مختلف، این روند را تسریع کنید.
مطالعه الگوریتم های موجود
درک الگوریتم هایی که پایه و اساس بسیاری از مفاهیم اساسی برنامه نویسی را تشکیل می دهند، مسلماً چیز خوبی است. در اینجا میخواهید به جزئیات یک الگوریتم تثبیت شده بپردازید تا بفهمید که چه کاری انجام میدهد و چرا – تأکید بر «چرا». شخصاً برای درک بهتر آن باید دوباره آن را پیاده سازی کنم.
بیشتر مکالمات در کتابها و کلاسها حول چند الگوریتم جستجو و مرتبسازی شناخته شده میچرخند که در زیر به آنها اشاره میکنم. این الگوریتمهای خاص مکانهایی برای شروع هستند زیرا جستجو و مرتبسازی دو اقدامی هستند که تقریباً هر توسعهدهندهای باید در مقطعی از حرفه خود انجام دهد. علاوه بر این، الگوریتمهای جستجو و مرتبسازی مبنای خوبی برای درک کارایی الگوریتم و موارد لبه فراهم میکنند.
در واقع، دونالد کنوت در مقدمه جلد سوم خود از هنر برنامه نویسی رایانه ای می گوید که او معتقد است جستجو و مرتب سازی مکان های خوبی برای شروع هستند زیرا شما را به فکر کردن در مورد آنها وادار می کند:
- نحوه ایجاد الگوریتم های جدید
- چگونه الگوریتم ها را می توان بهبود بخشید
- چگونه می توانید کارایی یک الگوریتم را تعیین کنید
- چگونه می توانید بین الگوریتم های مختلف یکی را انتخاب کنید
جستجو و مرتبسازی فعالیتهای مرتبطی هستند و الگوریتمها معمولاً بر روی یکدیگر ساخته میشوند و بر روی نسخههای قبلی اصلاح و بهبود مییابند. این به شما این فرصت را می دهد تا ببینید که چگونه می توانید به سادگی با یک الگوریتم ساده شروع کنید و به آرامی آن را بهبود بخشید همانطور که یاد می گیرید کجا (و چگونه) ناکارآمد است.
در اینجا برخی از الگوریتم های جستجو و مرتب سازی مهم وجود دارد که هر توسعه دهنده باید بتواند توضیح دهد.
- جستجوکردن
- جستجوی خطی
- جستجوی باینری
- مرتب سازی
- مرتب سازی درج
- مرتب سازی انتخابی
- مرتب سازی حبابی
- Heapsort
- مرتب سازی ادغام
- مرتب سازی سریع
خوشبختانه، احتمالاً هرگز مجبور نخواهید شد که هیچ یک از این الگوریتم ها را به عنوان یک توسعه دهنده حرفه ای پیاده سازی کنید. این روزها، کارآمدترین الگوریتمهای جستجو و مرتبسازی در کتابخانههای استانداردی که با اکثر زبانها ارائه میشوند، ارائه میشوند.
با این حال، فقط به این دلیل که مجبور نیستید نسخهای از مرتبسازی حبابی یا جستجوی باینری بنویسید، دلیل خوبی برای نادیده گرفتن درک و نوشتن آنها نیست.
این الگوریتم ها پایه و اساس درک الگوریتم ها را به عنوان یک کل تشکیل می دهند. آنها به شما می آموزند که چگونه کارایی الگوریتمی تأثیرات دنیای واقعی دارد و چگونه الگوریتم های جدیدتر، کارآمدتر و پیچیده تر توسعه داده می شوند.
چگونه تفکر الگوریتمی را تمرین کنیم
مانند هر مهارتی، تمرین آن شما را در آن بهتر می کند.
با این حال، روشی که شما پیشرفت می کنید با مهارت های فیزیکی متفاوت است، جایی که می توانید آن را بارها و بارها به همان روش انجام دهید و به آرامی بهتر شوید. چند بار می توانید در پایتون یک هپ سورت بنویسید و همچنان پیشرفت کنید؟ من واقعاً جواب را نمی دانم، اما حدس می زنم که تعداد زیادی نباشد.
در مورد الگوریتم ها، تکرار ساده چندان کمکی نمی کند. شما از آن سود خواهید برد، اما وظیفه واقعی این نیست که یک الگوریتم را به خوبی بشناسید، بلکه ایجاد الگوریتم های جدید و توانایی پیاده سازی و ارزیابی آنها در صورت نیاز است.
برای این منظور، مانند OOD و سایر مهارتهای کدنویسی، به چالشهای مختلفی نیاز دارید که همگی حول نیاز به حل یک مشکل میچرخند.
علاوه بر این، برای به دست آوردن سود، باید بدانید که چقدر خوب کار می کنید. شرکت در آزمون تمرینی اما دسترسی نداشتن به پاسخ ها چقدر مفید است؟
با کدنویسی، بخشی از چالش این است که راههای زیادی برای حل همان مشکل وجود دارد. بدون اینکه بدانید راه حل شما چگونه می تواند بهتر باشد، چگونه می توانید بهتر شوید؟
برای انجام این کار، باید راهی برای ارزیابی اجرای خود داشته باشید، ترجیحاً یک روش عینی. چند راه ساده عبارتند از:
- راه حل خود را زمان بندی کنید همانطور که تغییرات ایجاد می کنید، به سادگی ببینید که آیا زمان کوتاه تر می شود (اکثر زبان ها روش های داخلی برای کمک به شما در انجام این کار دارند).
- از یک توسعه دهنده با تجربه تر به راه حل خود نگاه کنید.
- با چالش های کد تمرین کنید. بسیاری از سایتهای چالش کد آنلاین پاسخ «درست» را برای مقایسه به شما میدهند، و برخی واقعاً راهحل شما را ارزیابی میکنند.