<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های حسان امینی لو</title>
        <link>https://virgool.io/feed/@hesanam</link>
        <description>برنامه نویس از جلو</description>
        <language>fa</language>
        <pubDate>2026-06-16 02:30:33</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/74138/avatar/iSk2IL.jpg?height=120&amp;width=120</url>
            <title>حسان امینی لو</title>
            <link>https://virgool.io/@hesanam</link>
        </image>

                    <item>
                <title>یادداشت - کاری که همیشه دوست داشتم انجام بدم!</title>
                <link>https://virgool.io/@hesanam/%DB%8C%D8%A7%D8%AF%D8%AF%D8%A7%D8%B4%D8%AA-%DA%A9%D8%A7%D8%B1%DB%8C-%DA%A9%D9%87-%D9%87%D9%85%DB%8C%D8%B4%D9%87-%D8%AF%D9%88%D8%B3%D8%AA-%D8%AF%D8%A7%D8%B4%D8%AA%D9%85-%D8%A7%D9%86%D8%AC%D8%A7%D9%85-%D8%A8%D8%AF%D9%85-bhb8exye27xr</link>
                <description>از ۴ سالگی دارم گیم میزنم! همیشه عاشق اینکار بودم. کم شده بعضی وقتا ولی همیشه باهام بوده. همیشه دوست داشتم یه کاری تو زمینه گیم انجام بدم. برای همین کلی رفتم راجع به گیم و گیم دیزاین مطالعه کردم. ابزار یاد گرفتم. یکم از ابعاد مختلف به موضوع نگاه کردم... سعی کردم چرایی چیز ها رو بفهمم.دیگه گیم برام یه تفریح نیست. یه کلاس درسه که از هر کدوم اش دارم چیزی یاد می‌گیرم. شاید یه روز شروع کنم یه بازی توسعه بدم برای خودم. اما اول دوست دارم یاد بگیرم چطور میشه اینکارو درست انجام داد.این مطالب رو دوست داشتم تو یه قالب ارائه بدم، ولی متن بستر مناسبی برای اینکار نیست. برای همین یه کانال یوتوب زدم، اینجا راجع به گیم حرف میزنم ولی نه حرفای معمولی. دوست دارم راجع به چیزایی توش حرف بزنم که کنجکاوی خودم بوده و هست.دوست داشتین یه نگاهی بندازید.https://www.youtube.com/@ThePlayMind</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Tue, 11 Nov 2025 18:54:30 +0330</pubDate>
            </item>
                    <item>
                <title>هوش مصنوعی - مرگ تدریجی، تولد دوباره</title>
                <link>https://virgool.io/@hesanam/%D9%87%D9%88%D8%B4-%D9%85%D8%B5%D9%86%D9%88%D8%B9%DB%8C-%D9%85%D8%B1%DA%AF-%D8%AA%D8%AF%D8%B1%DB%8C%D8%AC%DB%8C-%D8%AA%D9%88%D9%84%D8%AF-%D8%AF%D9%88%D8%A8%D8%A7%D8%B1%D9%87-gzcbsajyveol</link>
                <description>بذارید رک بگم - به نظرم دیگه آموزش به شکل سنتی دیگه معنی نداره. واقعا دوره ویدئو های آموزشی تموم شده یا در آینده ای نزدیک تمام خواهد شد. سرچ که دیگه عملا از بین رفته، کسی دیگه سراغ Stackoverflow نمیره یا خیلی خیلی کم میره. شیوه برنامه نویسی و حل مساله خیلی تغییر کرده. ابزار های جدید بوجود اومدن، شیوه ها تغییر کرده...تصویر از ChatGPTقبلا تو یه پست در مورد اینکه آیا هوش مصنوعی برنامه نویس ها رو بیکار میکنه یا نه توضیح داده بودم. هنوزم پای حرفم هستم. هنوز هم به نظرم هوش مصنوعی نمیتونه جای کسی رو بگیره ولی مدل کار کردن ما خیلی رو عوض میکنه. نکته اساسی اینجاست که در پی این موج عظیم هوش مصنوعی و کلمه AI که روز و شب داریم می‌شنویم، این تغییرات غیر قابل انکار هستن.البته این تغییرات محدود به دنیای برنامه نویسی نمیشن. مثلا روانشناسی، من مدت هاست که دیگه جلسات تراپی نمیرم، بیشتر به کمک هوش مصنوعی دارم با چالش های روزمره ام کنار میام و با اون پیش میرم. جالب ماجرا اینجاست که تشخیص های بسیار دقیق و درستی هم میده و راه کار هاش کاملا بر اساس سلایق، برنامه ها و اهدافی هست که قبلا از خودم گرفته.یا برنامه ریزی مالی، مشاوره سرمایه گذاری، برنامه ورزشی، دنبال کردن اخبار، مشاوره برای انتخاب بهترین تنظیمات سیستم، انتخاب محله مناسب برای زندگی و .... عملا میتونم به جرات بگم، الان در دورانی زندگی می‌کنیم که واقعا هر کسی با هر سطحی از نیاز، میتونه کارشو به کمک هوش مصنوعی انجام بده.حتی تو یکسال اخیر مبحث Agent ها و دستیار های هوش مصنوعی، پا رو فراتر گذاشتن و خیلی کار ها رو با اجازه‌ی شما انجام میدن. بذارین یه مثال بزنم:من با GPT صحبت می‌کنم و از احوال روزمره ام براش توضیح میدم، ازش راهکار میخوام که چطور میتونم حال روحیم رو بهتر کنم،‌ از طرفی راجع به درآمدم و اینکه چطور سرمایه گذاری کنم باهاش صحبت میکنم. از طرف دیگه برای کمر دردم هم ازش کمک میخوام که راهنماییم کنه چه ورزش هایی رو انجام بدم.پس با توجه به این اطلاعاتی که در اختیار این ابزار قرار گرفته، و با توجه به اینکه دیگه میتونیم بگیم همه این ابزار ها از قابلیت Memory پشتیبانی می‌کنن، یادشون هست که شما درگیر چه چیز هایی هستید، چه خط قرمز هایی دارید، الویت بندی شما چی هست و کلی چیز دیگه.حالا میتونم بعد از گرفتن یه خروجی مناسب از GPT برای خوراک یه هوش مصنوعی دیگه به کمک Agent ها اطلاعات رو از GPT دریافت کنم و ازش بخوام که برنامه ۷ روز آینده من رو بر اساس نیاز های شخصی سازی شده من روی Google Calender برنامه ریزی کنه. توی این برنامه هفتگی از رسیدگی به کار های روزمره مثل نظافت و انجام وظایف شغلیم و Laundry (کلمه فارسی مناسب میشه لباسشویی ولی جالب نی)  گرفته تا برنامه ریزی ورزش های کوتاه ۱۵ دقیقه ای بین کارم یا آخر روزم. حالا Google Calendar ام روی موبایلم هم نصب هست و برای هرکاری به من یه Notif میده که فلان موقع، زمان انجام اینکار هست.ممکنه فکر کنید که خیلی ممکنه بره روی اعصابتون با این کار، اشکالی نداره! میتونید تنظیمات رو عوض کنید تا کمتر بهتون فشار بیاد. بعضی کار ها رو که خیلی ساده میتونید بدید n8n براتون به شکل خودکار انجام بده!‌ مثلا اگه شمام مثل من یه خانواده پر جمعیت دارید که هر ماه تولد یه نفر هست و یادتون میره که بهش تبریک بگید، به جای اینکه دستی اینکارو کنید، میتونید به صورت اتوماتیک انجامش بدید، میدونم که مثلا Telegram قابلیت schedule رو داره ولی صرفا میخوام مثال بزنم براتون.تولید محتوا که دیگه از ساده ترین کار هایی هست که میتونن انجام بدن، عملا شما می‌تونید یه تیم کامل اعم از ویراستار، استراتژیست و کلی رول دیگه که من بلد نیستم رو به کار بگیرید.من تقریبا میتونم بگم مدت خیلی طولانی ای هست که کدی رو از صفر شروع نمیکنم، در عوض بهتر یاد گرفتم که مسائل رو به قسمت های کوچکتر تقسیم کنم و به کمک ابزار هایی مثل Cursor و مدل هایی مثل Claude دیگه بیشتر درگیر اینم که یه Prompt خوب بنویسم و ازش بخوام اون برام کار رو انجام بده و خودم تر تمیزش کنم و مرتبش کنم و بفرستم و بره بالا.تجربه من شاید با شما متفاوت باشه، ولی شرکتی که الان توش مشغول هستم، نه تنها استفاده کردن از این ابزار ها رو دیگه کاملا عادی میدونن، بلکه حتی تشویق هم به استفاده شون میکنن و ابزار ها رو با لایسنس در اختیارمون قرار میدن. نگرانی ای هم در مورد اینکه روزی بخواد جای برنامه نویس ها رو بگیره نداریم (بار ها توسط افراد این سوال مطرح شده) چون بالاخره که یه نفر باید همچنان به این ابزار ها بگه که چطور کار کنن. پس داریم خودمونو تطبیق می‌دیم! خلاف جهت شنا نمی‌کنیم.مرگ آموزش سنتیاول مطلب اشاره کردم و با مقدماتی هم که چیدم توضیح دادم که این ابزار ها اگر به شکل درست استفاده بشن می‌تونن چطور به کمکمون بیان. خلاصه که وقتی یه ابزار هوش مصنوعی در مورد شما اطلاعات کافی به دست بیاره، میتونه راه حل های منحصر به فرد شخص شما رو در اختیارتون بذاره. با ملاحظه تمام احوالات روحی شما، شرایط مالی شما و حتی زمان آزاد شما.البته فراموش نکنیم،‌ این ها تا جایی درست کار میکنه که شما اطلاعات بهش داده باشین، انتظار نمیتونیم داشته باشیم که از ناکجا همه چیز رو در مورد ما بدونن. اینکه شما انتخاب کنید این اطلاعات رو در اختیار این ابزار ها بذارید هم یه نکته دیگه است.حالا ناظر بر همه این موارد، دیگه چه لزومی داره من وقتم رو بذارم پای یک محتوای ۵۰ ساعته که مثلا Javascript یاد بگیرم؟ در حالی که میتونم استارت کار رو خیلی ساده بزنم و هر جا که گیر میکنم از هوش مصنوعی بخوام که موضوع رو برام شرح بده، ساده سازی کنه، مثال بزنه، با سرعت خودم پیش برم، نیاز هام رو توضیح بدم که حتی خیلی مواقع وقت الکی هم نذارم.پس به نظرم انقلابی در حوزه آموزش بوجود اومده و مطمینا گسترده تر هم خواهد شد.کمتر شدن هزینه زندگیمجدد با توجه به تاثیر غیر قابل انکاری که امروزه این ابزار ها توی زندگی ما گذاشتن، خیلی جاها توی خیلی هزینه ها میشه صرفه جویی کرد. من قبلا ماهی ۲۰۰ یورو هزینه مشاوره میدادم، شاید سالانه خیلی هزینه های پنهان دیگه داشتم که به خاطر عدم اطلاعات کافی خودم تو یک زمینه ای مجبور بودم یه سرویسی رو خریداری کنم. ولی الان خیلی از این هزینه ها کنار رفتن. حداقل برای من شخصا این مورد اتفاق افتاده.یادمون نرهسوال اساسی اینجاست که، پس با وجودی که امروز هوش مصنوعی میتونه این همه کار رو انجام بده، ما کجای داستانیم؟ ما باید چه کار کنیم؟به نظر من حقیر، باید یاد بگیریم با تغییرات حرکت کنیم. استفاده از این ابزار ها رو درست یاد بگیریم. توقعات مون از این ابزار ها رو به شکل معقول داشته باشیم. یاد بگیریم که چطور فکر کنیم، چطور به شکل درست بتونیم سوال مون رو از این ابزار ها بپرسیم که بهترین نتیجه رو بگیریم.در نهایت یادمون نره که این ها همه ابزار هستند نه چیزی بیشتر. در آخر آخر آخر داستان همه چیز برمی‌گرده به خود ما آدم ها.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Mon, 22 Sep 2025 17:32:36 +0330</pubDate>
            </item>
                    <item>
                <title>پرفورمنس، برای React Developer ها - قسمت ۱</title>
                <link>https://virgool.io/@hesanam/%D9%BE%D8%B1%D9%81%D9%88%D8%B1%D9%85%D9%86%D8%B3-%D8%A8%D8%B1%D8%A7%DB%8C-react-developer-%D9%87%D8%A7-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-lhd9vpcvncbp</link>
                <description>این روز ها که میشه با AI تقریبا هر کدی رو نوشت و خیلی ها از این ابزار برای نوشتن کد ها استفاده میکنن، ارزش کد نوشتن (صرفا نوشتن و تولید کد) داره کمتر میشه. تقریبا هرکسی میتونه هر اپلیکیشنی رو با React بنویسه. ولی فقط کد زدن تنها یه تیکه از این پازل هست. همچنان نیاز داریم که اپلیکیشن ها رو یه جایی Deploy کنیم، به کاربرا نمایشش بدیم، اون رو Maintainable تر کنیم، سرعتش رو بهبود بدیم و کلی کار دیگه که البته هنوز AI نمیتونه اینکارارو انجام بده. البته هنوز.پس بیاید امروز، همونطور که از عنوان مطلب هم پیداست، روی &quot;سریع&quot; تر کردن اپلیکیشن هامون تمرکز کنیم. برای اینکه اینکارو انجام بدیم اول باید کلا React رو بذاریم کنار. چون قبل از اینکه بخوایم چیزی رو سریع تر کنیم، اول باید بفهمیم اصلا &quot;سریع&quot; یعنی چی، چطور اندازه گیریش کنیم و چه چیزهایی هستند که روی این &quot;سریع تر&quot; شدن تاثیر میذارن.فقط قبلش اینو بگم: فعلا توی این قسمت خبری از React نیست! موضوع این مطلب فقط مبانی پایه ای و اصولی Performance هستن: اینکه چطور از ابراز های Performance استفاده کنیم، یه مقدمه ای بر Core Web Vitals (که احتمالا بار ها اسمش رو شنیدید)، ابزار های اندازه گیری توی Chrome، اینکه Initial Load Performance یعنی چی، چه شاخص (metric) هایی برای اندازه گیریشون داریم و چطور cache یا شرایط اینترنت (یا همون Network) روی اون میتونن تاثیر بذارن.قبل از ادامه لطفا حتما توضیحات زیر رو بخونید:منبع من توی این مطلب، نوشته ارزشمند Nadia هست که توی این لینک میتونید مطلب اصلی رو بخونید. خیلی دوست داشتم شرایط اجازه میداد که میشد کتابی که چند وقت پیش از همین نویسنده خوندم با عنوان Advanced React و آخرین کتابی که اخیرا (تیر ماه ۰۴) منتشر شده در مورد Performance رو ترجمه فارسی کنم و به صورت قانونی توی ایران برای همه در دسترس قرار بدم.ولی بعد از صحبت با ایشون و البته محدودیت های Copyright توی ایران و تحریم و هزار چیز دیگه، نتیجه نهایی این شد که نوشته های ایشون توی وبسایت Developerway رو به صورت مقاله به فارسی منتشر کنم.برای من که هر دو کتاب ها رو خوندم و مقاله ها رو هم نگاهی انداختم متوجه شدم که مطالب کتاب و مقاله های سایت باهم تفاوت چندان زیادی ندارند. در هر صورت این مطلب و قسمت های بعدی تا جای ممکن از نظر محتوا وفادار به منبع خواهند بود و صرفا من سعی کردم یه متن روان و راحت رو اینجا بنویسم.ضمنا، برای ترجمه از هیچ ابزار AI استفاده نشده، برای اینکه خودمم بتونم نهایت استفاده رو از مطالب ببرم، تصمیم گرفتم خودم خط به خط اینکارو انجام بدم، گرچه برای امتحان کردن هم که شده سعی کردم از ChatGPT استفاده کنم ولی متن ترجمه اصلا جالب نبود و اثری از قلم خودم توش نبود، پس امیدوارم از ترجمه من لذت ببرید.معرفی شاخص های (Metric) پرفورمنس در Initial Loadزمانی که ما مرورگر رو باز میکنیم و یه سایت رو باز میکنیم، دقیقا چه اتفاقی میوفته؟ فرضا مینویسیم http://www.my-website.com و مرورگر یه درخواست GET برای سرور ارسال میکنه و در جواب یه صفحه به صورت HTML برای ما برمیگرده. (توضیحات خیلی مفصل رو اینجا میتونید بخونید)مدت زمانی که طول میکشه تا این اتفاق بیوفته رو بهش میگیم TTFB یا Time To First Byte. یعنی زمانی که مرورگر درخواست رو ارسال میکنه تا زمانی که جواب سرور شروع میکنه به جواب دادن. بعد اینکه HTML دریافت شد، حالا مرورگر باید اون رو به شکل قابل استفاده ای واسه کاربر نمایش بده. بنابراین مرورگر شروع میکنه به رندر کردن صفحه، فرایندی که بهش میگیم Critical Path. یعنی مهم ترین و مینیمال ترین حالتی از محتوا که بشه به کاربر نمایشش داد.اینکه دقیقا چه چیزی باید توی Critical Path باشه سوال پیچیدهای هست. در حالت ایده آل، همه چیز هایی که کاربر بتونه به صورت کامل تجربه شون کنه ولی در عین حال، هم میخوایم که محتوا کمترین حد خودش باشه! چون نیاز داریم که در سریع ترین زمان ممکن این اتفاق بیوفته، چون که اصلا اسمش روشه: Critical Path (چیز های حیاتی یا واجب) پس نمیتونیم هم خر رو بخوایم و هم خرما رو. پس باید یه &quot;بده بستون&quot; داشته باشیم.این &quot;بده بستون&quot; برای ما این شکلیه: مرورگر برای اینکه محتوا رو نمایش بده قطعا به این منابع احتیاج داره:کد ها و المان های HTML اولیه که از سرور میاد (برای ساختن DOM)کدهای مهم CSS که اون المان های HTML که قبلا گرفتیم رو شکل بدن - در صورت عدم وجودشون لحظات اول، کاربر ممکنه یه &quot;فلش&quot; از محتوای زشت و لخت HTML ببینه که یهو استایل ها بهشون اعمال میشه.فایل های حیاتی JS که layout صفحه رو دستکاری (یا کنترل) میکنن.توی اولی (HTML) که مرورگر توی اون درخواست اول از سمت سرور دریافت میکنه، شروع میکنه به Parse کردنش و همزمان با این اتفاق لینک هایی که به فایل های CSS و JS اشاره دارن که برای تکمیل Critical Path بهشون نیازه رو هم استخراج میکنه. بعد مجدد برای دریافت اون فایل ها (همون CSS و JS ها) درخواست میفرسته به سرور، صبر میکنه که دانلود بشن، پردازششون میکنه، ترکیب شون میکنه و در نهایت این پیکسل ها رو روی صفحه نشون میده! (تقریبا تمام مراحلی که توی این مقاله بهشون اشاره کردم قبلا)از اونجایی که مرورگر نمیتونه رندر اولیه رو بدون اون فایل های CSS و JS انجام بده (چون فایل های حیاتی یا Critical هستند) ما اونا رو به عنوان منابع render-blocking میشناسیم. البته همه فایل های CSS و JS حالت render-blocking ندارند اونا فقط در زمانی به این حالت در میان که:بیشتر CSS ها، چه اونایی که به صورت inline نوشته شدن و چه اونایی که توی تگ &lt;link&gt; هستن.فایل های JS که توی تگ &lt;head&gt; باشن که حالت async یا defer نباشن.به صورت کلی پس میتونیم کل فرایند Critical Path رو اینطور جمع بندی کنیم:مرورگر HTML اولیه رو parse میکنههمزمان با این اتفاق لینک های مرتبط با CSS و JS رو از تگ &lt;head&gt; استخراج میکنهبعد شروع میکنه به دانلود کردن اون فایل ها (که بهشون میگفتیم render-blocking چون باید تا دانلودشون صبر کنه)تو همین زمانی که ممکنه داشته باشه (در حین دانلود اون فایل ها) به parse کردن باقی HTML ها ادامه میدهبعد اینکه همه منابع حیاتی دریافت شد، پردازش انجام میشهدر نهایت همه کار های لازم برای اینکه در انتها پیکسل ها روی صفحه نقش ببندن انجام میشه و کار تماماین مقطع از زمان رو بهش میگیم رسم (paint) اولیه یا همون First Paint یا FP. این اولین موقعی هست که کاربر میتونه یه چیزی روی صفحه ببینه. اینکه این اتفاق بیوفته یا نیوفته کاملا بستگی به HTML ای که سرور ارسال کرده داره. اگه چیز با معنایی اونجا باشه مثل یه متن یا تصویر، اینجا جایی میشه که بهش میگیم First Contentful Paint یا FCP. اگه HTML خالی باشه مثلا مثل یه div خالی، مرحله FCP بعدا اتفاق میتونه بیوفته.مرحله First Contentful Paint یکی از مهم ترین شاخص ها (metric) برای اندازه گیری Performance یا عملکرد اپلیکیشن ماست. این نشون میده که سایت از نظر کاربر چقدر زود شروع به لود شدن کرده. یعنی اون حس اولیهی «سایت سریع باز شد یا نه» رو اندازه میگیره.تا این لحظه، کاربرا فقط دارن به صفحهی خالی زل میزنن و معطل شدن! طبق گفتهی گوگل، یه عدد خوب برای FCP کمتر از ۱.۸ ثانیهست. اگه بیشتر از این طول بکشه، کاربرا کمکم علاقهشونو به اپلیکیشن از دست میدن و ممکنه صفحه رو ببندن و برن.البته این معیار بهترین معیار نیست. مثلا اگه اپلیکیشن با یه اسپینر یا صفحهی لودینگ شروع بشه، همون به عنوان FCP ثبت میشه. ولی خب بعیده کسی وارد سایت بشه فقط برای دیدن یه صفحهی خوشگل لودینگ! بیشتر وقتا، کاربرا دنبال محتوا هستن، نه افکتهای نمایشی.برای اینکه محتوا به کاربر نشون داده بشه، مرورگر باید کارایی که شروع کرده رو تموم کنه. یعنی باید JS هایی که اجرای اونها مانع بارگذاری نمیشن (همون non-blocking) رو هم اجرا کنه، تغییراتی که این کد ها ایجاد میکنن رو روی صفحه اعمال کنه (تغییرات مربوط به DOM)، عکسها رو دانلود کنه و خلاصه همه چیز رو ردیف کنه تا تجربه خوبی به کاربر بده.یه جایی وسط این فرایند، زمان Largest Contentful Paint یا LCP اتفاق میافته. برخلاف FCP که فقط اولین چیز نشون داده شده رو بررسی میکنه، LCP تمرکزش روی بخش اصلی و بزرگترین محتوای صفحهست، مثل بزرگترین متن، عکس یا ویدیویی که توی صفحه دیده میشه.طبق گفته گوگل این عدد بهتره زیر ۲.۵ ثانیه باشه. اگه بیشتر طول بکشه، کاربر فکر میکنه سایت کند داره لود میشه.همهی این معیار (Metric) هایی که گفتیم، بخشی از Web Vitals گوگل هستن — یه سری معیار که تجربهی کاربر از یه صفحه رو اندازهگیری میکنن. LCP یکی از سه مورد اصلی توی Core Web Vitals حساب میشه — یعنی سه تا معیاری که هرکدوم یه بخش متفاوت از تجربهی کاربر رو پوشش میدن. LCP مسئول بخش «سرعت لود شدن محتوا» یا همون عملکرد بارگذاریه.این معیارها رو میتونیم با Lighthouse اندازهگیری کنیم. Lighthouse یه ابزار بررسی عملکرد از طرف گوگله که توی Chrome DevTools هم به صورت built-in وجود داره، ولی میشه ازش با Shell Script یا UI یا به صورتNode Module هم استفاده کرد.اگه بخوایم توی فرایند build پروژه ازش استفاده کنیم، میتونیم از node module اش استفاده کنیم که قبل از اینکه به مرحله Production برسه مشکلات اپلیکیشن رو ببینیم و فیکس کنیم.برای دیباگ و تست لوکال، DevTools بهترین گزینهست. ولی اگه بخوایم عملکرد سایتهای رقیب رو بررسی کنیم، نسخهی وبش بهدرد میخوره.مروری کلی بر ابزار Performance توی DevToolsهمهی چیزایی که بالا گفتیم یه توضیح خیلی خلاصه و سادهشده از ماجرا بود. ولی همینم پر از اصطلاح و تئوریه که ممکنه آدمو گیج کنه! راستش برای من (نادیا) خوندن اینجور چیزا خیلی فایده نداره. چون اگه با چشم نبینم و باهاش بازی نکنم، همه چی از ذهنم میپره.برای این موضوع خاص، بهترین راهی که من برای درک کاملش پیدا کردم اینه که سناریوهای مختلف رو روی یه پروژه نیمه واقعی شبیهسازی کنیم و ببینیم چطور نتیجه رو تغییر میدن. پس بیایم دقیقاً همین کار رو کنیم، قبل از اینکه بریم سراغ تئوریهای بیشتر (که واقعاً کلی چیز دیگه هم هست!).ستاپ پروژهمیتونید همه شبیهسازی ها رو روی پروژه خودتون انجام بدین اگه دوس دارین، نتایج کم و بیش باید یکسان باشن. ولی برای سادگی و کنترل بیشتر من پیشنهاد میکنم که از این پروژه به صورت Case study استفاده کنیم. پروژه اینجا قابل دسترسه.بعد اینکه پروژه رو کلون کردین به ترتیب دستورات رو اجرا کنید.نصب dependency ها:npm installبیلد پروژه:npm run buildراه اندازی پروژه روی لوکال:npm run startحالا باید روی لوکال http://localhost:3000 یه دشبورد خوشگل ببینید!ابزار های واجب DevToolsاپلیکیشنی که میخوایم تحلیلش کنیم رو توی Chrome باز میکنیم و ابزار Chrome DevTools رو باز میکنیم. بعد، پنلهای &quot;Performance&quot; و &quot;Lighthouse&quot; رو پیدا کنید و بیاریدشون کنار هم، چون به هر دوتاشون نیاز داریم. همچنین قبل از انجام هر کاری که توی این مقاله گفته شده، حتماً مطمئن شید که گزینهی &quot;Disable cache&quot; فعال باشه. با فعال کردنش، مطمئن میشیم که مرورگر کش قبلی رو استفاده نمیکنه و نتایج دقیقتری به دست میاد.این کار برای اینه که بتونیم شرایط کاربرای تازه وارد رو شبیهسازی کنیم — یعنی کسایی که تا حالا وارد سایت ما نشدن و مرورگرشون هیچ فایل یا منابعی از قبل کش نکرده. با غیرفعال کردن کش، رفتار مرورگر مثل یه بازدید اول واقعی خواهد بود.امکانات پنل Lighthouseحالا پنل Lighthouse رو باز کنید. چندتا تنظیمات میبینیم و یه دکمه به اسم &quot;Analyze page load&quot;.تو این بخش، حالت &quot;Navigation&quot; برامون مهمه — این حالت یه تحلیل دقیق از بارگذاری اولیهی صفحه انجام میده.بعد از اجرا، یه گزارش کامل بهت میده که شامل امتیازهایی مثل اینهاست:Performance: عملکرد کلی بارگذاریAccessibility: دسترسیپذیری صفحهBest Practices: رعایت اصول کدنویسی و امنیتSEO: بهینهسازی برای Search Engine هاPWA (اگه فعال باشه): وضعیت اپلیکیشن در حالت PWAاین امتیازها بهت کمک میکنن بفهمی سایتت از نگاه کاربر چقدر سریع و درست لود میشه.عملکرد سایت بهصورت لوکال عالیه، که تعجبی هم نداره — همه چیز همیشه روی سیستم خودمون «درست کار میکنه»! 😄این معیار ها هم هستند:مقادیر FCP و LCP که برای این مقاله نیاز داریم، دقیقاً در بالای گزارش دیده میشن.کمی پایینتر، یه لیست از پیشنهادها میبینیم که میتونن بهمون کمک کنن امتیاز عملکرد رو بهتر کنیم — مثلاً کاهش حجم تصاویر، بهینهسازی فونتها، حذف جاوااسکریپتهای اضافی و غیره.هر کدوم از این پیشنهادها رو میتونیم باز کنیم تا اطلاعات دقیقتری ببینیم — بعضی وقتا حتی لینکهایی داره که اون موضوع خاص رو کاملتر توضیح میدن. البته همهی این پیشنهادها قابل اجرا نیستن، ولی واقعاً ابزار فوقالعادهایه برای شروع بهینهسازی عملکرد اپلیکیشن و یاد گرفتن چیزهای مختلفی که میتونن روش تأثیر بذارن. میتونیم ساعتها فقط گزارشها و لینکهای مرتبطش رو بخونیم و کلی چیز یاد بگیریم!با این حال، Lighthouse فقط اطلاعات سطحی در اختیارمون میذاره و اجازه نمیده سناریوهای مختلف مثل شبکه کند یا CPU ضعیف رو شبیهسازی کنیم.این ابزار بیشتر یه نقطهی شروع خوبه و برای Track کردن تغییرات در طول زمان خیلی مفیده. اما اگه بخوایم دقیقتر بفهمیم چه اتفاقی داره میافته، باید سراغ پنل &quot;Performance&quot; بریم.پنل Performanceوقتی که این قسمت رو باز میکنیم یه همچین چیزی میبینیم:این پنل سه تا معیار اصلی Core Web Vitals رو نشون میده — که یکی از اونها همون LCP مورد نظر ماست.همچنین امکان شبیهسازی شبکهی کند و CPU ضعیف رو بهمون میده و میتونیم عملکرد صفحه رو به صورت لحظه به لحظه (Real-time) ضبط کنیم.برای شروع، گزینهی &quot;Screenshots&quot; رو که بالای پنل قرار داره، تیک بزنید. بعدش روی دکمهی &quot;Record and reload&quot; کلیک کنید. وقتی صفحه خودش دوباره لود شد، ضبط رو متوقف کنید. این گزارش، جزئیات دقیقی از اتفاقاتی که حین لود اولیهی صفحه افتاده رو بهمون نشون میده.این گزارش چند بخش داره:در بالاترین قسمت Timeline Overview (نمای کلی زمانبندی) قراره گرفته.اینجا میتونیم ببینیم که یه چیزی روی سایت در حال اتفاق افتادنه، اما چیز زیادی بیشتر از اون مشخص نیست. وقتی موس رو Hover کنیم، اسکرینشاتی از همون لحظه ظاهر میشه و میتونیم یه بازهی خاص رو انتخاب کنیم و روش زوم کنیم تا دقیقتر ببینیم چه خبره.پایینش، یه بخشی به نام Network وجود داره. که وقتی بازش کنیم، تمام منابع خارجی (External Resources) که در حال دانلود هستن و زمان دقیقشون روی تایملاین رو میتونیم ببینیم. وقتی موس رو روی یه منبع خاص نگه داریم، اطلاعات دقیقی از اینکه در هر مرحله از دانلود چقدر زمان صرف شده نشون داده میشه. منابعی که گوشهی قرمز دارن، نشون دهندهی منابع بلاککننده (Blocking Resources) هستن.اگه دارید با پروژهی آزمایشی کار میکنید، دقیقاً همین تصویر رو میبینید، و این تصویر مو به مو با چیزی که تو بخش قبلی گفتیم مطابقت داره:در ابتدا، یه بلوک آبی دیده میشه — که مربوط به درخواست HTML صفحهست.بعد از اینکه لود شدنش تموم شد، با یه مکث کوتاه (برای پردازش یا Parse کردن HTML)، دو تا درخواست دیگه برای منابع جدید ارسال میشه.یکی از اونها (زرد رنگ) برای فایل JavaScript ـه — که بلاککننده نیست.اون یکی (بنفش رنگ) برای CSS هست — و این یکی بلاککنندهست.اگه الان کد پروژهی آزمایشی رو مثلا توی VSCode باز کنیم و یه نگاهی به پوشهی dist بندازیم، کد منبع دقیقاً با همین رفتار مطابقت داره:یه فایل index.html وجود داره و داخل پوشهی assets هم فایلهای .css و .js قرار دارنداخل فایل index.html و در بخش &lt;head&gt;، یه تگ &lt;link&gt; هست که به فایل CSS اشاره میکنه. همونطور که میدونیم، منابع CSS توی &lt;head&gt; باعث توقف رندر میشن، پس این مورد هم درست از آب دراومده.همچنین داخل &lt;head&gt; یه تگ هست که به فایل جاوااسکریپت داخل پوشهی assets اشاره میکنه. این تگ نه defer داره و نه async، ولی نوعش type=&quot;module&quot; هست. فایلهایی که به این صورت هستن بهصورت خودکار defer میشن، پس این مورد هم منطقیه — فایل جاوااسکریپت توی پنل، غیر بلاککننده نشون داده میشه.تمرین اضافهاگه یه پروژه واقعی دارید که روش کار میکنید، عملکرد بارگذاری اولیهش رو ضبط کنید و یه نگاهی به پنل Network بندازین. احتمال زیاد میبینید که منابع خیلی بیشتری دارن دانلود میشن.چند تا Blocking Resource دارید؟ آیا همهی اونها واقعاً ضروریان؟میدونی نقطهی شروع (entry) پروژه کجاست و این منابع بلاککننده چطور داخل تگ &lt;head/&gt; قرار میگیرن؟ یه بار پروژه تون رو با دستور npm build بیلد بگیرید و بعد دنبال این منابع بگردید تا ببینید از کجا اومدن. راهنمایی:اگه پروژه تون بر پایهی Webpack باشه، دنبال فایل webpack.config.js بگردید — مسیرهای مربوط به ورودی HTML معمولاً اون تو هستن.اگه از Vite استفاده میکنید، مثل همین پروژهی آزمایشی خودمون، یه نگاهی به پوشهی dist بندازید.و اگه با Next.js و App Router کار میکنید، یه سر به پوشهی next/server/app. بزنید.زیر بخش Network، میتونید قسمت Frames و Timing هم ببینیم.این بخشها خیلی باحالن. توی بخش Timing میتونیم همهی اون معیار هایی که قبلاً گفتیم رو ببینیم (FP و FCP و LCP) بهعلاوهی چندتا متریک دیگه که هنوز نگفتیم. اگه موس رو روی هر کدوم ببریم، زمان دقیقش رو نشون میده. اگه روش کلیک کنیم، تب &quot;Summary&quot; که پایین صفحهست آپدیت میشه و اونجا میتونیم ببینیم این متریک دقیقاً چیه و یه لینک هم هست برای اطلاعات بیشتر.نهایتا، بخش Main — اینجا دقیقاً نشون میده که روی main thread چه اتفاقهایی افتاده توی اون بازهای که ضبط شده.اینجا میتونیم چیزهایی مثل &quot;Parse HTML&quot; یا &quot;Layout&quot; رو ببینیم و اینکه چقدر طول کشیدن. بخشهای زرد مربوط به جاوااسکریپت هستن، که خب خیلی دقیق نیستن چون داریم از نسخهی production با کد Minify شده استفاده میکنیم. ولی حتی توی همین حالت هم یه دید کلی بهمون میده که مثلاً اجرای جاوااسکریپت چقدر زمان میبره نسبت به پردازش HTML یا رسم Layout.این بخش به ویژه وقتی خیلی کاربردیه که هم Network و هم Main باز باشن و زوم شده باشن تا کل صفحه رو پوشش بدن.از اینجا میتونیم ببینم که سرور مون فوقالعاده سریعه و باندلها هم کوچیک و سریع هستن. هیچکدوم از تسکهای شبکه Bottleneck نیستن؛ زمان خاصی نمیگیرن و بینشون، مرورگر راحت نشسته و کار خودش رو میکنه. پس اگه بخوایم سرعت بارگذاری اولیه رو بیشتر کنیم، باید بررسی کنیم چرا Parse HTML اینقدر طول میکشه — این طولانیترین بخش توی نموداره.یا اگه بخوایم از نظر عددی نگاه کنیم — اصلاً لازم نیست کاری کنیم! کل بارگذاری اولیه کمتر از ۲۰۰ میلیثانیه طول میکشه، که خیلی پایینتر از حد پیشنهادی گوگله 😁 ولی این به خاطر اینه که داریم این تست رو بهصورت لوکال انجام میدیم (بدون هزینههای واقعی شبکه)، روی یه لپتاپ خیلی سریع و با یه سرور ساده.وقتشه شرایط واقعی رو شبیهسازی کنیم.این قسمت اول از سلسله پست های مرتبط با Performance هست. همونطور که گفتم منبع اصلی این پست اینجاست:https://www.developerway.com/posts/initial-load-performanceکه با اجازه خود نویسنده (نادیا) مطلب ترجمه داره میشه و داریم باهم یاد میگیریم. به خاطر طولانی بودن مطلب، تصمیم گرفتم توی یک مقاله همه اش رو نیارم چون خوندنش سخت میشه. اگه دوست داشتین میتونید منبع اصلی رو بخونید. در هر صورت امیدوارم از این مطلب چیزی یاد گرفته باشید.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Fri, 27 Jun 2025 19:29:13 +0330</pubDate>
            </item>
                    <item>
                <title>می‌خواستم GO یاد بگیرم، پس اینکارو کردم - قسمت آخر - کار ناتمام؟</title>
                <link>https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%D8%A2%D8%AE%D8%B1-%DA%A9%D8%A7%D8%B1-%D9%86%D8%A7%D8%AA%D9%85%D8%A7%D9%85-rwvncagmjruv</link>
                <description>اگه قسمت قبل رو نخوندید، اینجا پیداش می‌کنید:https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B4-%D8%A7%DB%8C%D9%86-%DA%86%D9%87-%D8%AC%D9%87%D9%86%D9%85%DB%8C%D9%87-n8hh1ojsbr1rبذارید داستان رو اینطوری ادامه بدیم، من کجا ایستاده بودم الان؟ یه اپلیکیشن نوشته بودم به کمک Go و چندتا کتابخونه دیگه عملا یه کاری رو داشت انجام می‌داد. اگه یه نفر هم بود که سمت فرانت-اند پروژه رو انجام می‌داد، شاید میتونست که پروژه کامل بشه و حتی ازش استفاده هم کرد.همه API ها توی همون حالت Monolith داشتن کار می‌کردن، سرویس ارسال ایمیل داشت به خوبی کار می‌کرد، پروژه روی داکر بود، با gitlab ci هم به خوبی داشت کار می‌کرد، روی AWS بالا بود. این وسط بار ها و بار ها هم من ساختار فایل ها و فولدر ها رو عوض کردم. کلی توابع رو خوانا تر کردم و idiomatic تر هم شده بود. یعنی چی؟یه موضوعی که توی Go هست اینه که که مدلی داره برای خودش. منظورم چیه؟ در حین یادگیری، یه چیزی که بهش خیلی برمی‌خوردم این کلمه بود: Idiomatic Go یا Golang idioms. یعنی زبان کاملا دست شما رو باز گذاشته هر طوری که دوست دارید برنامه تون رو بنویسید ولی این وسط یه سری اصول یا قاعده وجود دارن که باعث میشه بگن این اپلیکیشن خوب نوشته شده و اگه رعایتشون نکنی دنیا تموم نشده ولی انگار مدل فکر کردنت به کد باید طور دیگری می‌بود. باید به سبک Go فکر کنی. کدت باید گوئی تر (Go-ish) باشه. 😅اما برای من که از دنیای فرانت وارد داستان شدم این موضوع خیلی قابل پذیرش بود. کلا JS هم خیلی این فرم رو داره. البته به اندازه Go جدی نیست ولی اونم تقریبا چنین چیزی رو داره. بذارید با مثال بگم حرفم روخیلی فریم-ورک ها شما رو مجبور میکنن که یه مدل مشخص کدتون رو بنویسید. یا فولدر ها و فایل ها رو یه طور خاصی دسته بندی کنید. مثلا توی NextJS شما مفاهیمی مثل App Router دارید. این یعنی یه مقدار Opinionated هست. انگار توی بعضی فریم-ورک ها، یک نظری یا شیوه فکر کردنی به شما تحمیل شده ولی خود زبان دست شما رو باز گذاشته که هر طور دوست دارید بنویسید. نمونه مقابلش هم هست که مثلا توی Java شما باید حتما OOP بلد باشید. ولی توی Go اصلا OOP شکل دیگری پیاده سازی میشه که متفاوته. همین موضوع توی JS هم صادقه. ایده رو امیدوارم گرفته باشین.توی Go هم تقریبا چنین داستانی وجود داره. زبان کامل دست شما رو باز میذاره هر کاری دوست دارید انجام بدید. ولی یه سری استاندارد هست که بهتره رعایت کنید. کلی اصول و قاعده وجود داره که از نام گذاری فایل ها و فولدر بندی بگیر تا شکل نوشتن شرط ها... که بهتره رعایت بشن. انگار سیم پیچی مغزم داشت عوض می‌شد. خورد خورد سعی کردم نکاتش رو یاد بگیرم و توی کدم پیاده کنم و اگه لازم بود تغییر بدم.این موضوع رو بهش خواستم فقط اشاره کوچیکی بکنم، که بگم کارم با Go تموم نشده بود و همزمان با درگیری های دیگه که داشتم سعی می‌کردم مهارت هام توی خود زبون رو هم بهبود بدم و بیشتر یاد بگیرم.کل این داستانی که براتون توی ۵ تا یادداشت خلاصه کردم، حاصل سر و کله زدن ۴-۵ ماه من بوده. پس اینو گوشه ذهن داشته باشید که همه این چیزا توی ۵ روز اتفاق نیوفتادن. پس من وقت زیادی داشتم که روی خیلی چیز ها کار کنم.بریم بقیه ماجرا.رسیدیم به نقطه ای که من تصمیم گرفتم اپلیکیشن رو با معماری Microservice یه طورایی بازنویسی کنم. چون دیگه این اسمش ریفکتور نبود. توی معماری Microservice هر سرویس باید در حالت ایده-آل دیتابیس خودش رو داشته باشه. چرا حالا میگم ایده‌-آل؟ چون شما میتونی مدلی پیاده سازی کنی که مثلا چند تا سرویس به یک دیتابیس متصل باشن ولی تو حالتی که بخواد best practice باشه باید اینا از هم جدا باشن و کاملا مستقل.خب منم مشکلی با این موضوع نداشتم. پس شروع کردم سرویس ها رو جدا کردن. برای جدا کردن سرویس ها از هم دیگه یه شمای کلی از سیستمی که داشتم باید ترسیم می‌کردم. خب هر سرویس باید وظایف خودشو فقط انجام می‌داد. مثلا توی Auth فقط چک کردن و امور مربوط به JWT و Credentials بود ولی ایجاد کاربر جدید باید یه سرویس دیگه به اسم User درگیرش می‌شد.۳ سال پیش یه کتابی به من معرفی شد با عنوان Domain Driven Design. اون زمان وقتی میخوندم کتاب رو خیلی برام گنگ و نامفهوم بود. کلا چون ذهنم مثل امروزم کار نمی‌کرد. خیلی سختم بود بفهمم، برای همینم اون موقع نصفه خوندم و ولش کردم و بعد ها متاسفانه کتاب رو گم کردم، ولی میتونید تو این مطلب با مفهوم کلیش بیشتر آشنا بشید.بعد از بررسی های خودم و نظرات سازنده AI و کمک و درک نصف و نیمه ام از همون DDD باعث شد من تصمیم بگیرم سیستم رو اینطوری به سرویس های کوچک تر بشکنم:سرویس Auth: وظیفه کنترل کردن Credentials به شکل کلیسرویس User: وظیفه امور مربوط به یوزر (ساخت و ادیت هر عملیاتی رو مدل User)سرویس Task: هر عملیاتی که روی یک تسک میتونست انجام بشهسرویس Upload: هر عملیاتی مرطبت با فایل هاسرویس Project: مدیریت و کنترل پروژه ها به همراه Board هاسرویس Gateway: ارتباط و هماهنگی بین همه سرویس های دیگهشاید این تقسیم بندی درست باشه، شایدم نباشه. فعلا که اینطوره! بر اساس Domain های مختلف سعی کردم این سرویس ها رو اینطور جدا کنم از همدیگه. هر کدوم از سرویس ها دیتابیس خودشونو داشتن. اینجا اگه مخاطب باهوشی که شما باشی، میگی پس بعضی چیزا مثل ارتباط بین همون auth و user چی؟ یا ارتباط بین task و user و ارتباط بین task و project و board. اگه اینا بخوان هر کدوم دیتابیس مستقل داشته باشن چی میشه؟خب بذارید اینطور بگم. ارتباط بین این سرویس ها از روش های مختلف باید انجام بشه. یه دونه از سناریو های ساده رو بیاید با هم مرور کنیم: سناریو ثبت نام کاربردرخواست از سمت کاربر میاد به register/ که سرویس Gateway داره گوش میدهسرویس Gateway درخواست رو با توجه به اینکه مربوط به Auth هست میده به اونسرویس Auth اطلاعات رو از body میخونه، اول از سرویس User می‌پرسه که این کاربر وجود داره یا نه؟اگه سرویس User ببینه وجود نداره، یوزر رو میسازه و میذاره توی دیتابیس خودش و به Auth خبر میدهاگه سرویس User ببینه وجود داره از قبل، به Auth میگه قضیه کنکله چون این از قبل بودهدر هر صورت سرویس Auth به Gateway میگه که این جواب منه (مثبت یا منفی)سرویس Gateway به سمت کاربر جواب رو میفرسته (مثبت یا منفی)من خیلی سعی کردم سناریو رو کامل تشریح کنم ولی خیلی چیزا این وسط از قلم میوفته ولی از طرفی اشاره کردن بهشون مطلب رو طولانی میکنه. نحوه ارتباطات اشاره نشده، validation input ها اشاره نشده و کلی چیز دیگه که شما بر من ببخشید.همینطور که می‌بینید، توی این مدل معماری کلی سرویس داریم که باید با همدیگه صحبت کنن. مثل کارمند های یه اداره، برای انجام یه کار اداری - مثل این میمونه که شما یه درخواست دارید، ولی کلی کارمند اون پشت باهم باید ارتباط بگیرن، تاییدیه بگیرن و در نهایت به شما جواب بدن - حالا توی بعضی اداره ها خیلی وقت ها این رفت و برگشت ها رو خودمون به عنوان کاربر انجام می‌دیم، ولی بعضی جاها هم اتفاقات پشت پرده اتفاق میوفته.وجود یه سرویس به اسم Gateway هم به همین منظوره، اون وظیفه اش اینه که درخواست رو بگیره و بده دست سرویس مربوط به خودش و در نهایت هم جواب رو بگیره بده به شما. اون پشت شاید چندتا سرویس مجبور بشن به هم دیتا رد و بدل کنن. البته ضمنا اون قضیه encrypt و decrypt شدن هم میتونه اینجا اتفاق بیوفته.اینجا اصلا یه سری use case جدید شکل گرفته بود، مثلا قبلا تو حالت monolith اصلا من API ای برای چک کردن اینکه کاربر وجود داره یا نه نداشتم! ولی اینجا لازم بود! یعنی یه API که عملا فقط کارش این بود که یه سری id بگیره و بگه اینا وجود دارن یا نه. یه internal API که فقط توسط سرویس های دیگه صدا زده بشه.اصلا پس با این تفاسیر وجود اون Gateway ضروری هم بود چون که اون فقط API هایی رو از سرور در اختیار قرار می‌داد که خودمون بخوایم.ولی اشاره کردم به صحبت کردن بین این سرویس ها، یه راه خیلی ساده که وجود داره اینه که سرویس ها مستقیم باهم صحبت کنن. مثلا در زمان همون ثبت نام، سرویس Auth از User به کمک یه Rest API ارتباط بگیره. در این حالت حالا میشه این ارتباط به شکل sync یا async هم باشه که این البته وابسته به سناریو و use case هست که می‌خوایم سریع به کاربر جواب بدیم یا می‌تونیم بعدا بهش جواب بدیم.پس تو روش اول داریم از داخل سرور، از یه سرویس به یه سرویس دیگه ریکوئست می‌زنیم.روش دیگه خیلی شبیه به همینه، با این تفاوت که این دفعه به جای Rest از gRPC استفاده کنیم. خب این روش دردسر های خودشو داره، مزایایی هم داره. مثلا سریع تره، ساختارمند تره و ... ولی من شخصا نرفتم سمتش. اما شیوه کارش رو فهمیدم.یه روش دیگه اینه که اصلا بیایم یه واسطی رو این وسط قرار بدیم که این سرویس ها کلا از طریق اون باهم در ارتباط باشن. یعنی یه چیزی بین این چندتا سرویس قرار بگیره که هر سرویسی با جای دیگه کار داشت بره به این بگه و این به بقیه.اینجا بود که با مفهوم Event Driven Design آشنا شدم! خیلی خلاصه یعنی یه سرویسی بلند داد میزنه میگه فلان اتفاق افتاد، بقیه سرویس ها که براشون اون اتفاق مهم باشه گوش میدن و یه کاری رو انجام میدن، برای بقیه اگه مهم نباشه خب کاری هم نمیکنن. این تعریف خیلی خیلی خیلی خیلی خلاصه از از معماری pub/sub هم هست. یه event رو publish می‌کنیم و توی یه سرویس دیگه به اون event خاص subscribe.این روش به نظرم خیلی جذاب اومد! scale شدنش خیلی خیلی راحت تر می‌تونست انجام بشه، coupling بین سرویس های مختلف هم کمتر می‌شد. از طرفی از نگاه DevOps هم که بخوایم بهش نگاه کنیم، اینجا می‌تونستیم مثلا تعداد instance های یه سرویس پر کاربرد تر رو بیشتر کنیم یا تعداد اون واسط ها رو بیشتر کنیم یا هرکار دیگه ای.این واسط که دارم راجع بهش صحبت می‌کنم میتونه چیزای مختلف باشه. شاید شاخص ترینش Kafka باشه. ولی من از Nats استفاده کردم. چون همینکارو دقیقا انجام می‌داد برای من ولی خیلی برام ساده تر بود پیاده سازیش. توی بیزنس های بزرگ (و البته واقعی) این کار رو میتونن روی سرویس های ابری هم هندل کنن که هم AWS دارتش، هم Google و هم Microsoft. من دقیقا نمیدونم چیه اسم این سرویس ها تو هر کدوم اینا ولی هست.البته اینم بگم که من اینجا اشاره کردم که این واسط بین سرویس هاست ولی خیلی کارای بیشتری هم انجام میدن. تو اپلیکیشن های با scale های خیلی وحشتناک که میلیون ها درخواست در ثانیه رو هندل می‌کنن یه چیزی مثل Kafka دیگه فقط یه Message Broker نیست.بخوام راجع بهش بنویسم نه اینجا جاش هست و نه شما حوصله اش رو دارید. اینو می‌سپرم به عهده خودتون.در هر صورت، من تصمیم گرفتم این روش رو پیاده سازی کنم ولی دقیقا این همونجایی بود که زیرش زاییدم 😂 توی حالت استاندارد و معماری تر و تمیز Microservice خیلی چیز ها باید سر جای خودشون دقیق قرار بگیرن که بگیم ما معماری Microservice رو درست پیاده کردیم. این کمالگرایی (یا شاید ماجراجویی من) من رو به این نقطه رسوند که الان که دارم این مطلب رو می‌نویسم هنوز همه API ها مثل حالت Monolith دیگه کار نمیکنن. باید کلی راه دیگه برم تا دوباره برسم به اون نقطه.ولی چه مسیری بوده تا الان، چه قدر چیز یاد گرفتم، چه قدر زبان مشترک پیدا کردم با دنیا های جدید و مختلفی که قبلا راجع بهشون چقدر کم میدونستم و الان هم کم میدونم ولی نقطه خوبی ایستادم و از خودم راضی هستم. البته بعد اینکه اپلیکیشن رو کامل کنم راضی تر هم میشم 😁ایده هایی تو سرم هست برای ادامه پروژه:دوست دارم یه مدل Log درست کنم برای تسک ها، یه چیزی شبیه historyسمت فرانت اپلیکیشن رو پیاده سازی کنم ولی نه با Next یا React بلکه با یه تکنولوژی جدید مثلا Vue و Nuxt. چرا؟ چون میخوام اونا رو هم یاد بگیرم و یه امتحانی کرده باشم 😅سمت فرانت زمانی که بخوام پیاده سازی رو شروع کنم، اون موضوع drag and drop رو دوست دارم بهش توجه کنمحتما موضوع هایی مثل Load Test و ... رو دوست دارم امتحان کنم. مثلا ببینم چقدر میتونم به کمک K8s یا Docker اپلیکیشن رو scale کنم.امکان کار همزمان چند نفر روی یک Project به کمک Web socket - یه چیزی شبیه google docs که میتونی ببینی دقیقا اون یکی کاربر داره چیکار میکنه و کجاستامکان اضافه کردن موارد جدید به هر تسک، مثلا همون Checklist یا تعیین Deadline براش و ...اینم راجع به تست بگم که تو قسمت های قبل یادم رفته بود: توی Go به صورت built-in شما میتونین تست بنویسید و با یه دستور اجراشون کنید، یعنی هیچ کتابخونه و خرت و پرتی نمیخواد. اینم یکی دیگه از چیزایی بود که برای من خیلی جذاب بود.در نهایت باید بگم تا اینجای این مسیر برای من بسیار پر چالش ولی لذت بخشی بود. خیلی وقت بود که از چیزی به این اندازه لذت نبرده بودم ولی این مسیر همچنان ادامه داره و هنوز کامل نشده. شاید یه روز که همه چیز انجام بشه لینک پروژه رو به همراه کد هاش روی گیت هابم بذارم که بتونید ببینیدش. تا اون موقع شاید خیلی زمان مونده باشه ولی یه روز تکمیل میشه.جا داره از منابع (یا ابزار) که استفاده کردم تو این مسیر هم نام ببرم.کانال یوتوب TechWorld with Nana به شکل قابل توجهی مخصوصا برای قسمت های DevOps (البته رو دور تند چون خیلی ویدئو باز نیستم😅)مقاله های Mediumابزار های AI مثل ChatGPT و Claudeسایت Codecrafters (البته منبع نمیشه بهش گفت، بیشتر تمرین بود)خود سایت Go و البته این لینکسایت Reddit و البته گوگل به شکل خیلی زیادیاینم موزیکی بود که در حین کار خیلی گوش میدادم 😁 حتما پیشنهاد می‌کنم یه بار گوش بدید - لذت ببرید.چندتایی کتاب هم بودن که عکسشونو این پایین میتونید ببینید.یه توضیحی هم بدم راجع به روش استفاده ام از AI - بعدا راجع به این موضوع یه مطلب مفصل می‌نویسم و شیوه کار خودم و تجربه ام رو توضیح میدم. ولی به طور کل کاری که من کردم این بود که خیلی سعی می‌کردم سوالاتی که ازش می‌پرسم رو با prompt های خوب و هدف مند انجام بدم. یعنی چی؟ یعنی هر زمان که هر کاری میخواستم انجام بدم و مطمئن نبودم بهش، ازش میخواستم بهم چندتا منبع معرفی کنه. خیلی جاها سعی می‌کرد خودش کد رو برام بنویسه ولی این مدلی منو خیلی تنبل می‌کرد. ازش خواسته بودم که کد ننویسه برام - در عوض بهم مسیر بده و صرفا hint بده و بذاره خودم اینکارو بکنم. قطعا در آینده اگه بخوام به شکل حرفه ای تر Backend رو دنبال کنم و دستم خیلی راحت تر بشه با Go و فضاش خیلی بیشتر ازش برای نوشتن کد ها استفاده می‌کنم. ولی فعلا دوست دارم بذاره خودم فکر کنم و دستم راه بیوفته. مثل خاموش کردن autocomplete میمونه.در آخر دمتون اگه مطلب رو خوندید، حتما خوشحال میشم نظرتون رو بدونم.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Tue, 03 Jun 2025 20:59:12 +0330</pubDate>
            </item>
                    <item>
                <title>می‌خواستم GO یاد بگیرم، پس اینکارو کردم - قسمت ۴ - این چه جهنمیه؟</title>
                <link>https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B4-%D8%A7%DB%8C%D9%86-%DA%86%D9%87-%D8%AC%D9%87%D9%86%D9%85%DB%8C%D9%87-n8hh1ojsbr1r</link>
                <description>اگه قسمت ۳ رو نخوندید اینجا پیداش می‌کنید:https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B3-%D9%85%D8%B3%DB%8C%D8%B1-%D9%87%D8%A7%DB%8C-%D8%AC%D8%AF%DB%8C%D8%AF-u5iodboridsgهرچیزی که تاحالا پیاده کرده بودم یه اپلیکیشن Monolith بود. یعنی همه چیز داشت تو یه اپلیکیشن هندل می‌شد. از Auth برای ثبت نام و فعال کردن کاربر بگیر تا ساخت پروژه جدید و Board ها و Task ها و File ها و ... ولی من میدونستم یه چیزی وجود داره به اسم Microservice ها که میاد یه ایده دیگه رو مطرح میکنه. ایده ای که میتونه به Scale کردن پروژه کمک کنه.میدونم البته که من الان یه اپلیکیشن خیلی خیلی خیلی ساده دارم. اصلا نیازی نیست که بخوام اونو Microservice کنم. مخصوصا اگه Guideline های این Microservice ها رو بری بخونی متوجه میشی که پیاده سازی درست مفهوم Microservice خیلی خیلی خیلی خیلی سخت و پیچیده هست. ولی خب دیگه، قشنگی کار هم همینه. اصلا یادگیری همینجا شکل می‌گیره.کنجکاوی بود که منو داشت هل میداد به جلو. هی می‌گفتم خب بذار اینکارم بکنم، بذار اون یکی کارم بکنم، بذار اینم بهش اضافه کنم. فقط میخواستم تجربه کنم. یعنی هدفم از اینکه برم سراغ Microservice ها این نبود که مشکل پرفورمنس خورده بودم، فقط میخواستم یاد بگیرم اینکار چطور انجام میشه.ولی قبل اینکه بهش برسیم بذارید تعریف کنم که چی شد اصلا رسیدم به اینجا و چی شد که اصلا به خودم گفتم این چه غلطی بود من کردم 😂داستان به جایی رسید که می‌خواستم اپلیکیشین رو Deploy کنم. برای همین سرچ کردم ببینم چه ابزار هایی دارم. خب میدونستم که AWS هست و میتونم ازش استفاده کنم، ولی گفتم یه چرخی بزنم. خیلی آپشن های مختلفی پیدا کردم که خیلی هاش اصلا بدون کانفیگ فقط لینک git رو میدادی و میرفت خودش دیپلوی می‌کرد و همه چی با GUI هندل می‌شد. قیمتی هم نداشتن و حتی بعضیاش رایگان بودن.ولی من پیش خودم فکر کردم &quot;حالا که تا اینجا اومدیم، ببینیم رو AWS چطوری میشه انجامش داد&quot;. این شد که یه سرچی کردم دیدم سرویسی که بهم میده اسمش EC2 هست. در حقیقت یه VPS میسازه با یه SSH Key که بهش وصل بشی و همه چی رو خودت دستی هندل کنی و بذاری بالا. یه کانفیگ پایه که داشت حالت micro بود اگه اشتباه نکنم که یه منابع حداقلی می‌داد.خب روال کار تا اینجا به چه شکل بود؟ من باید وصل می‌شدم به سرور و بعد نصب git و بقیه چیزا کد رو می‌گرفتم و اونجا یه وب سرور میذاشتم که اپلیکیشن رو بیاره بالا و از اون به بعد روی اون IP قابل دسترس می‌شد. این ولی خب روالی بود که شاید ۸-۹ سال پیش باهاش کار می‌کردن 😁 حالا دیگه Docker خیلی کارو ساده تر می‌کرد.یه داکرفایل برای پروژه نوشتم، توش ستاپ کلی رو انجام دادم و حالا نیاز بود که یه سرویس دیگه هم بیاد و این رو serve کنه که خب انتخابم Nginx بود. پس در واقع اپلیکیشنم می‌شد یه image و اون وب سرور هم میشد یه image دیگه. خب اینجا راه حل استفاده از docker compose بود که بیاد اول یه nginx بیاره بالا و بعد اپلیکیشن رو بیاره بالا. این وسط میموند دیتابیس که اونم شد یه قسمت دیگه از اون docker compose فایلی که داشتم.خلاصه اش کنم، بعد کلی بدبختی و سرچ و AI و ... رو سیستم خودم تونستم پروژه رو کامل با داکر بیارم بالا. فقط یه درد دل ریز بکنم اونم این که من پاااااره شدم. البته لذت بردم از اینکه پاره شدم ها 🤣 ولی واقعا به یه مواردی برخورد می‌کردم که واقعا بعضی جاها میخواستم بگم آقا ولش کن اصلا. اما خداییش کلی چیز یاد گرفتم.اما هنوز به سرور نرسیده بود. بعد اینکه رو سیستم خودم با داکر همه چی کار کرد گفتم ایول حالا دیگه با خیال رااااحت میتونم برم رو اون EC2 که ساخته بودم و فقط داکر رو اجرا کنم و تمااام.ولی خب دیگه 😅 حتما فهمیدید که یه جای کار مشکل داشت.من اینکارو انجام دادم و رفتم روی vps و شروع کردم داکر رو میزان کردن که وسط کار موقع ستاپ کردن پروژه هی گیر می‌کرد و بعد یه مدتی هم timeout می‌داد و می‌ترکید. خدایا مشکل چی بود... مگه نه اینکه میگن داکر مشکل Works on my machine رو حل میکنه 😅 یکم که بررسی کردم دیدم که بله، کد و کانفیگ و ... مشکلی ندارن. مشکل جای دیگه است. در واقع منابع اون instance من محدود تر از این بود که بخواد چندتا image رو باهم بیاره بالا بدون مشکل. و راه حل چی بود؟ پول! 😁باید منابع EC2 رو میاوردم بالاتر. مخصوصا Ram بیشتر. خب این پلنش هم Pay as you use هست دیگه، گفتم عیبی نداره در عوض چیز یاد می‌گیرم. خلاصه ردیفش کردم. بعد دیگه داکر اجرا شد و اومد بالا و لاگ ها همه چیز رو خوب نشون میدادن تا اینکه اومدم از طریق postman به سرور یه درخواست بزنم ببینم کار میکنه یا نه. هرکاری می‌کردم کار نمیکرد. بازم نمیخوام طولانی بشه، فهمیدم کانفیگ هایی که من رو سیستم خودم انجام داده بودم کاملا درست نبودن. نیاز بود تغییراتی بکنن. خلاصه کلی کلنجار رفتم و بالاخره اولین response از سرور دریافت شد و شادی و خوشحالی فضای اتاق رو گرفت 😂اون وسطا یه شیطنتی هم کردم یه دامین هم خریدم که با IP نخوام بهش درخواست بزنم، یه SSL هم براش باید میزان می‌کردم که اونم ردیف شد (البته شما راحت بخونید، ولی بر من سخت گذشت 😅)چیزایی که به واسطه این تجربه یاد گرفتم:کانفیگ کردن Docker و درک بهتر از Dockerfileکانفیگ کردن محیط dev ام با کمک Docker composeاجرای پروژه روی AWS و EC2کانفیگ Nginx به شکلی که رو سیستم خودم و سرور درست کار کنهکانفیگ دامین و SSL و خرت و پرتای مربوط بهش و آپدیت Nginx و سرویس های خرید دامینکار کردن با AWS پول میخواد 😂پس تا اینجا من یه اپلیکیشینی داشتم که داشت خیلی خوشگل کار می‌کرد، حالا رو یه سرور بود، می‌شد بهش درخواست بزنی و همه چی خوب بود. ولی بازم یه چیزی کم بود. هر بار که میخواستم آپدیت کنم پروژه رو باید می‌رفتم توی اون VPS و آخرین کد ها رو از Git می‌گرفتم و میزدم که داکر اجرا بشه. یعنی عملا من اینجا قسمت CI/CD رو نداشتم. که جلوتر می‌رسیم بهش.قبلش یادتونه اون ماجرای decrypt و encrypt شدن id ها رو؟ میخواستم روال کارشو بهینه تر کنم. نه که بهینه نبود قبلش، ولی بازم گفتم بذار یه چیز دیگه هم امتحان کنم. تصمیم گرفتم اون آیدی ها رو توی Redis ذخیره کنم. البته سربار اجرایی نداشت قبلش هم. شاید حتی اصلا چیز اشتباهی بود که بخوام از Redis برای اون مقادیر استفاده کنم. کلا یه موضوع خیلی چالش بر انگیز تو دنیای نرم افزار همین موضوع Caching هست. چون فقط این نیست که شما یه مقداری رو بذاری رو یه دیتابیسی شبیه Redis.بحث این پیش میاد که چه زمانی اون دیتا ها باید invalid بشن، با چه سیاستی از cache استفاده کنی و چجوری کلا باهاش کار کنی، موضوع مهمی برای من نبود البته، من میخواستم فقط تجربه اش کنم. برای همین اومدم هر id رو عدد و رشته اش رو تو Redis ذخیره کردم و زمانی که میخواستم GET ها رو هندل کنم از اونجا میخوندم. کار غلطی بود الان که بهش فکر می‌کنم ولی خب دیگه، تجربه است. خیلی استفاده های بهتری هم از Redis میشه کرد. بعد تر که بیشتر راجع بهش خوندم فهمیدم خیلی کار های دیگه هم میشه باهاش کرد.از این بگذریم، خواستم اشاره کنم که فقط اینم اون وسطا اومد. برگردیم سراغ همون موضوع CI/CD.راه حلش ساده بود ولی پیاده سازیش سخت 😂 صادقانه بگم قبلا درگیر این‌چیزا نمی‌کردم خودم رو. تا جای ممکن ازشون فاصله می‌گرفتم. مخصوصا که اینکارارو یه بار انجام میدادیم و دیگه تا نیازمندی جدید دیگه ای نبود نمی‌رفتیم سمتش. اونم چیزی نبود جز Gitlab CI.اگه مطالب من رو خونده باشید تا اینجا، می‌بینید، مسیر طوری ادامه پیدا می‌کرد که هرجا که می‌رفتم یهو احساس نیاز می‌کردم یه کاری کنم کارم ساده تر شه، یه کاری کنم که هم یاد بگیرم هم تجربه. خیلی چیز ها رو از اول نمیدونستم که لازم دارم. اپلیکیشی ساده ای که از اول با هدف یادگیری Go شروعش کرده بودم داشت منو می‌برد سمت اینکه خیلی چیز های دیگه هم یاد بگیرم.به نظرم اگه مخاطب من که شما باشی، میبینی که من از اول راه این مسیر رو آروم آروم آروم اومدم جلو و هی نیاز جدید بوجود میومد (یا بوجودش میاوردم 😂) که براش مجبور شدم یه مسیر جدید رو شروع کنم.خب از اونجا که من عموما تو پروژه ها و شرکت های مختلف سیستمی که استفاده کرده بودم همون Gitlab بود انتخابم هم شد همین Gitlab CI وگرنه میدونم که تو خیلی جاها از Github Actions برای Github استفاده می‌کنن که خب اون یه داستان دیگه است که من بلد نیستم.در واقع Gitlab CI یه شکلی از Docker هست (یا دست کم من اینطوری ازش فهمیدم) که میاد یه سری کار رو به کمک یه سری script با یه سری trigger انجام میده. مثلا بهش میگی بعد اینکه کد push شد روی فلان برنچ بعدش بیا این stage رو اجرا کن، بعدش فلان stage و... مثال دنیای فرانت اش میشه مثلا بعد اینکه کد push شد روی برنچ main بیاد lint کنه بعد تست ها رو انجام بده، بعد مثلا یه trigger دستی داشته باشه که بگیم کد رو بذار رو پروداکشن یا staging و ...خب من مشکلم چی بود؟ این بود که باید هر بار دستی میرفتم رو vps و کد رو می‌گرفتم و داکر رو اجرا می‌کردم. مجدد بعد کلی تحقیق و کمک های فراوان از AI تونستم یه فایل gitlab ci بنویسم که بعد از زمانی که کد روی برنج main میومد بالا، وصل شه به سرور، بره داخل directory مورد نظر و یه بار git pull کنه و بعد داکر رو اجرا کنه.حالا این مشکل هم حل شده بود. الان دیگه من یه سیستمی داشتم که روی کامپیوتر خودم توسعه می‌دادم و هر زمان که رو برنچ main کد رو میفرستادم در اصل روی سرور هم کدم می‌رفت و اجرا می‌شد.ولی من اینجا گفتم خب چه عالی حالا برم سراغ یه پروژه دیگه؟نه! گفتم حالا که انقدر Docker رو یاد گرفتم چرا نرم سر وقت اینکه هر کدوم از اجزای سیستم رو یه سرویس مستقل کنم و با compose اینا رو به هم وصل نکنم؟ یعنی چی؟ یعنی هرچی ساختم، هر API ای که داشتم حالا باید سرویس مستقل خودش می‌شد.سرویس مستقل یه تعریفی داره. کلا معماری Microservice یه سری نکته داره که باید از قبل دونست. این یعنی هر سرویس باید کااااملا مستقل باشه. اینکه میگم کاملا یعنی کااامل. برای درک بهتر یکی از دوستانم این سایت رو معرفی کرد. تقریبا کل Guideline هاش اینجا هست. کلی هم شکل داره که موضوع رو بهتر توضیح میده. درکش با AI و یه سری prompt خوب تازه بهتر هم میشه.این سرویس ها باید باهم صحبت می‌کردن، حالا از طریق REST Api یا روش های دیگه. من فکر می‌کردم پیاده سازیش نباید خیلی کار سختی باشه ولی....اینجا بود که من بدبختیم شروع شد.تو قسمت آخر میگم که این داستان Microservice ها با من چه ها که نکرد. با مفاهیمی مثل gRPC و معماری Event Driven و DDD بیشتر آشنا شدم. چیزایی مثل Nats و kafka رو دیدم. از scaling بیشتر یاد گرفتم. حتی یه ناخونکی به K8s زدم. توی پست آخر راجع به منابع ام هم میگم. کلی کتاب معرفی می‌کنم که خیلی خوب بودن. البته صادقانه من همه شون رو هنوز نخوندم ولی معرفی میکنم. از تاثیر AI روی این مسیر هم بیشتر صحبت می‌کنم. خلاصه سرویس های مختلف رو کانفیگ گردم و به کلی چالش برخوردم که هنوزم البته توش موندم 😁 که در موردش بیشتر میگم.قسمت آخر:https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%D8%A2%D8%AE%D8%B1-%DA%A9%D8%A7%D8%B1-%D9%86%D8%A7%D8%AA%D9%85%D8%A7%D9%85-rwvncagmjruv</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Mon, 02 Jun 2025 01:49:59 +0330</pubDate>
            </item>
                    <item>
                <title>می‌خواستم GO یاد بگیرم، پس اینکارو کردم - قسمت ۳ - مسیر های جدید</title>
                <link>https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B3-%D9%85%D8%B3%DB%8C%D8%B1-%D9%87%D8%A7%DB%8C-%D8%AC%D8%AF%DB%8C%D8%AF-u5iodboridsg</link>
                <description>اگه قسمت دوم رو نخوندید، اینجا پیداش می‌کنید: https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B2-%D8%B2%DB%8C%D8%A8%D8%A7%DB%8C%DB%8C-%D9%87%D8%A7-chzqckhu4zlv حالا دیگه اپلیکیشن داشت بزرگ تر می‌شد. ولی گفتم اینطوری نمیشه. باید یه اپلیکیشنی رو پیدا کنم تا ازش کپی کنم. اینطوری که داشتم پیش میرفتم خوب بود، ولی انگار هنوز هدف واضحی نداشت. انگار یه چیزی کم بود. انگار قدش کوتاه بود و جای رشد نداشت. اگرم داشت خیلی گنگ بود.عکس از ChatGPTاول برنامه ریزی کردم. یه اپلیکیشن Task management رو گذاشتم به عنوان الگو برای خودم. البته به شکل خیلی ساده تر برای خودم تحلیلش کردم. برای همین Trello رو انتخاب کردم. دلیل این انتخاب هم این بود که Trello خیلی ساده تر بود نسبت به Jira و البته منم نمیخواستم یه اپلیکیشن تو اون ابعاد بسازم.توی Trello کاربر ها میتونن:یک یا چند پروژه جدید ایجاد کنن. چند کاربر میتونن عضوی از یک پروژه یا صاحب چند پروژه باشن.بعد توی اون پروژه بیان ستون های مختلف (Board) ایجاد کنن - مثلا حالت Kanban که ستون های Todo و In progress و done - داشته باشه.میتونن این Board ها رو حرکت بدن و ترتیب شون رو عوض کنن.میتونن توی هر Board یه تسک بسازن.تسک ها رو میتونن بین این ستون ها جابجا کنن و حتی ترتیب شون رو عوض کنن.تسک ها رو میتونن به یه نفر دیگه که عضو اون پروژه هست Assign کنن.موارد دیگه مثل History داشتن هر تسک، Description های پیچیده تر مثل اضافه کردن Checklist به اون تسک و نشون دادن Progress هم بودن ولی گفتم برای شروع اسکلت اصلی Trello همیناست.بعضی قابلیت ها رو هم که از قبل داشتم مثل همون فایل ها، ولی با این تحلیل من که البته خیلی ساده هستنیاز بود دو تا Model دیگه به پروژه اضافه بشه:مدل Project که در واقع حکم جایی که توش ستون ها قراره بیاد رو دارهمدل Board که هر پروژه میتونه چندتا (مثلا ماکزیمم ۱۰ تا) ازش داشته باشه + ترتیب داشتن اش.از طرفی نیاز بود که بعضی Model ها هم تغییر کنن:مدل User حالا میتونست عضوی از یک یا چند پروژه باشه و در عین حال صاحب یک یا چند پروژه باشه.مدل User حالا میتونست به یک Task به عنوان Assignee اضافه بشه.مدل Task حالا باید زیر مجموعه ای از Board می‌شد (برخلاف قبل که بی صاحاب بود😁)مدل Task باید دارای ترتیب (Order) و Assignee می‌شد.با این تفاسیر شروع کردم به ایجاد کردن مدل های جدید و ایجاد روابط شون توی دیتابیس. نم نم هندل کردن این روابط کار سختی داشت می‌شد. دیگه احساس کردم وقتشه که برم سراغ یه ORM که انتخابم شد Gorm که کار کردن باهاش تجربه خوبی بود.یه موردی رو دوست دارم بهش اشاره کنم، اونم اینه که توی Go شما وقتی مثلا یه Type جدید ایجاد می‌کنی و میای المان های اون تایپ رو تعریف می‌کنی، خیلی شبیه TypeScript هست. مثلا این شخص اسم داره از جنس رشته.ولیعلاوه بر تایپ اون پراپرتی ها یه flag یا descriptor هم میتونن هر کدوم داشته باشن. یعنی واقعا کارایی که تو این flag ها میشه کرد باور نکردنی هست. شما از validation بگیر تا تعریف مدل های gorm تا حتی اینکه توی json خروجی به چه اسمی میخوای این برگرده رو میتونی تو اینجا تعریف کنی. در عین سادگی بسیار کارآمد و خفن و خوبه.توی این مدل جدید نیاز داشتم به خیلی API هایی که در واقع بیشتر کار PATCH رو انجام میدادن. اینجا بازم اونجایی بود که تجربه فرانتی خیلی به دردم خورد. چون میدونستم که کاربر ها اگه بخوان قابلیت اینو داشته باشن که مثلا فلان تسک رو از یه ستون بکشن یه ستون دیگه باید یه API باشه که این edit رو هندل کنه. پس روی API های مربوط به Task و Board و User این موارد رو لحاظ کردم. کاری که باید انجام می‌شد ساده بود.تسک فلان رفت به ستون فلان با این عدد به عنوان ترتیب.ستون فلان ترتیبش عوض شد به فلان عدد.فلان یوزر assign شد به فلان تسک.فلان فایل assign شد به فلان تسک.همه اینا در واقع ریکوئست های PATCH بودن. بعضی هاشون payload داشتن توی body و بعضیا فقط یه param توی url شون و بعضیاشون هر دو.در ضمن اینم بگم که کلا اپلیکیشن فقط یه سری API بود یعنی هیچ کد فرانتی براش زده نشده بود. ارتباط من هم باهاش فقط از طریق Postman بود.همین کار باعث شد چقد با Postman هم بیشتر آشنا بشم. مثلا یه سری script نوشتم که بعد از login بیاد و توکن رو تو یه متغیر ذخیره کنه تا هربار مجبور نباشم کپی پیست کنم یا env های مختلف تعریف کردم (که البته چیز جدیدی نبود) یا response ها رو همه رو تو حالت های مختلف ذخیره میکردم توی اون collection ها.حتی با AI اومدم یه سری script دیگه هم برای Test Automation روشون ایجاد کردم که مجبور نباشم هر دفعه بعد از هر تغییر خودم تست کنم. البته به تست های خود Go هم میرسیم که اونم یه چیز خیلی خفنیه اما من ایده ام این بود که ما که تا اینجا اومدیم، اینم بریم سمتش ببینیم چی به چیه.خیلی رک بگم. چون فرانت کار میکنم خودم، خیلی دنبال این بودم که یه چیزی درست کنم که اگه خواستم اینو بدم یه نفر دیگه فرانتشو بزنه راحت باشه. چون میدونستم دغدغه های فرانتی ها رو.به اینجا که رسیدم دیدم ای وای من...دو تا اتفاق بد داره میوفته:همه ID هایی که داشتم توی دیتابیس، دقیقا همونایی بود که client داشت صدا میزد. یعنی اگه کاربر شماره id اش عدد 1 بود - دقیقا همینو تو همه API ها صدا می‌زدیم. این برای همه مدل های دیگه هم صادق بود. این چیزی نبود که من تو اپلیکیشن های واقعی دیده باشم.کد ها و توابع handler داشتن نم نم بزرگ می‌شدن. خوندنشون واقعا داشت سخت می‌شد.مورد اول خیلی جدی بود. نمیخواستم همینطوری ID ها رو کاربر بتونه صدا بزنه و بدونه ID هر entity توی دیتابیس چیه. من خودم که فرانت کار می‌کردم ندیده بودم همچین چیزی رو پس میدونستم که یه جای کار داره می‌لنگه. یکم تحقیق کردم ببینم چیکار باید بکنم، البته از دوستام و همکارام هم مشورت گرفتم موضوع رو بهشون گفتم.طبق تحقیق خودم می‌خواستم بیام کلا یه چیزی مثل NanoID رو کلا جایگزین اعداد بکنم توی دیتابیس ام. یعنی کلا primary key ها و foreign key ها همه شون بشن NanoID ولی رفتم توی ستاپ کردنش دیدم اووووووووو این که خیییلی دردسر داره. باید یه hook ایجاد می‌کردم توی DB که مثلا وقتی فلان دیتا اضافه شد بیا یه NanoID بهش Assign کن. تایپ Primary Key رو عوض کن به VARCHAR و ... یه جای این موضوع بو های بدی میداد 😁 چرا باید یه تغییر انقدر پیچیده باشه؟بعد از صحبت با همکارا و دوستان بکند کاری که دارم، فهمیدم میتونم به ازای هر عدد مثلا 1 یا 80 یا هر عدد دیگه ای، اون رو به کمک یه salt و یه کلید به یه رشته encrypt شده تبدیل کنم که قابل بازیابی باشه مثلا عدد 1 تبدیل بشه به uj7Bh34 و عدد 80 هم تبدیل بشه به iah73v6 و اگه همین رشته ها رو دوباره بخوام Decrypt کنم بتونم راحت برگردونمشون به 1 یا 80.کلاینت که میخواد به من درخواست بده این رشته ها رو بفرسته و من به کمک اون کلید بفهمم که این منظورش چه عددی هست توی دیتابیس. از طرفی من هم قبل اینکه هر گونه id بخوام به سمت client برای هر کدوم از entity ها بفرستم این encryption رو انجام بدم.پس با این روش دیگه خبری از کار کردن با hook های سمت دیتابیس نبود، دیگه قرار نبود تایپ primary key عوض بشه، قرار هم نبود فیلد جدیدی به هر مدل اضافه بشه. چه خوب! 🤩خب مشکل حل شد!؟نه!!!😳مشکل درواقع حل شده بود ولی من ساده دیده بودمش یا بهتره بگم سطحی دیده بودمش. این موضوع اعداد و رشته ها حل شد ولی مساله دیگه ای که حالا وجود داشت این بود که اگه یه عدد مثل 1 همیشه برای همه entity ها از جمله Project, Board, Task و ... دقیقا تولید یک رشته می‌کرد! بنابراین مشکل حل نشده بود فقط شکلش عوض شده بود.یکم سرچ کردم و فهمیدم میتونم این موضوع رو - تولید عدد encrypt شده و بعدا decrypt کردنش - برای هر کدوم از entity ها با یه مقدار از پیش تعیین شده شکلش رو عوض کنم. حالا هر id برای هر کدوم از entity ها با وجودی که توی دیتابیس به یک عدد (مثل همون ۱) اشاره می‌کردن ولی رشته های مختلفی ازشون درست شده بود که البته خیلی ساده هم بعد از request برمی‌گشتن به عدد اصلی شون توی دیتابیس.این اعداد ثابت هم میتونستن هر چیزی باشن (مثلا برای مدل User من عدد 11 رو گذاشتم، برای Board عدد 33 و همینطوری الی آخر). صرفا در زمان encrypt و decrypt شدن مدل ها باید اینم لحاظ می‌کردم.پس اینم آشنا شدن بیشتر من با مفاهیم encrypt و decrypt و NanoID و حتی هوک های دیتابیس.از NanoID استفاده کردم چون UUID خیلی طولانی بود و نمیخواستم اونقدر طولانی باشن (مثلا UUID طولش شاید بشه ۲۵ کاراکتر ولی NanoID طولش میشه 6 تا 8 کاراکتر، دست خودمونه) - از طرفی تا جایی که من سواد و تجربه داشتم میدونستم اگه بخوام UUID نگه دارم باید یه فیلد جدید توی دیتابیسم درست کنم که کمکی به Business Logic نمی‌کرد و خبری هم از decrypt شدن نبود.مشکل دوم ریفکتور کردن پروژه بود. یکم حالا وقت داشتم یه دستی به کد بکشم. یکم سرچ کنم ببینم چه روش های بهتری هست و برم سمت اونا. مثلا قبلا اگه یه کاری رو توی دو خط کد داشتم انجام میدادم تو یه خط حالا انجامش دادم. از مسائل سینتکسی که بگذریم رفتم سراغ اون سیستم routing.قبلا داشتم از Mux استفاده می‌کردم. برای خوندن بدنه request ها هم دستی داشتم انجامش میدادم و دستی هم داشتم response ها رو هندل می‌کردم. البته یه سری ‌‌helper برای نوشته بودم ولی بازم دستی بود. کلا هرچی نوشته بودم تا اون موقع در هدف کار کردن اپلیکیشن بود.پرفورمنس برام مطرح نبود. فقط کار کنه کافیه.خب من قبلا با چیزایی مثل Express توی Node آشنا بودم، Laravel هم دیده بودم در مورد Django هم شنیده بودم ولی ندیدم تاحالا😁. میدونستم که خیلی کار ها رو میتونن ساده تر کنن. پس فکر کردم که وقتشه برم سراغ یکی از این فریم ورک ها ولی توی GO. یه سرچی زدم دیدم آپشن زیاده. برام مهم نبود پرفورمنس کدومشون بهتره یا سریع تر هستن یا ... برام کامیونیتی مهم بود و سادگی شون. خداروشکر تو همه شون هم که میری نوشته سریع ترین و فلان ترین و ...😒 در نهایت انتخابم شد Fiber.خب یه مزیتی که Fiber داشت این بود که شباهت بی حد و اندازه ای به Express داشت که قبلا من کار کرده بودم، یعنی خیلی این موضوع Middleware ها توش مطرح بود. اومدم و اپلیکیشن رو خلاصه ریفکتور کردم و بردمش روی Fiber. این وسط کلی چیز حذف شد. کلی لاجیک دیگه رفته بود توی Middleware ها به جای اینکه توی هر handler تکرار بشه مثلا اون چک کردن auth. خلاصه اپلیکیشن یه مقدار پوست انداخت.تو مرحله بعد فکر کردم که چرا اون قسمت verify شدن کاربر ها رو به کمک Email هندل نکنم؟ یعنی واقعی به کاربری که ثبت نام میکنه ایمیل بزنم. برای اینکار دوباره رفتم سراغ AWS و این دفه با سرویس SES آشنا شدم. کانفیگ کردم و کد نوشتم و خلاصه اولین ایمیل فرستاده شد. البته فقط برای ایمیل های Verify شده که از قبل خودم تعریف کرده بودم نه به صورت public چون اون داستانای خودشو داشت که حالا واردش نمیشم. این وسط البته من فقط گفتم کانفیگ کردم و تمام و شما تو یه جمله میخونی و رد میشی ولی واقعا کانفیگش کلی زمان و انرژی گرفت 😅بعد گفتم چرا این ایمیل ها بخوان زشت باشن، چون تا اون موقع هر ایمیل فقط توش یه متن بود با یه کد ۶ رقمی فعال سازی. میدونستم که برای اینکه ایمیل ها خوشگل بشن باید یه کد HTML بفرستم به جای این متن. یعنی البته اون html رو به شکل یه string بدم بهش.پس رفتم سراغ Template Engine ها توی Go و یه Template ایمیل دانلود کردم به صورت HTML و از اون به عنوان قالب ایمیل ها استفاده کردم. اینجا بود که یاد گرفتم بعدا (در آینده) اگه بخوام مثلا صفحات static یا فرانتی هم parse کنم چجوری اینکار انجام میشه.بعد گفتم اصلا حالا تا اینجا که اومدیم، چرا اینو deploy نکنم؟قسمت بعد میرم سراغ ماجرای دیپلوی کردن اپلیکیشنم روی AWS و دردسر هاش و چیزایی که بهم یاد داد مثل Docker و Docker compose و Nginx و ... چیزایی مثل caching هم دیدم که به کمک Redis هندل کردم و چالش های خودش.بعد اینکه چطور شد که یه دستی به سر رو روی اپلیکیشن تو محیط Dev کشیدم و کارم رو با داکر ساده تر کردم، جلوتر هم دیگه پا رو فراتر گذاشتم و گفتم برم سمت Microservice ها. اونجا با کلی مفهوم دیگه آشنا شدم و معماری های مختلفی رو دیدم. این اپلیکیشن که با ایده کپی از Trello بوجود اومده بود داشت نم نم بزرگ تر می‌شد و به من کلی چیز یاد می‌داد.قسمت چهارم: https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B4-%D8%A7%DB%8C%D9%86-%DA%86%D9%87-%D8%AC%D9%87%D9%86%D9%85%DB%8C%D9%87-n8hh1ojsbr1r </description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Sat, 31 May 2025 14:52:12 +0330</pubDate>
            </item>
                    <item>
                <title>می‌خواستم GO یاد بگیرم، پس اینکارو کردم - قسمت ۲ - زیبایی ها</title>
                <link>https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B2-%D8%B2%DB%8C%D8%A8%D8%A7%DB%8C%DB%8C-%D9%87%D8%A7-chzqckhu4zlv</link>
                <description>اگه قسمت ۱ رو نخوندید اینجا پیداش می‌کنید: https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D9%87%D8%A7-ior92wjkaeua بعد از مقایسه تفاوت های JS و GO حالا به مرحله ای رسیده بودم که میتونستم کامل کد بزنم. البته صادقانه بگم، خیییییلی اشتباه می‌کردم و بعد اصلاح می‌کردم. خیلی می‌شد که سرچ میزدم ببینم کاری که میخوام بکنم تو این زبون چطور باید انجام بشه. ولی میدونید چیه؟ یاد گرفتن یه زبون جدید با داشتن تسلط به یه زبون دیگه کار رو خییلی ساده تر میکنه.من بلد بودم فکر کنم. بلد بودم که چطور باید کار انجام بشه، موضوع فقط پیاده سازی بود. موضوع فقط رفتار جدیدی بود که از زبون داشتم می‌دیدم. مثل رانندگی که وقتی بلدی یه ماشین رو برونی، دیگه برات فرقی نمیکنه چه ماشینی باشه، شاید بعضی ماشین ها خاص تر باشن یا مثلا اتوماتیک باشن یا بزرگ یا کوچک باشن ولی در نهایت رانندگی کردن رو بلدیم و ماشین فقط عوض شده.اعتبار تصویر از ChatGPTخب تا اونجا اومدم که نم نم داشت اپکلیشنم بزرگ تر میشد. برنامه ای قصد داشتم بنویسم یه سیستم Task management بود. اولین قسمت چی بود؟ اینکه یه کاربر داشته باشیم. روال ثبت نام. روالی که همه مون بار ها و بار ها انجامش دادیم و میدونیم چطور کار میکنه ولی من کرمم گرفته بود (و البته کمالگرایی) که حتما ثبت نامم خاص باشه با همه مراحل از جمله verification. ولی حالا جلو تر بهش می‌رسیم.یاد گرفتم چطور باید http request ها رو هندل کنم. یکم که جلوتر رفتم با یه کتابخونه به اسم mux آشنا شدم. میخواستم یه API داشته باشم که کاربر بتونه مثلا به register/ یه درخواست بزنه و ایمیل و پسورد بده و بهش بگیم که ثبت نام شدی. پس نیاز به routing داشتم، این همون چیزی بود که mux در اختیارم میذاشت. میتونستم handler ها رو به route ها مختلف assign کنم.فعلا کاربر های ثبت نامی رو توی یه متغیر نگه میداشتم. خبری از دیتابیس نبود. نمیتونستم تو این مرحله برم سراغش؟ معلومه که میتونستم ولی نمیخواستم! میخواستم اول کار کردن با دیتا تایپ ها رو بهتر یاد بگیرم. قبلا توی JS میشد یه Array ساخت و کاربر هم میشد یه Object ولی اینجا داستان متفاوت بود و باید دیتا تایپ های جدید یاد می‌گرفتم. مثلا توی Go چیزی که ما توی JS میگفتیم بهش Array رو بهش میگه Slice و چیزی که تو JS می‌گفتیم Object بهش میگه Map. البته اینم در نظر بگیریم که رفتارشون قطعا تفاوت هایی داشت ولی من برای سادگی بیشتر اینجا بهشون اینطوری اشاره کردم.خلاصه کنم، یه CRUD خیلی ساده روی همون Slice ها درست کردم. بهم کمک کرد درک بهتری از اون دیتا تایپ ها پیدا کنم. بعد از اون وقت این بود که این دیتا ها ذخیره بشن. اینجا میتونستم مستقیم برم سراغ یه دیتابیس مثل postgresql ولی گفتم باز هم ساده ترش میکنم. همه دیتا ها رو توی یه فایل db ذخیره کردم و به کمک sqlite بهش query زدم. ستاپ کردن اولیه sqlite هم جالب بود.یاد گرفتن همین query ها خیلی لذت بخش بود. البته ناگفته نماند که فعلا هم دیتایی که باهاش سر و کار داشتم ساده بود، هم عملیات های روشون . فعلا خبری از join زدن و... نبود. بهرحال اینکار انجام شد.روال ثبت نام و login رو پیاده کردم. بعد یه سری route جدید ساختم که بدون وجود توکن توی header از request کار نکنه. یه چیزی شبیه Guard داشتن. برای همین مسائلی مثل hash کردن پسورد و JWT هم لازم بود که هندل کنم و یاد بگیرم. البته قبلا (شاید ۴-۵ سال پیش) با Node همه اینکار ها رو انجام داده بودم و میدونستم که روال کار چجوریه. یا تو اپ های فرانت میدونستم که JWT چیه و اصولا چطور کار میکنه. فقط اینبار قرار بود با Go پیاده سازیش کنم.برسیم به اون ماجرای فعال کردن یا Verify کردن کاربر ها. یه کد verification که تو زمان ثبت نام ساخته می‌شد و تاریخ مصرف داشت مثلا ۵ دقیقه یا ۱۰ دقیقه، برای تولید اون عدد رندوم از ChatGPT خواستم یه تابع برام بنویسه برای اینکار. بعد گفتم همونو برام توضیح بده خط به خط 😂 چون یه کارای عجیبی داشت می‌کرد که برام جالب بود. بعد از گذشتن تاریخ مصرف اون کد هم (حالتی که مثلا کاربر میخواد کد برای resend بشه) باید کد جدید براش ایجاد می‌شد. که در نهایت کاربر رو فعال می‌کرد و ادامه ماجرا...در نهایت روال ثبت نام، فعالسازی کاربر، قابلیت ارسال مجدد کد فعالسازی و Login و میشه گفت کل Authentication کاربر انجام شده بود. عالی نبود ولی کافی بود.نکته ای که وجود داره اینه که اگه شما یه برنامه نویس کاملا صفر کیلومتر باشی شاید ندونی اصلا نیاز به این چیزا داری ولی تجربه Frontend ام به من داشت کمک می‌کرد. البته اینکه پسورد باید hash بشه که دیگه خیلی واضحه ولی باز به هر حال انگار به صورت خودکار یه سری چیز رو می‌دونستم و فقط داشتم روش انجام دادنش رو یاد می‌گرفتم.بعد نوبت رسید به تعریف کردن مدل ها و انتقال دیتا ها از اون فایل ساده به یه دیتابیس بهتر (بهتر که میگم نه از نظر پرفورمنس یا ... ها) مثل همون PostgreSQL. پس شروع کردم ستاپ کردن سیستم و کد ها که بتونم دیتا ها رو ببرم اونور. برای اینکار صرفا باید Driver دیتا هام رو از SQLite تغییر می‌دادم به Postgres. البته روش query زدن ها هم یه مقداری تغییر کرد در حد سینتکس ولی کلیت همون بود.یه نکته ای که اینجا بود این بود که هر زمان اپلیکیشن تغییر می‌کرد یا میخواستم نتیجه کد ها رو ببینم باید یه بار دیگه build می‌کردم، یعنی با هر تغییر فایل باید یه بار سرور رو میاوردم پایین و دوباره میاوردم بالا.قبلا توی Node یه چیزی بود به اسم Nodemon که ازش برای همین کار استفاده می‌شد. اینجا هم یه سرچی زدم دیدم که بله، اینجا هم یه چیزی داریم که دقیقا همون کارو میکنه به اسم Air. پس اونم ستاپ کردم که سرعت dev بره بالاتر و کارم راحت تر بشه.خلاصه دیتا ها رفت روی postgres و حالا وقتش بود که یکم model های جدید تر به سیستم معرفی بشه. اومدم یه تحلیل ریز از چیزی که میخوام بهش برسم انجام دادم:کاربر باید عضو می‌شد که بتونه تسک بسازه.کاربر میتونست چندین تسک مختلف داشته باشه.هر تسک حاوی یه عنوان و توضیحات بود و وضعیت بود. (بعدا چیزای دیگه هم بهش اضافه کردم که میرسم بهش)پس تا اینجای کار من دو تا model داشتم. اومدم و اونا رو تعریف کردم. نم نم داشت ارتباط بین این مدل ها شکل می‌گرفت. معنی Relational Database ها بیشتر داشت مهم می‌شد. پس باید مفاهیمی مثل کلید خارجی یا Foreign Key و Association و ... رو یاد می‌گرفتم. اما همچنان اصرار داشتم که به صورت Raw بیام و query هام رو بنویسم. چون میدونستم که اگه بخوام مستقیم برم سراغ ORM ها شاید عمق درکم از مسائل مربوط به دیتابیس کم بشه.گرچه واقعا کسی که یه Backend Developer حتی جونیور هم باشه الان خیلی بهتر از من میتونه query خام بنویسه. یاد گرفتن query ها و مفاهیم خیلی مهم مثل Query optimization یا Indexing یا Sharding و Relication و ... و کلیییی چیز دیگه هست که من هنوز کار باهاشون رو تجربه نکردم. (ولی همین که میدونم این موارد وجود دارن بهم حس اعتماد به نفس میده که بعدا میتونم برسم سراغشون.به مرور که داشتم API ها رو کامل ‌می‌کردم ایده این اومد به سرم که چرا هر تسک نتونه یه attachment داشته باشه؟ یه فایلی بشه بهش وصل کرد. اینجا یه راه ساده این بود که بیام مدل Task رو ویرایش کنم که فایل هم داشته باشه ولی بازم تجربه بهم میگفت که این روش خیلی reusable نیست. چون که اگه چند وقت بعد بخوام یه مدل دیگه به سیستم اضافه کنم که اونم بخواد یه سری فایل بهش اضافه بشه چی؟ اگه بعدا کاربر بخواد عکس پروفایل بذاره چی؟پس فایل ها رو به شکل یه مدل مستقل ایجاد کردم که اسمش شد File که فارغ از موجودیت های مختلف برای خودشون ماهیت مستقل داشته باشن و بشه اونا رو به هر چیزی Assign کرد. مثلا کاربر به عنوان تصویر پروفایلش یه فایل عکس رو آپلود کنه و تسک هم بتونه یک یا چند تا فایل یا attachment داشته باشه و کلا هر چیز دیگه ای.پس مدل File هم اینطوری متولد شد. حالا اون روابط داشت جالب تر می‌شد. هر کاربر میتونست یه تصویر پروفایل داشته باشه که درواقع یک مدل از File بود. هر تسک میتونست چندین attachment داشته باشه که باز هم یک مدل از File بود. دوباره Relational DB.برای آپلود فایل ها یه API جدید ایجاد کردم ولی پیش خودم گفتم، باحال نمیشه اگه همه فایل ها (خود فایل) رو روی S3 ذخیره کنی و فقط URL اش رو توی دیتابیس خودمون؟ چه فرصتی از این بهتر که با AWS هم یکم کار کنم و یاد بگیرمش! مخصوصا حالا که use case های خوبی هم تو ذهنم که میخوام بهشون برسم.پس وارد کهکشان AWS شدم. خب S3 یکی از ساده ترین سرویساش هست ولی برای اینکه وصلش کنم به اپلیکیشن واقعا دهنم سرویس شد. خب من که بکند دولوپر نیستم 😂 تجربه اولم هم بود. ولی آخر سر یه API داشتم که میشد از طریق upload/ صداش زد و فایل رو براش فرستاد و اون در جواب یه URL برمی‌گردوند که در واقع مسیر فیزیکی فایل روی S3 بود. حالا این URL (در واقع همون فایل) میتونست به هر جایی که ما میخوایم بچسبه! ایول!🤩 البته اینجا مدل فایل هم یکم تغییرات کرد مثل mime type و description و ...خب یکم داشت برام عادی می‌شد کد زدن GO. انگار داشتم هی کارای تکراری انجام میدادم:به ریکوئست گوش کن و بفرستش دست handler خودشچک کن کاربر لاگین باشه و توکن اش درست باشهدیتا رو ذخیره کن و جواب بده به کاربرتقریبا خیلی کد ها داشت توی اپلیکیشن تکراری می‌شد. ولی وجود داشتن یه سرویس third-party مثل همون S3 یه جذابیت تازه بهش بخشید. قبلا ها توی JS برای هندل کردن اینکارا از Promise ها استفاده می‌کردیم. میخواستیم اپلیکیشن به قول معروف پرمورمنس خوبی داشته باشه. گفتم بیام و همین سرویس رو توی GO ببینم چطور باید انجام بدم. یعنی به جای اینکه تابع رو اونجایی که باید با AWS ارتباط می‌گرفت به صورت Sync هندل کنم، بیام و Async هندلش کنم.اینجا بود که با Goroutine و channel آشنا شدم. رفتم توی دلش. به نظرم واقعا برای کسی که از دنیای JS وارد میشد، فهم این مفاهیم توی Go خیلی ساده تر بود. لااقل من خیلی راحت فهمیدم ولی تو یوتوب که سرچ می‌کردم انگار از اون موضوعات خیلی سختی هست که همه باهاش درگیرن.ناگفته نماند که از اونجا که مفهوم کد Sync و Async رو باهاش آشنا بودم از قبل، هم به فهم بهترش کمکم کرد هم میدونستم که edge case های خیلی خاصی داره و ممکنه race condition به وجود بیاد یا مثلا راجع به تفاوت نحوه اجراش توی Go نسبت به JS خیلی مطالعه کردم. نمیگم الان کامل و ۱۰۰٪ میفهممش ولی اندازه ای که لازمه برای کسی که ۲ ماهه وارد زبون جدید شده به نظرم کافیه و خوبه. البته چیزایی مثل Wait group ها هم هستن که به صورت تئوری باهاش آشنا شدم ولی هنوز جایی استفاده نکرده بودم تا اینجای کارم. (البته کاربردی هم برام نداشتن و منم اصراری نداشتم حتما توی کدم اونا رو بچپونم😁)از این که بگذریم حالا یه اپلیکیشن داشتم که کاربر میتونست ثبت نام کنه و بعد از verify و login یه توکن بگیره و شروع کنه تسک جدید ساختن با عنوان و توضیحات و وضعیت (به این می‌رسم)، بعد یه فایل آپلود کنه و اون فایل رو به تسک Assign کنه یا در زمان ساخت تسک اصلا آدرس فایل هم بهش بده.تا اینجا تسک ها هر کدوم همونطور که گفتم یه وضعیت داشتن. به صورت پیشفرض سه مورد براشون در نظر گرفته بودم که اینا بودن: &quot;done&quot; و &quot;in progress&quot; و &quot;todo&quot;. این سه تا رو به صورت ثابت توی کد تعریف کرده بودم.یه چیزی شده بود برای خودش تا اینجا. ولی آیا همین بود؟ نه! خیلی قرار بود موضوع پیچیده تر بشه. نم نم فهمیدم که برای اینکه ساختار دیتابیس رو بخوام تغییر بدم (مثلا یه فیلد جدید اضافه کنم به همون task یا مدل های جدید تر) باید اینکار رو به شکل امنی انجام داد. یعنی آشنایی با مفهوم Migration ها. قبلا خیلی دیده بودم و شنیده بودم. از دوستای بکند کارم یا توی کد ها خونده بودم. ولی خودم دست نزده بودم بهش. اینجا ولی وقتش بود (تقریبا)پس اومدم و Migration ها رو به سیستم اضافه کردم. حالا میتونستم هر زمان که ساختار جدول هام تو دیتابیس عوض می‌شد اونا رو دنبال کنم. ورژن بزنم و کنترل کنم. البته هنوز خیلی جاهاش برای من گنگ هست ولی شروع خوبیه.توی قسمت های بعدی میگم که چطوری رفتم سمت اینکه این سیستم رو تکمیل تر کنم و فیچر های بیشتر بهش اضافه کنم. روابط model ها پیچیده تر شدن و دیگه رفتم سمت استفاده از یه ORM. فهمیدم که تعریف کردن فقط سه وضعیت برای مدل Task کار خیلی درستی نبود. البته تا اینجا خوب بود ولی جلوتر فهمیدم میشه بهتر اینو هندل کرد.بعد تر میگم که چطور کنجکاوی من رو برد به سمت مسائل پیچیده تری از DevOps و داکر و مایکروسرویس ها. با سرویس های دیگه از AWS مثل IAM و EC2 و SES آشنا شدم.هنوز کلی راه برای رفتن داشتم.قسمت سوم رو اینجا می‌تونید بخونید: https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B3-%D9%85%D8%B3%DB%8C%D8%B1-%D9%87%D8%A7%DB%8C-%D8%AC%D8%AF%DB%8C%D8%AF-u5iodboridsg </description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Fri, 30 May 2025 02:32:00 +0330</pubDate>
            </item>
                    <item>
                <title>می‌خواستم GO یاد بگیرم، پس اینکارو کردم - قسمت ۱ - تفاوت ها</title>
                <link>https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B1-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D9%87%D8%A7-ior92wjkaeua</link>
                <description>یاد گرفتن یه زبون برنامه نویسی جدید میتونه خیلی چالش داشته باشه. از کجا شروع کنم؟ چی یاد بگیرم؟ الان کجای کارم؟ آیا کارم خوبه؟ تا کجا میتونم کشش بدم؟ فکر می‌کنم این سوالا برای هرکسی که بخواد وارد یه حوزه جدید بشه پیش میاد.یادمه اوایل که میخواستم فرانت-اند یاد بگیرم و کار کنم، دنیایی بدون AI و کورس ها و پکیج های چند میلیونی بود. اون موقع فقط علاقه و پشت کار و تلاش مستمر و عشق به کار بود که منو هل میداد که ادامه بدم. اون موقع دسترسی به منتور ها و افرادی که بتونن کمکت کنن به سادگی امروز نبود.ولی امروز ماجرا متفاوته، امروز خیلی چیزا هست که اگه بدونی چطور ازشون استفاده کنی میتونن سرعت پیشرفتت رو به چشم چشم گیری بیشتر کنن. میتونی از ویدئو های یوتوب شروع کنی و اصول اولیه رو یاد بگیری و بعد بری سراغ ساختن یه چیزی. هر چیزی. نباید یه چیز کامل باشه، فقط یه چیزی که کار کنه کافیه. بعد بهبودش بدی و بهترش کنی. برگردی عقب و اشتباهاتت رو ببینی. یه جاهایی از کاری که قبلا کردی درس می‌گیری و دوباره تکرارش نمی‌کنی. میتونی با یه منتور صحبت کنی و ازش مشورت بخوای. میتونی توی لینکدین با افراد با سابقه اون حوزه تماس بگیری و مسیر بگیری. میتونی به کمک AI مسیرت رو بهبود بدی.برای من ولی یه مقدار متفاوت بود. خب من تقریبا ۱۰ ساله که دارم کار میکنم. خیلی چیز ها رو میدونم. با خیلی مفاهیم هر چند شاید دور، ولی آشنا هستم. توی کار باهاشون برخورد داشتم، بعضی وقتا خیلی چیزا رو می‌شنیدم ولی نمیدونستم چی هستن یا دارن چیکار میکنن. اما در نهایت میدونستم به چی میخوام برسم. قدم اول برای من این بود که ببینم کجا میخوام برم.بعد از اینکه از ایران خارج شدم تازه کلی مفاهیم جدید تر هم بهشون برخورد کردم که توی ایران به خاطر محدودیت های داخلی یا تحریم یا ضعف های فنی و کلی دلیل دیگه اصلا اطلاعی راجع بهشون نداشتم. پس تازه انگار چشمام باز شد، برای من خارج شدن از ایران صرفا رهایی از استفاده از ابزار های دور زدن فیلتر و تحریم نبودن، استفاده از کارت های بانکی متصل به شبکه جهانی نبودن. برای من دسترسی به اطلاعات و فضایی بود که حالا میتونم ازشون خیلی بهینه تر استفاده کنم.از این صحبتا که بگذریم، براتون بگم که من چه کار کردم که GO یاد بگیرم. پس مطلب تازه از الان شروع میشه.اعتبار تصویر با ChatGPTمن تسلط نسبتا خوبی روی JavaScript دارم. هنوز نمیگم من استاد این زبون هستم ولی جایی ایستادم که میتونم باهاش یه کارایی بکنم. میتونم بگم که دیگه برایم فریم-ورک مهم نیست. میتونم بگم برام دیگه کتابخونه مهم نیست چون باور دارم همیشه اگر تسلط خوبی روی زبان وجود داشته باشه، باقی چیز ها ابزار هستن.این ابزار ها برای ما کار رو راحت میکنن ولی ما باید بدونیم دقیقا زیر اون لایه خوشگل بالایی چه پیچیدگی هایی هست. نه اینکه خودمون بریم زیر و بم همه چیز رو دربیاریم، بلکه دست کم کنجکاو باشیم و صرفا ابزار ندونیم.هر زبان برنامه نویسی به نظرم ۳ اصل پایه ای و اساسی داره. پس نقطه شروع خوبیه که از همینجا شروع کنیم یادگیری. این سه اصل این ها هستند:تعریف متغیر و تایپ ها (Types and Assignment)شروط و عملگر ها (Conditions and Operators)حلقه ها (Iteration)این سه مفهوم توی تمام زبان ها اشتراک دارن. شاید Syntax ها متفاوت باشن ولی این سه اصل وجود دارن. میدونم که کلی چیز دیگه هم هست مثل OOP یا Function ها یا FP یا حتی موارد پایه ای تر مثل Memory Management و خیلی چیزای دیگه.اما من ساده شروع کردم. اول یاد گرفتم همین سه کار توی Go چه شکلی انجام میشن. چه تایپ های مختلفی توی این زبون وجود داره. برای اینکه تجربه خوبی روی JS داشتم خیلی سعی می‌کردم به شکل مقایسه ای بهش نگاه کنم. مثلا تعریف متغیر توی JS چطور انجام میشد، و حالا توی Go به چه صورتی انجام میشه. توی JS ما چه تایپ هایی داشتیم و حالا توی Go چطور این اتفاق میوفته.به کمک ChatGPT این مقایسه کردن ها برام خیلی ساده تر انجام شد. شاید بگم من تو چند ساعت کل سینتکس رو یاد گرفتم. حتی موارد خیلی عجیب و غریبی که برام خییییلی عجیب بود، به کمک روش مقایسه کردن هم شیرین شد هم قابل فهم. بذارید براتون چند تا مثال بزنم که به نظر خودم خیلی جالبن:توی JS ما به تمام اعداد میگیم number ولی توی Go اعداد تایپ های مختلفی دارن (البته برای خیلی تایپ های دیگه هم این تفاوت وجود داره ولی من فقط به عدد اشاره کردم چون خیلی ملموسه)توی JS هر تابع میتونه فقط یک مقدار رو return کنه ولی توی Go توابع میتونن چندین مقدار مختلف رو برگردوننشکل تعریف کردن تایپ ها توی Go خیلی شبیه TypeScript هست ولی حتی از اون هم بهتره! مثلا توی ورودی تابع شما میتونی سه تا arg رو پشت هم بنویسی و بگی تایپ همه اینا string هست.توی هر دو زبان scope ها به شدت شبیه همدیگه هستن.البته یه تغییر خیلی بزرگی که کلا JS نسبت به Go داشت و این خیلی مهمه قبل از شروع، این بود که توی JS شما کدتون به صورت runtime اجرا میشه و کامپایل نمیشه. مگه اینکه از TS استفاده کنید ولی بذارید باهاتون صادق باشم: واقعا مدل کار کردن TS نسبت به یه زبونی مثل Go که کامپایلری هست انقدر احمقانه و ساده است که من بعد از یه مدت کار کردن با Go اینطوری ام که واقعا TS خیلی شت هست 😂. بگذریم... پس قبل اینکه شما کدتون رو بخواید اجرا کنید توی Go بر خلاف JS باید کدتون کامپایل بشه. اگه مشکل runtime داشتیم پس چی ‌میشه؟ بعدا میرسیم بهش.بعد از یاد گرفتن اولیه سینتکس، شروع کردم به ساختن چیز های خیلی ساده. همون برنامه های احمقانه ای که همه مون تو مسیر برنامه نویسی انجامش دادیم. یه برنامه که چندتا عدد بگیره و جمع کنه یا یه برنامه که سن شما رو بتونه حدس بزنه یا از طریق CMD بتونه یه فایلی بسازه و ادیت کنه و ...هدفم ساختن یه چیز مفید و به درد بخور نبود، هدفم این بود که با سینتکس بیشتر آشنا بشم. با پکیج های built-in زبان آشنا بشم و قابلیت های زبون رو بشناسم. پس کمالگرایی رو کامل گذاشتم کنار. برام مهم نبود که پرفورمنس کدی که نوشتم خوبه یا نه، برام مهم نبود کدی که مینویسم چقد style درستی داره یا ... فقط میخواستم بنویسم که یاد بگیرم.بعد رفتم سراغ نوشتن اپلیکیشن هایی که چند تا فایل داشتن. گفتم بذار کدم رو تمیز کنم، پس قدم اول این بود که بعضی توابع رو ببرم توی یه فایل دیگه. خب توی JS ما میتونیم از توابع یا متغیر یا هرچیز دیگه ای که دوست داریم تو یه فایل دیگه استفاده کنیم. به شرطی که اونجا export کرده باشیم و جایی که میخوایم استفاده کنیم import کنیم. بماند که این وسط برای اینکه این فایل ها رو یکجا تجمیع کنیم (چون در نهایت کد رو میدیم browser اجرا کنه) نیاز داریم به ابزار های build گرفتن مثل Webpack یا Rollup و ... اگه توی Node هم باشیم بازم بستگی به یه سری پارامتر دیگه داره که کاری نداریم حالا.ولی توی Go این کار به کمک package انجام میشه. یعنی نیازی نیست حتما توی اون فایل بهش اشاره کنی که میخوام این تابع رو export کنم. البته میگی ها... ولی اصلا شبیه JS نیست! خیلی راحت میتونی توابع ات رو توی یه namespace بذاری و حرف اول اون تابعی که میخوای جای دیگه استفاده کنی رو بزرگ بنویسی. مثلا به جای اسم yechizi بذاری Yechizi همین یعنی داری این تابع رو export میکنی! چه باحال!بعد اینکار گفتم خب برم چندتا پکیج third-party نصب کنم. میخواستم یه اپلیکیشن بسازم که به یه درخواست فقط جواب بده. مثلا روی پورت ۳۰۰۰ بیاد بالا و یه ping/pong ساده رو هندل کنه. دیدم که برای انجامش میتونم از پکیج های built-in استفاده کنم. که خداییش کار کردن باهاش هم خیلی ساده بود ولی گفتم حالا که اول نیت کردم یه پکیج نصب کنم، اصلا اینجا تفاوتش با js چطوریه؟ اصلا فرض کنیم Go نداشت این پکیج رو خودش. خب ما توی JS یه پکیج منیجر داریم که اصولا یا npm هست یا yarn یا npmn یا ... که در نهایت یه فایل package.json میسازن و یه lock فایل که check sum ها رو نگه میداره، همه depencency ها رو لیست میکنن و ورژن کنترل رو انجام میدن. پکیج های نصب شده هم میذارن تو یه سیاه چاله ای به اسم node_modules که معرف حضورتون هست که اگه منو دنبال کرده باشید.دیدم روش کار کردنش توی Go در عین سادگی، خیییییییلی موثر هم هست. اینجا هم ما یه فایلی مشابه package.json و lock داریم ولی فقط از دور شبیه اش هست! هیچ خبری از node_modules یا معادلش نیست. مدل import کردن این پکیج ها به خیلی شبیه deno انجام میشه (البته به نظرم deno شبیه go هست و نه برعکس) یعنی هرجا که شما میخوای از یه پکیجی استفاده کنی مستقیم آدرسش رو مینویسی. حالا ممکنه این آدرس یه لینک گیت باشه یا پکیج داخلی خود اپلیکیشن خودت.اول به نظر می‌رسید که خیلی پیچیده یا سردرگم کننده است، ولی یه مقدار که باهاش کار کردم متوجه مزایای دیگه اش هم شدم. مثلا توی JS اگه دوتا پکیج به یه اسم یا آدرس داشته باشیم برای import کردنشون عملا راهی نداریم. ولی اینجا شما میتونید دقیقا از یک آدرس (پکیج) توی یک فایل چند بار با اسامی مختلف import کنید. اشتباه برداشت نکنید البته، میدونم که توی JS قابلیت alias کردن هست،‌ ولی مثلا شما دوبار توی دو خط نمیتونید از یه پکیج import کنید ولی اینجا به کمک اون namespace ها اینا با هم تداخلی نمیخورن. گرچه باز هم امکان alias کردن هم وجود داره که خب... چی از این بهتر.تا جایی که یادم میومدم تفاوت ها رو گفتم و اشاره کردم. ولی این مسیر ادامه داشت. نم نم داشتم اپلیکیشنی می‌نوشتم که یه کاری انجام میداد. نیاز شد که بیشتر با دیتا تایپ های مختلف کار کنم مثل slice ها یا map ها. اینکه چطور بتونم تغییرشون بدم. نم نم از ذخیره اطلاعات روی memory بیام و روی فایل ذخیره کنم و بعد ببرمش روی یه دیتابیس که تو قسمت های بعد میرسیم به اونجا هم.پی‌نوشت: هدفم از ثبت کردن این مسیر دو چیز هست. اول اینکه برای خودم بمونه یادگاری و بعدا بتونم بهش سر بزنم شاید بفهمم کجا ها رو درست و کجا ها رو اشتباه اومدم. دوم اینکه شاید برای شما هم که میخواید یه زبون یا تکنولوژی جدید یاد بگیرید، بتونه ایده ای بده از اینکه راه رو چطور برید و قدم بعدی رو چطور تعیین کنید. البته اینا تجربه منه.قسمت دوم: https://virgool.io/@hesanam/%D9%85%DB%8C-%D8%AE%D9%88%D8%A7%D8%B3%D8%AA%D9%85-go-%DB%8C%D8%A7%D8%AF-%D8%A8%DA%AF%DB%8C%D8%B1%D9%85-%D9%BE%D8%B3-%D8%A7%DB%8C%D9%86%DA%A9%D8%A7%D8%B1%D9%88-%DA%A9%D8%B1%D8%AF%D9%85-%D9%82%D8%B3%D9%85%D8%AA-%DB%B2-%D8%B2%DB%8C%D8%A8%D8%A7%DB%8C%DB%8C-%D9%87%D8%A7-chzqckhu4zlv </description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Wed, 28 May 2025 15:48:14 +0330</pubDate>
            </item>
                    <item>
                <title>تغییر بدون ترس: با Feature Flag برو، با A/B Test ببین!</title>
                <link>https://virgool.io/@hesanam/%D8%AA%D8%BA%DB%8C%DB%8C%D8%B1-%D8%A8%D8%AF%D9%88%D9%86-%D8%AA%D8%B1%D8%B3-%D8%A8%D8%A7-feature-flag-%D8%A8%D8%B1%D9%88-%D8%A8%D8%A7-ab-test-%D8%A8%D8%A8%DB%8C%D9%86-xkcwcim6axnk</link>
                <description>یه بار داشتم توی Doulingo یه درس انجام میدادم، یهو بعد از ۵ تا تمرین اول یه انیمیشن رعد و برق برام زد، تا حالا ندیده بودم اونو با وجودی که هر روز تمرینامو انجام میدادم. بنابراین هر روز داشتم از اپلیکیشن استفاده می‌کردم و نسخه قدیمی ای نبود. از دوستم پرسیدم که باهم داشتیم کوئست انجام میدادیم و اون گفت که نه این چیز جدیدی نیست و برای من خیلی وقته اینطوریه!اتفاقی که داشت برای ما میوفتاد یه مدلی از A/B Testing بود. اگه من از دوستم نمی‌پرسیدم متوجه نمیشدم که این قابلیت از قبل هم بوده و من اونو نمیدیدم ولی اون قبلا هم اونجا بود! این موضوع توی بیزنس خیلی مهمه مخصوصا برای تصمیم گیری در مورد اینکه یک قابلیتی که بهش اطمینان نداریم رو بتونیم تست و بررسی کنیم و اگر نتیجه تست ها مثبت بود اضافه اش کنیم وگرنه بیخیالش بشیم.تجربه ای که براتون تعریف کردم یه مفهوم ساده و در عین حال خیلی کارآمده به اسم A/B Testing. نحوه کارش اینطوریه که شما یک فیچر یا UI یا فرایند یا هرچیزی رو به دو یا چند شکل مختلف پیاده سازی می‌کنید و بعد هر کدوم از اون نسخه ها رو در اختیار دسته ای از کاربراتون قرار میدین، فیدبک می‌گیرید و تصمیم گیری ‌می‌کنید. این قابلیت میتونه یک تغییر ساده در ظاهر (UI) باشه مثل این که کاربر ها با کدوم رنگ یا کدوم شکل بیشتر راحت بودن یا حتی یک Flow کاملا مستقل.سناریو: کدوم شکل؟سه تا دکمه با حالت های مختلف داریم. ببینیم کاربر بیشتر با کدوم ارتباط می‌گیره. هدف اینه که کاربر روی این دکمه کلیک کنه. حالا پارامتر های مختلفی وجود داره که این جذابیت رو براش ایجاد کنیم، میتونیم از شکل شروع کنیم:تو این حالت چیزی که داریم کنترل می‌کنیم شکل دکمه است. و بله من میدونم که این شکل ها توی Context و خیلی پارامتر های دیگه تعریف ‌میشن و معنا پیدا میکنن ولی بیاید ساده بهش نگاه کنیم.یا میتونیم روی رنگ بازی کنیم:در هر حالت، ما میخوایم ببینیم که کاربر در هر کدوم از این مدل ها با کدوم بیشتر ارتباط برقرار میکنه. در هر حالت کاربر متوجه این موضوع نیست که سناریو های دیگه ای هم وجود داره. کاربری که داره رنگ نارنجی رو میبینه، فقط همون رو میبینه و کاربری که شکل دکمه های با لبه های تیز، باز هم همون. بعد از مدتی وقتی اطلاعات جمع آوری شد تصمیم گیری صورت می‌گیره.سناریو: تکمیل اطلاعات پروفایلاین سناریو برای کاربر ها اختیاری هست ولی برای بیزنس داشتن اون اطلاعات ارزشمنده. چرا ارزشمنده؟ چون بیزنس میتونه بر اساس اطلاعات اختیاری مثل سن و جنسیت و یا علایق کاربر ها، پیشنهاد های بهتری بهشون بده. پس برای بیزنس و مارکتینگ مهمه که این اطلاعات رو داشته باشه ولی از طرفی هم نمیخوایم کاربر رو مجبور کنیم که این اطلاعات رو وارد کنه چون خیلی ها قطعا دوست ندارند!پس اینجا میخوایم یک سیاستی رو پیاده سازی کنیم که بالاترین نرخ ورود اطلاعات رو داشته باشیم در عین حال همچنان این فرایند اختیاری بمونه. خب بنابراین اگر ما این فرایند رو پیچیده طراحی کنیم ممکنه کاربر همون اول کار بیخیال بشه و بره ولی اگه فرایند رو براش راحت یا جذاب کنیم، احتمالا تمایل بیشتری برای ادامه دادنش داشته باشه.دو تا سناریو در نظر می‌گیریم:دسته اول کاربر ها بعد از اینکه توی سایت ثبت نام می‌کنن، میخوایم که وارد پروفایل شون بشن و اطلاعات رو تکمیل کنن.دسته دوم کاربر ها برای تکمیل این اطلاعات یه امتیازی میدیم! مثلا فلان کد تخفیف رو میگیری بعد اینکه اطلاعات پروفایلت رو وارد کنی.در هر دو حالت کاربرا آگاهی ندارن که دارن مورد آزمایش قرار می‌گیرن. ممکنه دسته اول چون دقیقا بعد از ثبت نام ازشون درخواست میشه، اطلاعات رو تکمیل کنن. ممکن هم هست دسته دوم برای دریافت کد تخفیف، بیشتر تمایل داشته باشن که اطلاعات پروفایل رو وارد کنن. شاید هم هیچکدوم کار نکنه یا هر دو به یه اندازه اوکی باشن! ما نمیدونیم!نکته مهم توی بحث A/B Testing ایده آل هست که کاربر ها دقیقا به طور برابری هر دو نسخه رو ببینن، یعنی اگر ۱۰۰۰ تا کاربر دارن نسخه A رو میبینن، ۱۰۰۰ تا کاربر دیگه نسخه B رو ببینن. اینطوری راحت تر میتونیم اندازه گیری کنیم.این که چطور بفهمیم کاربر ها با کدوم مدل پیاده سازی بیشتر ارتباط برقرار کردن، بر اساس Log هایی هست که در زمان تعامل با اون قابلیت خاص ازشون جمع‌‌آوری می‌کنیم. این لاگ ها میتونن بر اساس نیاز های ما تعیین بشن، مثلا نرخ کلیک، مدت زمانی که کاربر تو صفحه مونده، نرخ تبدیل و ...تا نخوایم نشون نمیدیم: Feature Flagاین یه تکنیکه که به توسعه‌دهنده‌ها اجازه می‌ده قابلیت‌های جدید رو بدون اینکه بلافاصله برای همه کاربران فعال بشن، در کد اضافه کنن. این یعنی می‌تونی یه فیچر رو با خیال راحت بنویسی و حتی Deploy کنی، ولی فقط برای بخشی از کاربران (یا حتی فقط تیم خودت) فعالش کنی.از Feature Flag می‌شه برای موارد مختلفی استفاده کرد: تست تو محیط واقعی، اجرای rollout تدریجی، فعال‌سازی قابلیت‌ها فقط برای کاربران خاص (مثلاً کاربران Premium یا بتا تسترها یا تیم خودمون)، یا حتی خاموش کردن سریع یه قابلیت مشکل‌دار بدون نیاز به deploy جدید. تصور کن یه فیچر باعث خطا شده، ولی به‌جای rollback کل نسخه روی گیت، فقط اون فیچر رو غیرفعال می‌کنی و بقیه‌ی سیستم به کارش ادامه می‌ده.در عمل، پیاده‌سازی Feature Flag می‌تونه ساده یا پیچیده باشه. می‌تونی با یه شرط ساده مثل if (showNewFeature) توی کدت داشته باشیش، یا از سرویس‌های داخلی رو سرور خودت یا حتی ابزار های third-party استفاده کنی که کنترل خیلی دقیق‌تری روی فلگ‌ها دارن (مثلاً فعال‌سازی براساس درصد، کشور، نقش کاربر، زمان‌بندی و غیره). اما ایده اصلی اینه که کنترل کامل دست خودته، در نهایت همون مفهوم فیوزباکس هست که انگار چندتا چیز رو خاموش و روشن میکنی. مهم‌ترین مزیتش اینه که توسعه و انتشار رو چابک‌تر، امن‌تر و قابل کنترل‌تر می‌کنه.فرق A/B Test با Feature Flag و ترکیب شون باهماگه مخاطب باهوشی که شما باشی، اینجا یه لامپی باید بالا سرت روشن شده باشه.توی A/B Test یعنی دو یا چند نسخه از یه قابلیت یا طراحی رو به کاربرها نشون بدی و ببینی کدومش بهتر عمل می‌کنهتو Feature Flag مثل یک سوییچه: روشن یا خاموش. قابلیتت رو پشتش مخفی می‌کنی و فقط برای بعضی کاربرها روشنش می‌کنی.حالا که فرق شون رو میدونیم بریم چندتا مثال دنیای واقعی رو باهم بررسی کنیم:فرض کن تیم محصول Spotify می‌خواد یک طراحی جدید برای صفحه‌ی “Now Playing” رو تست کنه. اون‌ها این طراحی جدید رو پشت یک Feature Flag قرار می‌دن، تا فقط برای ۵٪ از کاربران فعال باشه. اما در همین ۵٪، دو نسخه‌ی متفاوت از طراحی (مثلاً با کنترل‌های پخش در بالا یا پایین صفحه) به‌صورت A/B بین کاربران پخش می‌شه. اینجوری اگر کل طراحی مشکل داشت، می‌تونن فلگ رو خاموش کنن، و اگر فقط یکی از نسخه‌ها عملکرد ضعیفی داشت، اون رو در تست حذف کنن.یا مثلاً LinkedIn زمانی که قابلیت “Open to Work” رو معرفی کرد، نمی‌دونست دقیقاً چه نوع نمایش یا phrasing برای کاربران جذاب‌تره. پس این قابلیت پشت یک Feature Flag قرار گرفت و تنها برای بخشی از کاربران فعال شد. در همین حال، تیم UX دو نسخه مختلف از عبارت یا نمایش اون رو. توی پروفایل کاربرا تست کرد. مثلا عبارت ”Open to Opportunities” یا ”Actively looking”. این ترکیب بهشون اجازه داد هم feature رو مرحله‌ای rollout کنن، هم بهترین پیام رو پیدا کنن.یا توی فروشگاه های بزرگ، مثل Zalando یا Amazon، این روش خیلی مرسومه. مثلاً وقتی بخوان یک الگوریتم جدید مرتب‌سازی محصولات رو تست کنن یا سیستم پیشنهاد محصولات مشابه، اول اون الگوریتم رو پشت Feature Flag پیاده‌سازی می‌کنن تا اگر سیستم دچار افت شد، بشه به‌راحتی غیر فعالش کرد و فاجعه نشه. ولی در همین حال، الگوریتم جدید در نسخه A و قدیمی در نسخه B به کاربران مختلف نمایش داده می‌شه تا نرخ کلیک و خرید مقایسه بشه.ترکیب A/B Testing با Feature Flag به ما این توانایی رو می‌ده که هم با اطمینان تغییرات مهم رو منتشر کنیم، و هم با داده و تست واقعی تصمیم بگیریم که چه چیزی واقعاً بهتر عمل می‌کنه. این ترکیب، قلب فرآیند Continuous delivery در شرکت‌های بزرگه.امیدوارم ایده رو تونسته باشم به طور کلی براتون توضیح داده باشم، نمونه کدی نذاشتم چون روش های پیاده سازی همه یه کار انجام میدن که ایده بزرگ پشتش همون جعبه فیوز هست. یه تعداد boolean داخل یه Object یا لیست و چک کردن شون با شرط و ... پس خیلی چیز عجیبی نداشت. مطمئنم که خودتونم میتونین پیاده سازیش کنین.اگه دوست داشتین میتونید از طریق لینکدین باهام در ارتباط باشین.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Tue, 20 May 2025 15:14:23 +0330</pubDate>
            </item>
                    <item>
                <title>پیاده سازی سرویس دانلود ویدئو به سبک YouTube در React</title>
                <link>https://virgool.io/@hesanam/%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D8%AF%D8%A7%D9%86%D9%84%D9%88%D8%AF-%D9%88%DB%8C%D8%AF%D8%A6%D9%88-%D8%A8%D9%87-%D8%B3%D8%A8%DA%A9-youtube-%D8%AF%D8%B1-react-ctjojpfyu3z3</link>
                <description>اول اینکه عنوان این مطلب اصلا چیزی که میخوام نیست ولی بهتر از این نمیشد.یک کنجکاوی ای که من همیشه نسبت به سرویس Premium یوتوب داشتم این بود که شما میتونین ویدئو رو دانلود کنین و بعدا حتی آفلاین هم بهش دسترسی داشته باشین. اما یوتوب همینطوری بهتون یه فایل mp4 یا مشابه اش رو نمیده، یعنی عملا شما برای استفاده از اون محتوا باید مجدد وارد یوتوب بشید و برید قسمت دانلود هاتون و اونجا بهشون دسترسی دارید.سوال بزرگ اینجاست که پس این ویدئو ها کجا ذخیره میشن؟ اصلا چطور این ذخیره سازی صورت میگیره و نحوه کارش چطوریه؟ و از اون جذاب تر: چطور میتونیم خودمون یه مدل مشابه (خیلی البته ساده تر) رو پیاده سازی کنیم؟! تصویر به کمک هوش مصنوعی - لعنتی خیلی خوبهبرای اینکه مساله رو بررسی کنیم، بذارید توی چند قدم کلی و ساده موضوع رو ببینیم:شکستن ویدئو به قسمت های (چانک) کوچکتر برای ذخیره و استریم بهینه ترذخیره سازی به کمک IndexedDB - البته با چاشنی Encoding و یه سری خرت و پرت دیگهبازیابی ویدئو ذخیره شده و پخش به صورت آفلاین (بعد از Decrypt و یه سری خرت و پرت دیگه)همین!ساز و کار اولیهیوتوب کلا یکی از BadASS ترین سرویس هایی هست که اون بیرون وجود داره، توضیح کار هایی که پشت پرده داره اتفاق میوفته (کاری با الگوریتم و درآمدزاییش و ... ندارم) کار خیلی مشکلیه. ولی برای اینکه در ساده ترین حالت ممکن موضوع رو ببینیم این اتفاقیه که میوفته:یک فرد به عنوان تولید کننده یک محتوای ویدئویی، با یک کیفیت مشخص مثلا در نظر بگیریم به صورت 4K یک ویدئو رو تهیه میکنه و از طریق یوتوب اون رو آپلود میکنه. در زمانی که ویدئو آپلود میشه، سرویس های داخلی یوتوب ویدئو رو با کیفیت های مختلف تبدیل و در یه فضایی (ما نمیدونیم کجا) ذخیره میکنن. این یعنی با وجودی که محتواساز ویدئو رو با بالاترین کیفیت آپلود کرده ولی کیفیت های پایین تر اون ویدئو هم ذخیره شدن پس بنابراین ما یک ویدئو داریم با چند کیفیت مختلف. دلیلش هم که دیگه واضحه. (سرعت اینترنت و اندازه screen کاربر و ... و ...)بعد از اینکه ویدئو روی یک فضایی روی سرور (که ما نمیدونیم کجا)‌ ذخیره شدن، حالا وقتشه که کاربرا بتونن بهش دسترسی داشته باشن. شما زمانی که یه ویدئو رو باز می‌کنید تا ببینید، حتما دقت کردید که پلیر شما یه مقداری از اونجایی که شما دارید میبینید جلوتره و دانلود شده (یا بهتره بگیم بافر شده):خب یوتوب برای اینکار چند تا قانون هم داره که جالب هستن، با وجودی که این ویدئو نزدیک به ۵۴ دقیقه هست، همیشه این مقدار دانلود شده به یک اندازه محدودی جلوتر میره نه کل ویدئو. یعنی اگه در نظر بگیریم من در دقیقه ۲ باشم، بافر تا دقیقه ۴۰ رو نیازی نیست دانلود کنه حتی اگه من مشکل سرعت اینترنت نداشته باشم) و فقط تا دقیقه ۶ رو داشته باشه براش کفایت میکنه.برای اینکار هم چندتا دلیل وجود داره:ممکنه کاربر اصلا تا انتهای ویدئو رو نبینه و پشیمون شه و بره پس منابع رو برای چی هدر بدیمممکنه سرعت اینترنت باعث بشه همیشه کل ویدئو رو نشه با بالاترین کیفیت دانلود کرد پس دستمون بازه که تا هرجایی که ممکن بود با کیفیت خوب دانلود و بافر بشه و هرجا که به مشکل خوردیم کیفیت رو بیاریم پایین تر که در هر صورت کاربر بتونه ویدئو رو ببینه و نریم توی لودینگمیشه از این لاجیک برای استریم های لایو هم استفاده کردبرای اینکه بتونه این بافر رو به بهترین شکل انجام بده که بهترین تجربه کاربری رو داشته باشه، یوتوب ویدئو رو به قسمت های (چانک) خیلی کوچکتری میشکنه. من نمیدونم دقیقا این الگوریتم دقیقا به چه شکلی اینکارو انجام میده. یعنی برای این ویدئو یک ساعته آیا اون رو به ۶۰ قسمت ۱ دقیقه ای یا ۱۲۰ قسمت ۳۰ ثانیه ای یا ۲۴۰ قسمت ۱۵ ثانیه ای یا ...یا ممکنه حتی بستگی به حجم و طول ویدئو داشته باشه. ولی اینکار در هر صورت انجام میشه. این کار خیلی مهمه. جلوتر توی پیاده سازی میبینیمش.برای پخش ویدئو با این تفاسیر نمیشه همینطوری یه فایل MP4 به یه تگ video داده بشه، اگر داریم ویدئو رو به صورت استریم لایو یا تیکه های کوچیک شده دریافت می‌کنیم نیاز به روشی هم داریم که بتونیم ویدئو رو همینطوری به خورد تگ video بدیم. اینجا میتونیم از MediaSource API استفاده کنیم (در واقع یوتوب هم داره همینکارو انجام میده). به طور خلاصه از طریق این API میتونیم کنترل کامل روی روند پخش ویدئو داشته باشیم، bitrate رو کم و زیاد کنیم، دیتا رو از استریم دریافت کنیم، چانک ها رو خورد خورد اضافه کنیم (به جای اینکه کل فایل رو یکجا لود کنیم).پس تا اینجا هم‌صفحه شدیم که در ساده ترین شکل ممکن یوتوب ویدئو رو چطوری بهمون نشون میده و ساز کارش به چه شکلیه. البته به شکل خییییییلی ساده شده. (منم یافته های خودم رو گفتم، اگه شما بهتر میدونید حتما بگید)دور نماما که یوتوب نیستیم، ولی به اندازه کافی کنجکاو هستیم که بخوایم یه سیستم مشابه اش رو پیاده کنیم.کاری هم با استریم و پخش ویدئو نداریم. تمرکز ما تو این مطلب صرفا زمانی هست که کاربر Premium ویدئو رو دانلود میکنه (به طور کامل) و به صورت آفلاین بهش دسترسی داره. ولی همونطور که میدونید یوتوب برای دانلود فایل MP4 یا MOV یا و... رو در اختیار شما قرار نمیده و در عوض اون رو در یک فضایی (IndexedDB) ذخیره میکنه. این ذخیره سازی هم باید طوری انجام بشه که کسی مثل من نتونه این محتوا رو استخراج و توی یک فایل ذخیره کنه. پس محتوا باید به صورت Encrypt شده ذخیره بشه.این اتفاقیه که میوفته:یکم پیچیده به نظر میرسهاینجا کامل مشخصه که ویدئو به صورت Chunk های کوچکتر تقسیم شدن و توی یک دیتابیس که با IndexedDB ساخته شده ذخیره شدن. IndexedDB قابلیت ذخیره Blob و یا ArrayBuffer رو داره که میتونیم به کمک همین ها محتوا مون رو ذخیره کنیم. بیاید فعلا در نظر بگیریم محتوای ما به این شکل میتونه ذخیره بشه:بعدا برای پخش مجدد این ویدئو این ArrayBuffer یا Blob تجمیع میشه که به کمک MediaSource میتونیم اون رو به خورد پلیر بدیم که بتونه اون رو پخش کنه. دقت کنید که مثلا اینجا این chunkIndex مقدارش ۵ هست پس این پنجمین تیکه از n تیکه کل ویدئو هست.چرایی ها و ابزار هابذارید یکم برگردیم به عقب تر، اصلا چرا IndexedDB؟ چرا Blob یا ArrayBuffer یا MediaSource؟چرا IndexedDBاساسا روی وب چند فضا برای برای ذخیره سازی وجود داره (وقتی میگم وب هم منظورم سرور نیست و فقط ساید مرورگر رو میگم): Localstorage, indexedDB و چندتای دیگه.اگه روی هر کدوم از این فضا های ذخیره سازی یه مطالعه کوچیک بکنیم متوجه میشیم که localstorage فضای بیشتر از 5mb رو نمیتونه ذخیره کنه. Sessionstorage که همینه تازه بین تب ها هم دیتاش اشتراک نمیشه. کوکی هم که اصلا برای کار دیگریه. میمونه همین IndexedDB خودمون که میشه تنها انتخاب ما. قطعا این هم محدودیت هایی داره ولی انتخاب بهتری هم وجود نداره.چرا Blob و ArrayBufferدلیل استفاده از blob خیلی پیچیده نیست. کلا شما اگه بخواید با هر مدلی از فایل توی کد کار کنید باید اون رو به شکل یه آبجکت دریافت کنید. Blob همون آبجکت ماست.حالا چرا ArrayBuffer؟ اینجا دقیقا همونجایی هست که پیوند بین MediaSource و Blob شکل میگیره. درواقع به ArrayBuffer به شکل یه حامل میشه نگاه کرد که دیتا رو از blob تبدیل به ArrayBuffer میکنیم و اون رو به خورد MediaSource میدیم.چرا MediaSourceدر حالت عادی تگ video داخل HTML از ما برای src اش یه فایل ویدئویی میخواد. مثلا اگه بخوایم یه ویدئو خیلی معمولی نشون بدیم باید دقیق آدرس ویدئو رو وارد کنیم و اون شروع به پخش میکنه. با یک سری کنترل محدود مثل Play, Pause و Volume و همه چیز های دیفالتی که داره.ولی به کمک MediaSource همونطور که بالاتر هم گفتم میتونیم روی ذره ذره محتوای ورودی اون تگ video کنترل داشته باشیم. روش listener های مختلف داشته باشیم، ازش لاگ بگیریم و کلی چیز دیگه:همه اش رو یکجا بدیم، خورد خورد بدیم، بافر کنیم، از مموری بخونیم، از worker و indexdb لود کنیم، از یه سرور به صورت live stream بگیریم یا ... حتی به کمک همین MediaSource و ترکیبش با کلی تکنیک دیگه میتونیم پلیر های خیلی منعطف تری بنویسیم که کارای خیلی خفنی بتونن انجام بدن که البته خارج از حوصله من و این مطلبه.ارکستر (Orchestration) - همه چیز کنار هموقتشه همه این ها رو بذاریم کنار هم تا یه نتیجه گیری ای داشته باشیم. نمونه کامل اپلیکیشن اینجا قابل دسترس هست و میتونید ببینیدش. با vite استارت شده و روی vercel قرارش دادم.برای سادگی بیشتر، صرفا قرار هست یه ویدئو رو کاربر انتخاب کنه (حالا میتونه سورس های مختلفی داشته باشه) ولی اینجا برای سادگی میذاریم کاربر خودش آپلود کنه. در واقع آپلودی هم صورت نمی‌گیره، صرفا کاربر ویدئو رو انتخاب میکنه و ما اونو توی IndexedDB به صورت چانک های کوچک ذخیره میکنیم و بعد از همون چانک ها دوباره برای پخشش استفاده می‌کنیم.کار هایی که تو این پروژه انجام میشه رو بیاید مرحله به مرحله مرور کنیمآماده سازی کلی UI و فرم و ... (کلا اشاره ای نمیکنم، همینه که میبینید دیگه با tailwind)خورد کردن ویدئو به چانک های کوچکترذخیره دیتا (چانک ها) روی IndexedDBپخش یا Retrieve کردن چانک ها و فید کردنش به تگ ویدئو بعد اینکه کاربر روی play کلیک میکنهحذف ویدئو از روی IndexedDB (این اختیاریه)برای اینکه کارمونم راحت تر بشه یه دکمه بنفش داریم که یه تگ pre رو باز میکنه و توش اطلاعات IndexedDB تون رو نشون میده. بیشتر نقشش یه debugger هست. خودتونم میتونید برید تو قسمت Application از inspector تون و اونجا هم همون اطلاعات رو ببینید.قرار شد که قسمت UI رو بیخیال بشیم پس یه راست بریم سر وقت خورد کردن ویدئویه تابع داریم که فایل رو از input میگیره و فایل رو تبدیل میکنه به ArrayBuffer و اونو به چانک های ۱ مگابایتی میشکنه. مجدد تکرار کنم که این یه قرارداد هست مثلا من اینجا هر ویدئویی باشه رو اینطوری خورد کردم، ممکنه شما یه تصمیم دیگه بگیری https://gist.github.com/hesan-aminiloo/91fed56567af6b21d7d2d1672ac9d27f مهم ترین قسمتش همون حلقه while هست که داره چانک ها رو برامون میسازه.خب حالا که چانک ها رو داریم باید توی دیتابیس مون ذخیره اش کنیم. برای اینکار من ویدئو رو به دو بخش تقسیم میکنم:قسمت اطلاعات ویدئو یا همون metadataخود ویدئو که میشه همون چانک هامونپس در واقع چیزی که به ازای هر ویدئو قرار میگیره به این صورته. الان که چانک ها رو داریم میمونه که metadata رو بگیریم و بعد هم بریم سر وقت ذخیره کردنش https://gist.github.com/hesan-aminiloo/3242430bf6edf9b3af2781859bad75d2 همه این اطلاعات هم از روی فایل قابل دسترسه پس چیز سختی نیست.میرسیم به قسمت ذخیره سازیش روی IndexedDB. اینجا هم میتونید از یه چیز ORM طور استفاده کنید مثل idb یا مستقیم باهاش کار کنید. ما که نمیخوایم آپولو هوا کنیم من ازش استفاده نمیکنم.اول کار باید یه دیتابیس ایجاد کنیم و با همون instance بعدا بهش query بزنیم (دیتا ذخیره کنیم یا بخونیم یا پاک کنیم یا هرچی) https://gist.github.com/hesan-aminiloo/56368ce5514afb3d4d4526c0dc819a92 پس در واقع این تابع رو ما یکبار صدا میزنیم که اگر دیتابیس وجود نداشت اونو بسازه و اگر از قبل بود هم که از همون استفاده کنه. یه singleton پترن گوگولی.بعد نوبت ذخیره ویدئو و metadata هست. https://gist.github.com/hesan-aminiloo/90081a2905acba13a699ca3d734deb89  خبتویکد۲تاجارومشخصکردمکهکامنتدارهINJA1وINJA2(کلامنبااینکلمههمیشهدیباگمیکنم).تویقسمت۱کهمشخصهفقطدارهmetadataروذخیرهمیکنه.توضیحاضافهایندارهواقعا.یهآبجکتسادهاست.تنهانکتهطلاییشقسمتchunkCountهستکهجلوترباهاشکارداریم. توی قسمت ۲ ولی یکم داستان فرق داره. اینجا میایم در واقع به تعداد چانک های ویدئو که قبلا ایجادشون کردیم همون آبجکتی که بالا بالا ها نشون دادم رو ذخیره میکنیم. دیتا از قبل به صورت ArrayBuffer درومده و فقط باید ذخیره بشه. هر چانک هم index خودشو داره که بعدا برای نمایش ویدئو بهش نیاز داریم.در نهایت اگر همه چی خوب پیش بره دیتای ما توی IndexedDB ذخیره شده.اینجا دیگه میشه گفت ۹۰ درصد راه رو اومدیم. مونده گرفتن این دیتا و نمایش دادنش در قالب همون تگ video. بازم تاکید کنم که پلیر ما اینجا فقط یه تگ video سادست که دیتاش رو بهش فید میکنیم و امکانات خاصی نداره.توابعی که داریم اینا هستن: https://gist.github.com/hesan-aminiloo/7a53bcec03eb0e83f84a664283915d99 خب یکم حجم کد ها زیاد شده ولی همه شون همون چیزایی هستن که قبلا مرور کردیم. اول از همه تابع readVideoFromIndexedDB رو صدا میزنیم. این همون تابعی هست که گفتیم قراره ویدئو رو بگیره، همه چانک ها رو به ترتیب تجمیع کنه و به تگ ویدئو بده. اول metadata رو میخونیم که اطلاعات کلی ویدئو رو بگیریم. از پراپرتی chunkCount استفاده می‌کنیم که بدونیم کلا این ویدئو چند قسمت شده که توی loop ازش کمک بگیریم.بازم اینجا دو تا کامنت INJA داریم که توضیحشون مفصل تره.ببینید، ArrayBuffer یه ساختار داده باینری سطح پایین هست (حالا به نقل از MDN). یعنی اگه شما میخواید باهاش کار کنید باید یه بافر با یک طول ثابت ایجاد کنید. پس قابل تغییر نیست - پس بنابراین برای اینکه بتونید باهاش کار کنید اصطلاحا نیاز به یه view دارید. که میشه دقیقا همون Uint8Array که می‌بینید ایجاد شده. ما درواقع اینجا با یک واسطی (به مفهوم ساده البته) طرف هستیم که دیتا رو برای ما هندل میکنه.امیدوارم تونسته باشم اینو خوب توضیح بدم چون فهمش برای خودمم یکم مشکل بود.در نهایت ما فایلمون رو داریم. مونده فقط نحوه استفاده ازش: https://gist.github.com/hesan-aminiloo/b2d1a429333b703fca1ccd3b2812a816  یادتونهگفتمفایلهابایدblobباشن؟اینجاهمونجاییهکههمهچیکنارهمقرارمی‌گیره.ازاونبافرکهایجادکردیمیهblobمیسازیم-ازشیهurlمی‌گیریموبعدهممقدارurlرومیذاریمتویvideo. حالا اگه همه چیز کنار هم درست کار کنه ما یه سیستمی داریم که میتونیم فایل ها رو روی indexedDB ذخیره کنیم و ازش دوباره استفاده کنیم.جمع بندیاین مطلب خیلی زمان برد نوشتن و آماده سازیش، قطعا خوندنش هم برای شما طول کشیده (اگه خونده باشید کلش رو). اگه با دقت دنبال کرده باشید کلی چیز این وسط هست که من اصلا نشون ندادم یا اصلا بحثی راجع بهشون نکردم. مثلا اون موضوع Encryption رو یه اشاره کوچیکی کردم ولی تو مدل پیاده سازی شده اصلا اونو نداریم.یا مثلا این پروژه خیلی جا برای بهبود داره که میشه روش زمان گذاشت ولی برای من قسمت جذاب و فان اش همینی بود که اینجا گفتم. اما ایده هام رو لیست میکنم شاید شما دوست داشتین روش کار کنید:تو پیاده سازی الان Thumbnail هندل نمیشهتوی مدلی که یوتوب این قسمت رو پیاده سازی کرده حتی صدا و تصویر رو جداگانه ذخیره میکنهتوی این پروژه عملا ما داریم کل محتوا رو دوباره یکجا به هم میچسبونیم پس اون قابلیت بافر کردن یا preload کردن ویدئو رو نداریم. پیاده سازی اون میتونه خودش یه چالش دیگه برای جای دیگه ای باشهاینجا هر فایلی که خودتون آپلود کنید رو ذخیره میکنه، میشه کاری کرد که با URL های دیگه هم کار کنه (شاید)زشته (خوشگل کردنش)کلام آخرکلا خوبه کنجکاو باشیم، اخیرا بیشتر دارم سرک می‌کشم اینور و اونور ببینم هرچیزی دقیقا چه اتقافی داره براش میوفته یکم از زیر و بم چیزا سر در بیارم. راجع به این موضوع و این مطلب که روبه‌روی شماست شاید ۳ سال هست که ایده نوشتنش رو داشتم ولی همیشه به تعویق مینداختم. موضوعی بود که همیشه برام جالب بود. چیزی نداره واقعا وقتی از نزدیک باهاش کار میکنی ولی انقدر پتانسیل داره که یوتوب اونو تو سرویس پولی خودش به کاربرا داره میده 😁امیدوارم درکل مطلب براتون مفید بوده باشه و از خوندنش یه چیز جدید یاد گرفته باشین. دوست داشتین میتونید از طریق لینکدین باهام در ارتباط باشین.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Tue, 13 May 2025 16:32:53 +0330</pubDate>
            </item>
                    <item>
                <title>بازی Light Memory و چالش پیاده سازیش</title>
                <link>https://virgool.io/@hesanam/%D8%A8%D8%A7%D8%B2%DB%8C-light-memory-%D9%88-%DA%86%D8%A7%D9%84%D8%B4-%D9%BE%DB%8C%D8%A7%D8%AF%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%A7%D9%88%D9%86-k3jd21ataak2</link>
                <description>بعضی وقتا یه بازی به نظر ساده، میتونه شما رو به شکل خیلی جدی به چالش بکشه. چند روز پیش یه مطلب خوندم راجع به یه مصاحبه که یه چالش بامزه داشت. بازی Light Memory. بازی ای که توی اون چندتا چراغ وجود داره و شما باید ترتیب روشن شدن چراغ ها یادتون بمونه و بعد همون ترتیب رو وارد کنید که برید مرحله بعد و هر مرحله بازی سخت تر میشه. حالا این سخت تر شدن میتونه روشن شدن چراغ های بیشتر، سرعت روشن شدن چراغ ها یا جابجا شدن اون ها باشه.درک مسالهبیاید در نظر بگیریم که ما هم توی جلسه مصاحبه هستیم و همچین مساله ای برامون پیش اومده. بنابراین ما دنبال این نیستیم که فقط به جواب برسیم، اینکه چطور مساله رو تحلیل کنیم از به جواب رسیدنش مهم تره.من برای خودم مساله رو اینطور تحلیل کردم:چندتا (۵ تا) چراغ وجود دارهچراغ ها به یه ترتیب رندوم باید روشن و خاموش بشنکاربر باید همون ترتیب رو وارد کنهاگر کاربر ترتیب درست رو وارد کنه امتیاز می‌گیرهاگر ترتیب اشتباه وارد بشه - بازی ریست میشه.چی برامون دارهوقتی یه نگاه کلی بهش میندازیم، به نظر ساده میاد ولی بعد اینکه پیاده سازی رو شروع می‌کنیم موضوع جالب میشه. بریم ببینیم چه چیزایی توی این چالش وجود داره که باید بلد باشیم.تولید یه سری از اعداد رندوم که به ترتیب چراغ ها رو روشن و خاموش کنن (Math.Random و Stack)بین روشن و خاموش شدن چراغ ها باید یه تاخیر کوچیک وجود داشته باشه (Async و Promise)ورودی های کاربر و ترتیب چراغ ها رو باید به ترتیب نگهداری کنیم (State management)این State ها باید بین کامپوننت های مختلف حرکت کنن (بازم State management)درجه سختی بازی باید افزایشی باشه (یه جورایی Business logic)حالت روشن و خاموش شدن چراغ ها (CSS Animation)پس در واقع با یه نگاه عمیق تر به مساله برامون روشن میشه که این بازی همچین ساده هم نیست. من بازی رو یه بار پیاده سازی کردم و تجربه خیلی جالبی برام داشت.سرعت ویدیو توی تبدیلش به gif یکم بهم ریختههمه چیز این بازی پیاده سازی نشده. مثلا مکانیزم disable کردن دکمه ها در زمانی که بازی داره اجرا میشه، یا game over شدن، انیمیشن های بهتر، صدا دادن لامپ ها و کلی چیز دیگه...البته منم کد های کامل این پروژه رو اینجا نشون نمیدم، صرفا میخوایم باهم یه راه حل رو مرور کنیم، پیاده سازی اصل قضیه رو به خودتون میسپرم و میتونید به عنوان یه چالش بامزه آخر هفته ای روش وقت بذارید.به طور کلی اسکلت اصلی بازی رو من اینطور پیاده سازی کردم: https://gist.github.com/hesan-aminiloo/4baf888c06120e1ebc22f8347055d240 کامپوننت های اصلیسه تا کامپوننت اصلی رو من به این شکل پیاده سازی کردم:یه کامپوننت Score که خیلی خیلی خیلی ساده فقط یه عدد رو نشون میده.کامپوننت اصلی Lights که یه طورایی اتفاقای اصلی ما اینجا میوفته.کامپوننت Controls که دکمه های Start و Reset توش هست که اولین بار بازی رو استارت میزنهبرای استایل ها هم که واضحه از tailwind استفاده شده و پروژه هم کلا با vite استارت شده و TS هم هست. اینا دیگه بدیهیات هست دیگه ...توی Lights یه حلقه است که ۵ تا چراغ رو رندر میکنه. یه Click handler هم داره برای وقتی که کاربر روی لامپ ها کلیک میکنه. اون 5 تا چراغ هم یه لیست ثابت هستن که ۵ تا رنگ دارن و یه id که بیان‌گر اون رنگ خاصه. این بهمون بعدا کمک میکنه که هم ترتیب روشن شدنشون رو بدونیم هم کلیک های کاربر رو بگیریم.وقتی ساده میشه حلش کرد پیچیدش نکردماز روی کد میشه سه تا کامپوننت اصلی پروژه رو دید، برای سادگی من کل State ها رو توی useGame نگهداری میکنم و توی App ازشون استفاده کردم.اولین راند بازی فقط یه چراغ روشن میشه، بعد دو تا بعد سه تا و همینطوری الی آخر... برای همین یه متغیر Level تعریف کردم که اول کار مقدارش 1 هست. هر مرحله که کاربر بازی رو درست انجام میده یه دونه بهش اضافه میشه.بر اساس همین Level یه سری از اعداد رندوم بین 0 تا 4 ایجاد میشه که در واقع اشاره میکنه به یکی از چراغ ها. پس بنابراین زمانی که بازی استارت میشه یه آرایه رندوم به طول Level ایجاد میشه و بعد لامپ ها به اون ترتیب روشن میشن.برای روشن شدن هر کدوم لامپ ها کافیه یه دونه کلاس CSS بهش اضافه و کم کنیم. بعد یه delay بذاریم و بریم سراغ رنگ بعدی. (استفاده از promise اینجا اتفاق میوفته)بعد هم که کاربر روی لامپ ها کلیک میکنه، ترتیب کلیک ها رو نگه میداریم و مقایسه میکنیم و اگه درست بود یه دونه به Level اضافه می‌کنیم و یه دونه هم به Score. حالا این Score میتونه ۱۰ تایی اضافه بشه، میتونه یه دونه ای اضافه بشه، میتونه اصلا بر اساس level به صورت تساعدی زیاد بشه... این دیگه میشه business logic.ایده ها برای آیندهمیشه با روشن شدن چراغ ها یه صدایی هم در بیادمیشه بعد از یه مرحله ای به بعد چیدمان رنگ ها جابجا بشنمیشه مکانیزم های کمکی استفاده کرد مثلا گرفتن راهنمایی یا power upمیشه بعد از هر مرحله سرعت روشن/خاموش شدن چراغ ها رو کم و زیاد کردهدفمون چیهبعضی وقتا برای یاد گرفتن مفاهیم پایه ای میشه راه حل های خلاقانه تری هم داد. مثلا چرا ما همیشه برای یاد گرفتن Promise و Async/Await میخوایم یه request بزنیم و یه لیستی نشون بدیم؟ خیلی وقتا مسائل بامزه تری هستن که میتونیم ازشون برای یاد گرفتن مفاهیم پایه ای استفاده کنیم. کلا من خیلی طرفدار دیدن چیز ها از زاویه های جدید هستم.شمام سعی کنید همین بازی یا یه بازی دیگه رو پیاده سازی کنید، مطمئنم بهتون خوش میگذره.امیدوارم مطلب براتون جالب بوده باشه، دوست داشتید میتونید از طریق لینکدین باهام در ارتباط باشین.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Sat, 10 May 2025 13:57:43 +0330</pubDate>
            </item>
                    <item>
                <title>مطلب زرد = سوالات پر تکرار مصاحبه Frontend</title>
                <link>https://virgool.io/@hesanam/%D9%85%D8%B7%D9%84%D8%A8-%D8%B2%D8%B1%D8%AF-%D8%B3%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D9%BE%D8%B1-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1-%D9%85%D8%B5%D8%A7%D8%AD%D8%A8%D9%87-frontend-sslxxlyocpgg</link>
                <description>خیلییییی زیاد می‌بینم که همه دارن محتوای مرتبط با سوالات مصاحبه ای تولید میکنن. از این مدلا که تو مصاحبه های فرانت مثلا در مورد ری-اکت می‌پرسن که virtual dom چیه؟ یا مثلا symbol چجوری کار میکنه یا مثلا ref چجوری کار میکنه...کلا این مدل چیزا.به نظر من همه اینا چیزی جز محتوای زرد نیست! دیگه واقعا اینکه دیگه کنکور نیست که فقط تست بزنیم که فقط بریم دانشگاه و برای بعدش هیچ برنامه ای (جز مهاجرت) نداشته باشیم.مصاحبه کننده ها عموما دنبال این هستن که شما چه تجربه ی عملی یا عینی (تو دنیای واقعی) با اون مطلب دارید، صرف توضیح یه مفهوم که به درد نمیخوره، وگرنه همه میتونن با ChatGPT خودشونو خیلی خوب آماده کنن برای مصاحبه.حتی اگه صرفا راجع به مفاهیم پایه ای باشه مثل همین Virtual DOM در نهایت مصاحبه کننده دنبال این شاید  هست که چقدر با این موضوع آشنایید که بتونید یه بهبودی تو پرفورمنس اپلیکیشن ایجاد کنید.یا حتی برای سوالات ساده تر (مثلا همون سوال همیشگی فرق var, let, const) اگر شما پاسخی بدید که نشون بده چقدر عمق مطلب رو درک کردید، نشون میده که احتمالا توی انجام کار ها کمتر به مشکلاتی میخورید که دلیل شون عدم دانش عمیق کافی توی اون زمینه باشه. به نظرم توی این جور مطالب (🟡) تمرکز روی این هست که شما بیشتر بتونید جواب نهایی رو بدید، در صورتی که  اینکه چطور به اون جواب نهایی رسیدید خیلی مهم تره. دست کم تاثیر خیلی بیشتری روی فرد مصاحبه کننده میذاره.فرض کنیم که از پس همه سوالات بر بیایید ولی اگه دانش تجربی کافی براشون نداشته باشین در آخر حتی وقتی کار رو بگیرید، نمیتونید اونطور که باید و شاید کارارو انجام بدید.پیشنهاد من چیه؟راجع به هر موضوعی ازتون سوال شد اگر تجربه مشابهی دارید یا use case ای برای اون موضوع سراغ دارید حتما اشاره کنید بهش، مثلا اگه ازتون پرسیدن توی hook های ری-اکت چجوری unmount اتفاق میوفته، علاوه بر جواب ساده ای که میگه توی return ای که برای useEffect مینویسیم، میتونید بگید مثلا برای ریست کردن تایمر ها معمولا استفاده میشه. خیلی سادهاگر تجربه مشابه دارید حتما به اون اشاره کنید. مثلا فلان جا ما فلان چالش رو داشتیم و به کمک این موضوع تونستیم حلش کنیم که توش از این موضوع استفاده کردیم. بازم خیلی سادهاز خودتون چیزی در نیارید برای اینکه فقط به سوال جواب داده باشید. منظورم اینه که خالی نبندید😁! صادق باشید. اگر نمیدونید بگید نمیدونم! اگه میدونید چیه ولی تاحالا استفاده نکردید بگید میدونم اینطوریه و این شکلی کار میکنه ولی تاحالا استفاده نکردم یا توی پروژه ای بهش بر نخوردم.اصلا خیلی وقت ها جواب &quot;نمیدونم&quot; خیلی قشنگ تره به نظرم نسبت به اینکه یه چیزی از خودتون در بیارید یا زور الکی بزنید برای اینکه ثابت کنید یه چیزی رو بلدید در صورتی که بلد نیستید یا حداقل تسلط خوبی ندارید.به نظرم کلا این موضوع آماده شدن برای مصاحبه فنی، حداقل برای اینجور مسائل بی فایده است، منظورم حفظ کردن یه سری سوال و جواب، یا دیدن یه سری نمونه کد و یاد گرفتن خروجی شون بدون فهم دقیق از دلیلش یا حتی حل کردن یه سری مسائلی که بار ها و بار ها حل شده.اگر یکی به من بگه من کلی سوالات مصاحبه ری-اکت رو دیدم و مرور کردم من بهش میگم وقتت رو تلف کردی! اشتباه برداشت نکنید، اگه اینکار به منظور یادگیری باشه، یعنی صرفا من به عنوان یه تازه کار فقط میخوام ببینم اصلا چه چیزای مختلفی هست که باید یاد بگیرم که حتی اصلا از وجودشون خبر ندارم یا هنوز بلد نیستم، به نظرم کار اشتباهی نیست، ولی اگه برای آماده شدن برای مصاحبه رفتن باشه (اونم مثلا یه هفته قبل مصاحبه) به نظرم خیلی کار اشتباهیه.البته به طور کل آماده شدن برای مصاحبه همیشه هم بد نیست، مثلا مصاحبه شرکت هایی مثل گوگل و آمازون و ... رو اگه دیده باشید معمولا به شما یه مساله میدن که حل کنید. توی اون حالت آمادگی قبل از مصاحبه به این شکل انجام بشه میتونه مفید باشه:مهارت حل مساله تون رو تقویت کنید. نه اینکه بخواید از صفر بسازیدش ها... تقویتش کنید. یاد بگیرید که مسائل رو چطور میشه به تیکه های کوچیکتر شکست. (البته باید اینکار رو از قبل هم بلد باشید)بلند بلند فکر کنید، رسیدن به جواب درست همه ی مساله نیست. اینکه چطور بهش رسیدید خیلی مهم تره. یعنی بیشتر تمرکزتون روی فرایند حل مسائل باشه به جای اینکه روی نتیجه نهاییش باشه.در کل میخوام بگم توی جلسات مصاحبه خیلی خودتون باشید. همونطوری که روزمره کار هاتون رو انجام میدین. حتی اگه دفعات اولیه کی مصاحبه می‌رید و نیاز به یه رفرنس دارید برای سوالات، اشکالی نداره که این مطالب رو بخونید یکم حساب کار دستتون بیاد یا آشنا بشید ولی حتی در این حالت هم ارجاع بدید به پروژه هایی که تا اون موقع انجام دادین. از چالش هاتون برای طرف مقابل بگید به جای اینکه خیلی سریع و مستقیم به جواب سوال اشاره کنین.نکته مهم: اینا همه اش در صورتی هست که فرد مصاحبه کننده هم انسان درست و حرفه ای باشه و دنبال زیر بغل مار نباشه! دیدم که میگم! در اون صورت که دیدید طرف مقابل هم یه سری سوال مسخره و همیشگی داره می‌پرسه و جواب های شما رو دنبال نمیکنه،‌ یعنی از شما توضیح بیشتر نمیخواد و سریع میره سراغ سوال بعدی، یعنی احتمالا اونم از همون رفرنس های 🟡 داره استفاده می کنه. این مطلب قرار نبود انقد طولانی بشه، صرفا خیلی زیاد اخیرا به چشمم میومد اینجور مطالب و چند نفر هم ازم پرسیده بودن که کار درستی هست یا نه، اول اینکه من که نمیتونم نفر به نفر بگم کار درستی هست یا نه! دوم اینکه نظر من اینه که اینجا نوشتم، حالا شما بذار تو فرمول خودتو در میاد دیگه 😁خلاصه که دوس داشتید تو لینکدین میتونین باهام در تماس باشین.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Wed, 11 Sep 2024 01:09:31 +0330</pubDate>
            </item>
                    <item>
                <title>از تهران تا هامبورگ!</title>
                <link>https://virgool.io/@hesanam/%D8%A7%D8%B2-%D8%AA%D9%87%D8%B1%D8%A7%D9%86-%D8%AA%D8%A7-%D9%87%D8%A7%D9%85%D8%A8%D9%88%D8%B1%DA%AF-yl63gpgrl9lw</link>
                <description>یک ماه از اومدن من گذشت. تو این یک ماه خیلی چیز ها تجربه کردم و دیدم و یاد گرفتم که دوست داشتم راجع بهشون بنویسم. قبلا راجع به رزومه و ... نوشته بودم اما از تجربه ای که خودم داشتم صحبت نکردم. تا جایی که مسائل شخصی دخیل نباشن سعی میکنم اینجا توضیح بدم.البته این وسط کلی هم پیام گرفتم که ازم سوالای مختلف می‌کردن راجع به مهاجرت و شرکت جدید و ریفر و ... که بعدا تو یه مطلب جدا شاید در موردش توضیح دادم.داستان مهاجرت منتصور کن، من نشسته بودم مشغول پلی استیشن بازی کردن بودم گفتم گوشیمو چک کنم و دیدم که یه پستی اومده و یه کاری و توضیحات و خلاصه گفتم شانسمو امتحان کنم و خلاصه اوکی شد!بعد از کلی مصاحبه و صحبت و تسک و ... خلاصه کاره اوکی شد و فرایند مهاجرت شروع شد. من جزییات مصاحبه رو لزومی نمیبینم بگم. صرفا میتونم بگم توی تجربه من توی چند مرحله مختلف انجام شد و البته انصافا دوستم آروین هم خیلی خیلی تو این موضوع بهم کمک کرد.من فرایند مصاحبه ام بهمن ماه ۱۴۰۲ شروع شد و فروردین ۱۴۰۳ بالاخره آفر رو گرفتم. شرکت همه هزینه های مربوط به ریلوکیت رو داد از جمله پول بلیت هواپیما و سفارت و حتی اقامت موقت من زمانی که رسیدم هامبورگ.البته به این سادگیا هم نبود اصلا، چون دقیقا زمانی آفر رو گرفتم که پدر همسرم سه روز بود از دنیا رفته بود و اصلا حال و وضع خوبی نداشتیم. البته سخت تر هم شد چون با توجه به اینکه من سربازی نرفتم و باید برای خروج از کشور یه راهی پیدا میشد و باز هم از همه اینا سخت تر این بود که به خاطر شرایطی که پیش اومده بود مجبور شدم اول خودم بیام و بعد همسرم بهم ملحق بشه که این فرایند خیییلی طولانی هست و الان که اینو مینویسم هنوز نمیدونم کی میتونه بیاد پیش من.بعد از کلی استرس و انجام کار های ویزا و خروج از کشور و ... نهایتا من ۱۵ تیر ماه پرواز کردم به ترکیه و بعد ۵ روز از اونجا اومدم آلمان. واقعا هرکی میگه آسمون همه جا یه رنگه ...... میگه. اینجا هم الفی هست، توی هافن سیتی، جای خیلی باحالیه.واقعا میتونم بگم من خیلی خوش شانس بودم که شهر خیلی خوبی اومدم! از هرکی میپرسم که هامبورگ چطور شهریه، همه هم نظر میگن شاید قشنگ ترین شهر آلمان همینجاس! حتی خود آلمانی ها! خیلی ها اینجا انگلیسی رو راحت صحبت میکنن و تاحالا حتی برای کار های دولتی نشده که نیاز پیدا کنم به زبان آلمانی. البته برنامه یاد گرفتنش رو دارم قطعا. گذشته از اون واقعا از شرکتی که توش اومد خیلی راضی هستم. به شدت همه چیز سر جاشه. از همه کشور ها تقریبا افرادی هستن که اینجا کار میکنن. مواجه شدن با فرهنگ ها و زبان ها و آداب مختلف توی شرکت برام یکی از جذاب ترین نکات بوده و هست.روز اول کاریم خیلی عالی پیش رفت و همه آدما به شدت مهربون بودن و همه سعی داشتن کمک کنن. سیستمم رو بهم دادن و البته از قبل آروین میزم رو رزرو کرده بود. برای همه چیز از گوگل استفاده می‌کنیم. ایمیل مون همون gmail هست ولی سازمانی، برای چت گوگل چت داریم و برای همه میتینگ ها هم گوگل میت و گوگل کلندر. با ایمیل شرکت عملا هر کاری میشه کرد دیگه! البته این موضوع برای من جذاب بود ولی شاید برای خیلی ها عادی باشه. بهرحال ما از کشوری میایم که برای ساده ترین کار ها هم باید کلی اذیت بشیم.اینجا آشپزخونه طبقه همکف هست!‌ اولین دقایقی که وارد شرکت شدم.برای ستاپ سیستم هر نیازی که داشته باشیم خیلی راحت و سریع یه ایمیل به همراه لینک چیزی که میخوایم میفرستیم و فردای اون روز یا ماکزیمم با فاصله ۱-۲ روز بهمون میدن چیزی که میخوایم رو. مجدد نمیخوام مقایسه کنم با ایران که احتمالا همه میدونیم چقدر فرایند سختیه.گذشته از اینها هر هفته دوشنبه ها یه گردهمایی داره شرکت که همه تیم ها دور هم جمع میشن و آپدیت میدن راجع به اهداف و برنامه ها و جشن و معرفی اعضای جدید اگر داشته باشیم! روز اول کاری من هم دوشنبه بود و توی این جلسه اسم من رو هم گفتن و همه هم دست زدن و کلی تبریک گفتن! خیلی حس خوبی رو منتقل میکنه واقعا. احساس میکنی که اینجا به تو واقعا اهمیت میدن. اینکه حالت خوب باشه براشون خیلی مهمه. ماهی یک روز هم ناهار دسته جمعی داریم و البته روزی که من رسیدم جشن سالانه تابستون هم بود که من البته نرسیدم بهش ولی اونجا هم ظاهرا خیلی خوش میگذره.میزامون هم قابلیت تنظیم ارتفاع داره. ایران که بودم خیلی دنبالشون گشتم ولی نبود. خیلی خوبن اینا. اگه تونستید حتما تهیه کنید.واقعا من گله ای از فضای کار نمیتونم بکنم. همه چیز خیلی منظم، تمیز و مرتب با تمام امکانات. انواع نوشیدنی soft و غیر soft 😁 و کلی اسنک و میز پینگ پنگ و بازی و ... چیزی که شاید برای ما ایرانی ها خیلی عجیب و جذاب باشه. قطعا برای همین هم برای من خیلی جذاب بوده و هست.شرکت باشگاه داره و ۲۴ ساعت هر روز هفته میشه به شرکت رفت و آمد کرد. خیلی پیش اومده که بیرون بودم و وسط راه هوس کردم یه چیزی بخورم یا یه سرویس تمیز بخوام برم (واقعا هنوز نتونستم سرویس بهداشتی عمومی برم انقد که بدم میاد) سر زدم به شرکت حتی نصف شب.از نظر کاری هم بیزنس رو به رشد هست و هر هفته داره بهتر میشه، این شفافیتی که بین تیم بیزنس و تک و پروداکت و همه و همه وجود داره خیلی جذابه! همه ما دقیق میتونیم ببینیم که شرکت به کدوم سمت داره میره.به شدت فضای شفافی هست، توی جلسات ۱:۱ هفتگی که با مدیرم دارم خیلی رک و پوست کنده فیدبک میگیرم و واقعا این خیلی کمک میکنه که هم احساس آرامش بیشتری داشته باشی هم دقیق میدونی چه مسیری باید بری که بتونی ترفیع بگیری یا بتونی رشد کنی.خود پروژه ای که من روش کار میکنم هم پروژه خوبیه، هنوز دارم آنبورد میشم و خیلی چیزا هست که یاد بگیرم راجع بهش اما به طور کلی میتونم بگم دوسش دارم و واقعا فضا هم برای یادگیری فراهمه هم چالش. بک لاگ مون هم تا ۱-۲ ماه آینده کاملا پر هست و مشخصه کجا میخوایم بریم. حتی من وقتی اومدم مدیرم رفت تعطیلات و ۳ هفته نبود ولی هیچ اختلالی توی کار ها ایجاد نشد.واقعا راجع شرکت خیلی میشه صحبت کرد ولی خب خبر خوب اینه که شرکت ما به شدت در حال رشد هست و همچنان درحال جذب نیرو. پس اگه خودتون دوست داشتین یا کسی رو میشناختین که به نظرتون خوب میومد حتما برای پوزیشن ها اپلای کنید! اگر من بتونم ریفر هم میکنم و تو این موضوع کمکی از دستم بر بیاد حتما انجام میدم براتون.و اما هامبورگ!اینجا Hamburg Townhall هست، هر آخر هفته که بری کلی آدم میان برنامه اجرا میکنن و خیلی وایب و فضای مثبت و قشنگی دارهمن تازه ۱ ماه هست که اینجا زندگی میکنم و قطعا مشاهداتم محدوده بنابراین نمیشه اون ها رو تعمیم داد به همه چیز. ولی شهر، اینجا واقعا قشنگه!شرکت ما رو به روی یه دریاچه هست به اسم Alster که روز های آفتابی میبینی روش کلی آدم دارن قایق سواری میکنن. خیلی ها هم دارن پدل میکنن و کلا خلاصه من خیلی دیدم که از هر فرصتی برای تفریح استفاده می‌کنن.شهر جاذبه های گردشگری خیلی خیلی باحالی داره. پیشنهاد میکنم اگه میخواید با هامبورگ آشنا بشید حتما این ویدئو رو ببینید https://www.youtube.com/watch?v=_a-tISPzHeo من انقدر خوش شانس بودم واقعا که تونستم خیلی از جاهای تاریخی این شهر رو برم و از نزدیک ببینم!سیستم حمل و نقل عمومی واقعا عالی و درجه یک هست! اتوبوس، قطار، مترو و حتی دوچرخه و اسکوتر عمومی. همه چیز سر جاشه.توی اتوبوس و قطار هم اینترنت رایگان هست که سرعتش هم بد نیست، حدودا ۱-۲ مگ هست که برای کارای ضروری جواب میده. البته من خیلی اوقات پیاده میرم و میام. فعلا نیازی به خرید ماشین و ... پیدا نکردم و البته اگر بخوام هم نمیتونم فعلا به خاطر هزینه هاش و البته گواهی نامه که فعلا ندارم 😊 دوچرخه ها اینجا کلا حکم نیسان آبی های ایران رو دارن واقعا، تو مسیر های مخصوص دوچرخه اگر بری واقعا اگر حواست نباشه میان میزنن لهت میکنن.جدا از اینها مردم اینجا خیلی خوب انگلیسی میتونن صحبت کنن، چیزایی که قبلا راجع به نژاد پرستی و ... شنیده بودم واقعا ندیدم (البته شایدم به خاطر اینه که من فقط یک ماهه اینجام)، پر از کافه و رستوران و جاهای خوب و قشنگ. هزینه ها نه خیلی زیاد بوده و نه خیلی کم. البته ماه های اول به خاطر اینکه مجبور هستم خیلی چیز ها رو برای بار اول تهیه کنم هزینه ها بالاتره اما جدا از اون خیلی هزینه ها بالا نیست.یه نکته خیلی خیلی جالب توجه برای من اینجا اهمیت دادن به موضوع Accesiibility بود. انقدر این موضوع براشون مهمه که تو عملا جایی نمیبینی که براش چیزی تعبیه نکرده باشن. حتی پشت چراغ قرمز ها که می ایستی یه دستگاهی با یه صدای هی تق تق میکنه تا زمانی که چراغ سبز بشه و صداش یه بوق متفاوتی میشه. اتوبوس ها همه رمپ دارن، مترو و قطار همه آسانسور و ... اینجا من خیلی افراد معلول میبینم که راحت دارن تو اجتماع زندگی میکنن.البته این موارد که گفتم مختص به هامبورگ نیست ولی برای من خیلی جالب توجه بود.حرف برای گفتن زیاده، دوست داشتم یه مطلب بنویسم تا اینا رو یه جایی حتی برای خودمم که شده داکیومنت کنم چون مطمئنم خاطره میشن همش. همینطور که احتمالا میدونید، اگه دوست داشتید از طریق لینکدین میتونین باهام در تماس باشید!</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Sun, 18 Aug 2024 20:41:25 +0330</pubDate>
            </item>
                    <item>
                <title>رزومه مون رو بهتر بنویسیم</title>
                <link>https://virgool.io/@hesanam/%D8%B1%D8%B2%D9%88%D9%85%D9%87-%D9%85%D9%88%D9%86-%D8%B1%D9%88-%D8%A8%D9%87%D8%AA%D8%B1-%D8%A8%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%85-xcvp8uwj0frn</link>
                <description>سعی میکنم مطلب کوتاه و جمع و جور باشه که راحت بشه خوندش و استفاده کرد.من هیچوقت راجع به نحوه رزومه نوشتن نظر نمیدادم، اینو بچه هایی که با من منتورشیپ داشتن میدونن. ولی احتمالا بدونید که اخیرا من مهاجرت کردم آلمان به کمک یه جاب آفر و دلیل عدم فعالیت اخیرم هم این موضوع بود و توی این مدت چیزایی یاد گرفتم که میتونه مفید باشه براتون.تکرار میکنم که من تخصصم رزومه نوشتن و کارای مرتبط باهاش نیست و صرفا میخوام تجربه های خودمو بگم و چیزایی رو بهش اشاره کنم که خودم فهمیدم.توی این زمینه دوستان عزیزم نیما و آروین خیلی کمک بزرگی به من کردن و همینجا ازشون قدردانی میکنم.عکس خاصی نداشتم واسه پست بذارم - عکس زیبای خودم رو براتون گذاشتم صفا کنیدچیز هایی که باعث بایاس میشه نذاریدکلا از هر چیزی که باعث بشه ذهن خواننده رزومه بایاس بشه پرهیز کنید.بایاس یعنی به ذهن مخاطب یه جهت دهی اولیه کنید، مثلا اول به طرف بگی هوا چقدر سرده، بعد ازش بپرسی توام سردته؟ حالا اگه هوا خیلی هم سرد نباشه ممکنه طرف به خاطر جهت دهی اولیه ای که شما به ذهنش دادید بگه آره منم سردمهچه چیز هایی ممکنه باعث بایاس بشه؟عکس خودتون (مخصوصا خانم ها)تاریخ تولدتونازدواج کردید یا نهسربازی و چیزای مربوط بهشبذارید توجه خواننده فقط به محتوا باشه.بایو یا Descriptionتوضیحات راجع به خودتون رو تا جای ممکن خلاصه بنویسید و سعی کنید این توضیحات خیلی خوب شما رو توصیف کنه. مثلا قصه ننویسید که من فلان موقع شروع کردم و فلان شد و بعد وارد شدم و بعد اینطوری شد و ... خیلی کوتاه. بهتون قول میدم اگه متن طولانی باشه اصلا طرف نه وقتش رو داره که بخونه و نه اهمیتی میده.خیلی خلاصه فقط اشاره کنید که چه چیز هایی به بهترین شکل کاراکتر شمارو توصیف میکنه. میتونید اینجا بنویسید که کلا چند سال تجربه دارید و دوستاتون شما رو به چه چیزی میشناسن.اطلاعات تماسزیر اسمتون بالای رزومه همه اطلاعات تماس و شبکه های اجتماعی مهم تون رو قرار بدید. قطعا اگه اینستاگرام تون مرتبط با کارتون نیست دلیلی نداره بهش توی رزومه اشاره کنید ولی مثلا اگه توی stackoverflow فعال هستید و امتیاز خوبی دارید لینکش رو بذارید. ایده رو گرفتید دیگه؟ دیگه مثال نزنم. شماره تلفن و ایمیل و لینکدین مهم ترین هاش هستند که حتما حتما باید باشن.صادق باشیداگر برای پوزیشن سنیور دارید اپلای می‌کنید، مطمئن بشید که واقعا سنیور هستید. بسته به شرکت و کشوری که دارید اپلای می‌کنید تعریف سنیور میتونه متفاوت باشه. مثلا توی اروپا تجربه بالای ۶ سال رو میگن سنیور ولی مثلا تو ایران با ۲ سال هم شما میتونی سنیور باشی 😂 کلا ادعای چیزی رو نکنید که نیستید.حتی روی مدارک تحصیلی تون. مثلا اگه دانشجوی ارشد هستید ننویسید که ارشد دارید، یا کلا ننویسید یا بنویسید که در حال تحصیل هستید.تجربیات تون رو اول بیاریدمهم ترین چیزی که خواننده رزومه شما (این که میگم خواننده یعنی ممکنه منابع انسانی باشه یا یه فرد تکنیکال) دنبالش هست اینه که شما قبلا چه کار هایی کردید و کجا ها بودید. اینکه چندتا certificate و مدرک و دوره و کلاس گذروندید واقعا نسبت به اون تجربه کار هیچ اهمیتی نداره.سعی کنید تجربیاتی که توی رزومه تون بهش اشاره کردید هماهنگ باشه با چیزی که توی لینکدین دارید. توی لینکدین حتما حتما حتما عکس پروفایل داشته باشید.توضیحات خوب (مهم)اول راجع به اون شرکت در حد یه خط توضیح بدید که اصلا شرکت چی بوده. بازم تکرار میکنم که توضیحات طولانی اصلا ندید چون خونده نمیشه واقعا.صرفا تسک ها و خواسته هایی که ازتون شده و وظیفه داشتید اونا رو انجام بدید رو ننویسید. فقط کار هایی رو بنویسید که منجر به خلق یه ارزشی شدن. ننویسید مثلا سیستم لاگین نوشتم. اشاره کنید به کار هایی که باعث بهبود ها شده. مثلا میتونید بنویسید که مشکل پرفورمنس فلان جا رو پیدا کردم و حلش کردم و در نتیجه باعث رشد n درصدی رضایت کاربرا شد.میتونید از این فرمول استفاده کنید:چه مشکلی وجود داشت، چطوری حلش کردید، نتیجش چی شد.سعی کنید این موارد رو توی همه نکته ها رعایت کنیدبرای هر پوزیشنی که قبلا داشتید بیشتر از ۳-۴ مورد ننویسید. متن تون کوتاه و مفید باید باشه. وگرنه کسی حوصله نداره بخونه.تکنولوژی هامیتونید یه قسمت به تکنولوژی هایی که توی اون شرکت (یا پوزیشن) داشتید اشاره کنید. سعی کنید موارد مهم تر رو bold کنید که به چشم بیان. این مورد رو میتونید توی توضیحات اون پوزیشن هم بنویسید که خیلی بیشتر کمک میکنه.البته دقت کنید که این نکاتی که هایلایت می‌کنید باید هم‌راستا با نیاز های اون کمپانی هم باشه. مثلا اگه توی Job description اون شرکت نوشته ما نیاز به ThreeJS داریم و شما هم قبلا تجربه اش رو دارید حتما بهش اشاره کنید و bold هم کنید.این مورد با اون تکنولوژی های کلی که تو رزومه میذارید فرق داره، این اشاره داره به اینکه توی اون شرکت قبلی مرتبط با اون پوزیشن چه اسکیل هایی مورد استفاده بوده.زبان رزومهمن برای این فرمولی واقعا پیدا نکردم ولی خودم همیشه انگلیسی فرستادم همه جا. حالا اگه شرکت برای یه جای دیگه بود توی همون فایل (نه یه فایل جدا) انتهاش ترجمه اش هم گذاشتم که طرف راحت بتونه بخونه.اسم فایلاین مورد خیییییلی مهمه، خیلی دیدم که اسم فایلی که میفرستن بچه ها اصلا اشاره ای به اسمشون نداره که هیچ، مثلا نوشته Resume (5) 🤦‍♂️خیلی بدهههههاسم فایل باید اسم کامل خودتون باشه. بدون هیچ زیاد و کمی. اگه طرف رزومه ۱۰ نفر هم اینطوری دانلود کنه که همه چی گم میشه.استایل رزومهرزومه dark mode نفرستید. شما برنامه نویس هستید اوکی، ولی دلیل نمیشه رنگ زمینه رزومه تون هم تیره باشه با متن سفید. همیشه پس زمینه سفید بذارید.برای اسمتون بزرگ ترین فونت رو استفاده کنید (البته بزرگترین که میگم نسبت به بقیه اندازه های رزومه)سعی کنید تا جای ممکن هارمونی فونت ها برقرار باشه، هرجا یه فونت متفاوت نباشه. حتی رنگ نوشته ها هم سعی کنید هماهنگ باشن. اینکه میگم هماهنگ باشن نه اینکه همه شون یک رنگ باشن. مثلا تکنولوژی ها تون رو میتونید خاکستری تیره بذارید، ولی همه جا تکنولوژی ها همین رنگی باشه.اون bullet point هایی که برای توضیحات کارتون میذارید رو حتما indent کنید.قسمت مهارت هامن کاری که کردم این بود که اسکیل هام رو سه قسمت کردم:تکنیکال - Technical Skillsانسانی یا نرم - Human Skills یا همون Soft skillsکتابخونه ها - Librariesواژه Hard skill یکم یه جوریه... من خوشم نمیاد ازش ولی اگه دوس دارید به جای تکنیکال میتونید از این استفاده کنید.از این لوس بازیا که ۵ ستاره میدن و ۳ ستاره میدن و درصد میذارن و اینا هم نکنید! خیلی بده. همه چی نسبی هست. نمیشه به چیزی درصد و اندازه داد والا.این قسمت رو بذارید بعد از تجربیات تون. حتما اونایی که برای اون شرکت هدف تون مهم تر هستند رو bold کنید. خیلی روی تفکیک این مواردی که مینویسید دقت کنید. مثلا یهو HTML رو توی کتابخونه ها ننویسید.این قسمت میتونه بسته به تخصصی که دارید انعطاف داشته باشه ولی کلا این ۳ موردی که گفتم رو من خیلی توی رزومه های استاندارد زیاد دیدم که می‌نویسن.مرسی که خوندین، اگه نکته دیگه ای به ذهنتون رسید که من نگفتم حتما بگید که اضافه کنم، اگه دوس داشتین هم میتونین از طریق لینکدین باهام در ارتباط باشین.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Wed, 17 Jul 2024 12:20:30 +0330</pubDate>
            </item>
                    <item>
                <title>سال ۱۴۰۲ تمام - معرفی کتاب و پادکست و ویدئو</title>
                <link>https://virgool.io/@hesanam/%D8%B3%D8%A7%D9%84-%DB%B1%DB%B4%DB%B0%DB%B2-%D8%AA%D9%85%D8%A7%D9%85-%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%DA%A9%D8%AA%D8%A7%D8%A8-%D9%88-%D9%BE%D8%A7%D8%AF%DA%A9%D8%B3%D8%AA-%D9%88-%D9%88%DB%8C%D8%AF%D8%A6%D9%88-fzjykzngyisp</link>
                <description>خب سال نو شما مبارک! سال ۱۴۰۲ تموم شد. فکر کردم بد نیست یه برنامه اشتراک گذاری فیلم و پادکست و کتاب و ویدئو و ... داشته باشم باهاتون که شما هم کامنت بذارید و تجربه های خودتونو بگید.مدل این مطلب اینطوری هم نیست که من یه پادکست یا یک فیلم و یه چیز خیلی کلی رو بگم. به نظرم به درد نمیخوره اینطوری. من میخوام اگه کتاب معرفی میکنم، بگم کدوم quote اش برام جالب تر بود یا کدوم اپیزود از اون پادکست برام جالب تر بود و چرا؟ به نظرم اگه شمام میخواید چیزی به کسی معرفی کنید اینطوری اینکارو انجام بدین. (البته به نظرم بهتره که متناسب با شخصیت اون آدم اینکارو بکنید که خیلی باحال تر هم میشه)راستی میدونم که الان نزدیک یه هفته از سال جدید گذشته ولی خب من امروز حوصله ام کشید بشینم بنویسم اینو 😁 پس پوزش میخوام.نکته آخر هم اینکه، من میدونم که شاید دوستانی که مطالب من رو میخونن و یا دنبال میکنن به خاطر موضوعات فنی تر یا مرتبط با نرم افزار و فرانت اند و ... هست ولی این پست بیشتر یک پست شخصی هست و لزوما مطالبش ربطی به اون مباحث نداره. اگر میخونید دمتون گرم🥰پادکستخب من خیلی خیلی خیلی زیاد پادکست گوش میکنم و برام سخته انتخاب یه پادکست از بین همه چیزایی که گوش میدم. سعی میکنم ۲-۳ مورد بگم که دل خودم حداقل خنک بشه.چگونه فرمولا وان به زندگی روزمره کمک می‌کند؟نکته کنجکاوی من راجع به این اپیزود از پادکست &quot;تد و کمی بیشتر&quot; عنوان اپیزود بود. واقعا همیشه سوال هست که آیا مسابقات فرمولا وان واقعا به چه دردی میخوره؟ صرفا یه عده آدم هستن که توی پیست دارن هی دور میزنن و هدفشون اینه که مسابقه رو برنده بشن؟ که چی بشه؟ اصلا هدف توسعه چنین ماشین هایی چی هست؟واقعا یکی از شگفت انگیز ترین و جالب ترین پادکست هایی بود که شنیدم. اینکه چقدر چیز هایی که ما روزمره داریم باهاشون کار می‌کنیم یا می‌بینیم اولین بار توی ماشین های فرمولا وان استفاده شدن و در زمان خودشون جزو تکنولوژی های بسیار مدرنی بودن. مثلا چی؟ مثلا ترمز ABS که روی همه ماشینامون داریمش. یا یکم شیک تر همون پدل شیفتر های پشت فرمون یا فیبر کربن و ...حالا این های چیز هایی بودن که برای ما قابل لمس تر هستند، ولی موضوع پادکست راجع به اینا نیست، اینا حاشیه است. موضوع اصلی راجع به یک سخنرانی TED هست که چطور میشه با تکنولوژی های مانیتورینگ فرمولا وان از سکته قلبی نوزاد ها قبل از اتفاق افتادن شون جلوگیری کرد. البته این TED برای ۱۰ سال پیش هست و شاید امروز یکی بتونه اینکار رو بهتر با یادگیری ماشین انجام بده. ولی گوش دادنش رو به شدت توصیه میکنم. https://podcasts.google.com/?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy8xMDg3MzJiOC9wb2RjYXN0L3Jzcw%3D%3D&amp;episode=dGVkYW5kbW9yZS5wb2RiZWFuLmNvbS8lZDklYmUlZGIlOGMlZDglYWElZDglYjElZDklODglZDklODYtJWQ5JTg1JWQ4JWE3JWQ5JTg2JWQ5JTg2LSVkOSU4MSVkOCViMSVkOSU4NSVkOSU4OCVkOSU4NCVkOCVhNyVkOSU4OCVkOCVhNyVkOSU4NiVkOCUtNTdmZGM2ZjI3MDMyOThhNGM0ZDc5YWM4OWRlMmNlNTI%3D مکانیک ایمانپادکست &quot;بی پلاس&quot; رو اگر بشناسید سازنده این پادکست یعنی &quot;پادکست پرسه&quot; رو هم میشناسید. عباس سیدین. کلا ما پادکست هایی که خلاصه کتاب تعریف میکنن یا راجع به کتاب هستند زیاد داریم. اما هر کدوم به نوعی خاص هستند و جنبه هایی که بهش می‌پردازن مثل هم نیست. یکی فقط خلاصه و چکیده کتاب رو تعریف میکنه و یکی از روی کتاب کامل میخونه مثل یک نسخه صوتی.پادکست پرسه نه اونقدر خلاصه هست که بشه با یکبار گوش دادن کامل متوجه اش شد، نه اونقدر مفصل که حوصله ات سر بره. تازه فقط محدود به کتاب نیست. موضوعی که راجع بهش توی پادکست صحبت میشه شاید بتونم بگم کامل ترین چیزی هست که تو میتونی از اون کتاب بفهمی. هم خیلی خوب بیان میشه هم خیلی به اندازه کتاب رو تعریف میکنه.توی سری اپیزود های مکانیک ایمان، راجع به موضوع ایمان و دین و تاثیرش و ریشه های پیدایش دین و تنوع ادیان و ... صحبت میکنه. خیلی سخته بخوام توی یک پاراگراف خلاصه کنم که پادکست و کتابی که داره روایت میکنه میخواد چی بگه. اما به طور کلی نگاه من به ادیان و باور هایی که داریم رو به شدت تغییر داد. توصیه میکنم حتما گوش بدید این ۴ اپیزود رو.اگر خوشتون اومد اپیزود &quot;مولکول های جادویی&quot; هم بشنوید که موضوعش راجع به LSD هست که خیلی اونم جالب بود برام. https://podcasts.google.com/?feed=aHR0cHM6Ly9mZWVkcy5hY2FzdC5jb20vcHVibGljL3Nob3dzLzY1ODI2YmNjOTZiNjZhMDAxNmM5Mzk2YQ%3D%3D&amp;episode=NjVhNzYxYjI3OWM0ODQwMDE3MGMxNDVj پودر سفید مرموز | تاریخ نمکیکی از پادکست های مورد علاقه من که دنبالش میکنم پادکست چیزکست هست. کلا این پادکست راجع به چیز ها صحبت میکنه. از کجا اومدن؟ چی شد انقدر پر استفاده شدن؟ کلا پادکست بسیار جالبیه. اما اپیزودی که من پارسال گوش دادم و خیلی برام نسبت به بقیه اپیزود ها جالب تر بود در مورد نمک بود!توی این اپیزود در مورد تاریخ نمک صحبت میکنه از اول تا امروز که جز توی سفره ها و آشپزی ما جای دیگه کمتر می‌بینیم نمک رو. انقدر این ماده مهم بوده که چه جنگ هایی براش اتفاق افتاده و چه انسان هایی که کشته شدن. هم به خاطر خود نمک هم به خاطر تاثیرات نمک. شما ببین چقدر مهم بوده در زمانی این نمک که اصلا ریشه واژه Salary یا همون حقوق از نمک میاد!اگه این اپیزودش رو دوست داشتید پیشنهاد میکنم اپیزود های دیگه راجع به خودکار، سلاح شیمیایی، دینامیت و موسیقی بلاچاو هم بشنوید که خیلی خیلی جالب هستند. https://podcasts.google.com/?feed=aHR0cHM6Ly9mZWVkLnBvZGJlYW4uY29tL2NoaXpjYXN0L2ZlZWQueG1s&amp;episode=Y2hpemNhc3QucG9kYmVhbi5jb20vNGVhYWJiNjQtYjUyMC0zYzhhLWJiZjgtZTUyOTJjMTQ0YzM4 فیلمسال ۱۴۰۲ من زیاد نتونستم فیلم ببینم. اما چندتایی که دیدم فیلمای خوبی بودن. بین این فیلم ها یه فیلم برای من خیلی حال غریبی داشت. لزوما فیلمای جدیدی نیستن و شاید دیده باشیدشون قبلا.فیلم The Whaleکل فیلم راجع به یک چیز هست! که همون اول فیلم به شما میگه. من نمیخوام فیلم رو اسپویل کنم برای کسانی که ندیدند. برای من چند تا نکته برجسته داشت:اینکه واقع این میزان از تعهد و جدی گرفتن و Dedication برای یک بازیگر واقعا تحسین برانگیزه که البته اسکار نقش بهترین بازیگر رو براش به همراه داشت که لیاقتش رو واقعا داشت.چقدر من تحت تاثیر کاراکتر اصلی فیلم قرار گرفتم، میشه بهش نگاه ترحم برانگیز کرد، میشه بهش گفت احمق، میشه اونو یه قهرمان دید. به نظر من انقدر این کاراکتر وجه های مختلف داشت که هرکسی متناسب با وضعیت خودش میتونه باهاش همزاد پنداری کنه. دست کم این چیزی بود که من حس کردم.کل فیلم تو یه لوکیشن اتفاق میوفته و تو طول فیلم شما اصلا این موضوع رو احساس نمی‌کنید. حوصله تون سر نمیره.من تا انتهای موزیک تیتراژ آخر فیلم نشسته بودم و به صفحه خیره شده بودم! من همچین آدمی نیستم در حالت معمول 😁 (فکر کنم هیچکس نباشه البته)میشه از فیلم درس های زیادی گرفت. به نظرم فیلم عمیقی بود. همونطور که راجع به کاراکتر اصلی فیلم گفتم که هرکس با توجه به وضعیت خودش میتونه باهاش همزاد پنداری کنه، میشه از کل فیلم هم برداشت های متفاوتی کرد. در سطحی ترین حالت ممکن، فیلم تکان دهنده ای هست.فیلم The Fabelmansفیلم رو اسپیلبرگ (Steven Spielberg) ساخته و بر اساس زندگی خودش در کودکی و علاقه مند شدنش به فیلم سازی هست! واقعا فیلم حال خوبی داره! حتی جاهایی که داره سعی میکنه شما رو غمگین کنه.نکته های فیلم که برای من جالب بود:خلاقیت چقدر توی کار مهمه! میشه با امکانات خیلی خیلی کم، کار های خیلی بزرگ کرد. برای من که بسیار کمال گرا هستم خیلی الهام بخش بود. پدر اسپیلبرگ تو حوزه تکنولوژی چه کار های باحالی انجام داده و چه کاراکتر جالبی داشته.چقدر توجه کردن به علایق بچه ها توی سنین کم میتونه مسیر زندگیشون رو در آینده تغییر بده.موقعیت خورشید توی تصویر تعیین کننده است!‌😁 (فیلم رو ببینید متوجه میشید)کتابمتاسفانه تو سالی که گذشت زیاد کتاب نخوندم.ولی کتاب &quot;Friends, Lovers, and the Big Terrible Thing&quot; رو میگم. کتاب رو Matthew Perry بازیگر سریال Friends که نقش Chandler رو داشت. نوشته و در مورد زندگی خودش هست. چقدر این آدم زندگی غمگینی داشته و چقدر با این کتاب میشه فهمید که تمام لحظه هایی که ما توی سریال فرندز داشتیم می‌خندیدیم زندگی این آدم چطور داشته می‌گذشته. متاسفانه تو سالی که گذشت ایشون از دنیا رفتن ولی من قبل از فوت ایشون کتاب رو خونده بودم و خبرش با توجه به چیزی که ازش فهمیده بودم خیلی دردناک تر هم شد برام. روحش شاد.یه کتاب دیگه اگه بخوام بگم (البته هنوز تمومش نکردم) کتاب &quot;مغالطه های پرکاربرد&quot; هست از ریچارد پل و لیندا الدر بازنویسی شده توسط مهدی خسروانی.کتاب به نظر کتاب زردی میاد 😁 ولی اینطور نیست، کتاب در واقع راجع به مغلطه است! البته از عنوانش هم پیداست اما نکته قشنگش اینجاست که در مورد این نیست که چطور مغلطه کنید، در مورد اینه که چطور توی این چاله نیوفتید و کسی که داره باهاتون صحبت می‌کنه رو بهتر بشناسید.ویدئوخب مثل پادکست ها من خیلی خیلی زیاد ویدئو میبینم روی یوتوب. میتونم بگم خیلی وسواس زیادی هم دارم روی چیزی که میبینم. برام ساده بود که انتخاب کنم که کدوم ویدئو ها برام جذاب تر بودن.اگه یه تخم مرغ رو از فضا بندازیم روی زمین، چی میشه؟به نظر خیلی احمقانه میاد. که چی بشه خب؟ حالا گیریم که یه تخم مرغ رو از فضا پرت کردیم زمین. چی میشه؟نکته این نیست. نکته فرایند حل مساله هست! کسی که ویدئو ساخته یا بهتر بگم صاحب این کانال، قبلا یکی از مهندسین ناسا بوده. مساله اینه: چطور یک تخم مرغ که اگه از ارتفاع ۲۰ سانتی متری بیوفته میشکنه رو میشه از فضا سالم روی زمین انداخت؟اصلا انداختنش به کنار، چطوری بفرستیمش فضا؟؟؟نکته جالب ویدئو اینه که چقدر این آدم جالب با مساله برخورد میکنه. اینکه چطور مساله رو میشکنه به مسائل کوچکتر و برای حل هر کدوم از دوستانش کمک می‌گیره. حالا آیا تخم مرغه میشکنه؟ برید ببینید!ویدیو رو میتونید از اینجا ببینیدچگونه مورتال کمبت باعث شکل گیری نظام رده بندی سنی شد؟امسال من یه کانالی پیدا کردم که برخلاف کانال های گیمینگ دیگه که میشینن بازی میکنن و مسخره بازی در میارن و کاملا مزخرف هستن، میاد راجع به تاریخچه بازی ها صحبت میکنه! خییییییلی جذاب و کامل موضوع رو توضیح میده. اگه مثل من گیمر باشید خیلی جذابه دونستن اینکه چطور بعضی بازی ها در زمان خودشون ساخته شدن یا چرا انقدر مهم شدن.این ویدئو راجع به اینه که چطور بازی مورتال کمبت باعث شد که برای بازی ها رده بندی سنی بوجود بیاد. اصلا چرا؟ خب البته دلیلش رو ما میدونیم اگه کمبت بازی کرده باشیم 😂 ولی اینکه چه فرایندی طی شد، چه دادگاه هایی تشکیل شد،‌ چع اتفاقاتی افتاد تا در نهایت این اتفاق بیوفته واقعا جالب بود.یه چیزی دوست داشتم بگم اینجا اونم نحوه برخورد با مساله بود. مطمینا اگر این اتفاق توی کشور هایی شبیه کشور ما میوفتاد خیلی راحت در این صنعت رو تخته می‌کردن و هر کسی هم توی این زمینه کار می‌کرد بیکار میشد و موضوع با پاک کردن صورت مساله حل میشد. ولی اونا قبولش کردن،‌ برای یه راه حل پیدا کردن. این موضوع در نوع خودش به نظرم یک اتفاق آموزنده بود. ویدیو رو میتونید از اینجا ببینیدخب این یه پست دلی بود، اگه خوندید دمتون گرم و خیلی خوشحالم می‌کنید اگه شما هم فیلم/سریال/بازی/ویدئو یا پادکستی رو توی سال گذشته تجربه کردید که به نظرتون ارزش اشتراک گذاری داشته باشه رو توی کامنت ها بگید!دمتون گرم و اگه دوس داشتید میتونید از طریق لینکدین باهام در تماس باشید!سال ۱۴۰۳ مبارک!</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Sun, 24 Mar 2024 21:47:07 +0330</pubDate>
            </item>
                    <item>
                <title>موقع انتخاب کردن Lib ها به چی باید توجه کنیم؟</title>
                <link>https://virgool.io/@hesanam/%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D9%86%D8%AA%D8%AE%D8%A7%D8%A8-%DA%A9%D8%B1%D8%AF%D9%86-lib-%D9%87%D8%A7-%D8%A8%D9%87-%DA%86%DB%8C-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%AA%D9%88%D8%AC%D9%87-%DA%A9%D9%86%DB%8C%D9%85-j1owhjhna0fi</link>
                <description>۲-۳ سال پیش میخواستیم برای شرکت نیرو فرانت بگیریم. من باید با افراد مصاحبه می‌کردم. یه بنده خدایی اومد مصاحبه و توی جلسه Live code گفتیم میخوایم یه لیست رو از سرور بگیریم و نشون بدیم که یه قابلیت خیلی ساده برای Pagination هم داشته باشه.استارت کار رو زد و پروژه جدید ایجاد کرد. خب وقتی یه پروژه React Native ایجاد میشه یه تعداد کتابخونه به صورت پیشفرض روش نصب میشه که خب اصطلاحا میگیم out of the box اینا رو داره. بعد برای دریافت دیتا ها از سرور رفت و axios رو نصب کرد.برای UI یه کتابخونه دیگه اضافه کرد (فکر کنم MUI بود). برای فیلتر کردن آیتم ها یه کتابخونه دیگه نصب کرد. برای عکس های گالری یه کتابخونه دیگه نصب کرد... برای کلاس ها یه کتابخونه ی دیگه .... همینطوری مثل یه نفر که میره هایپر مارکت همه چیو از قفسه ها برمیداره شروع کرد به نصب کردن کتابخونه های مختلف! خیلی هاش رو من اصلا نشنیده بودم یا ندیده بودم که وجود دارن! واقعا برگام ریخته بود. تا وسطای کار پیش رفته بود که گفتم لطفا ادامه نده و تا همینجا کافیه.مشکل اینجا بود که اون فرد انقدر به ابزار ها وابسته شده بود که دیگه عملا خودش هیچ کاری انگار نمیتونست انجام بده.ولی نکته این نیست که اصلا از کتابخونه ها استفاده نکنیم. نکته اینه که زمانی که به فکر اضافه کردن یه پکیج جدید به پروژه هستیم، فرایند تصمیم گیریمون چطور باید باشه و چه چیز هایی رو در نظر بگیریم. میدونیم که بعضی از پکیج ها حجم نهایی باندل ما رو بیشتر میکنن پس بنابراین مهمه که بدونیم چه چیزی رو چه جایی و برای چی داریم اضافه میکنیم. این مطلب راجع به اینه.اصلا چرا پکیج جدید؟آیا کاری که میخواید انجام بدید رو بدون پکیج هم میشه انجام داد؟ چه دلیلی داره که برای انجامش پکیج بخواد اضافه بشه؟ بذارید برای درک راحت تر براتون مثال بزنم.فرض کنیم پکیجی که میخوایم نصب کنیم یک پکیج مثل lodash هست. این پکیج یه سری ابزار در اختیار ما قرار میده که مثلا بتونیم با array ها راحت تر کار کنیم. کارایی مثل فیلتر کردن و index گرفتن و مرتب کردن و کلی چیزای دیگه. خب بودن چنین کتابخونه ای میتونه کمک کنه ولی آیا بدون این کتابخونه میشه اینکارارو انجام داد؟ یا اگه این پکیج رو اضافه کنیم که ۲۰۰ تا کار انجام میده،‌ ما میخوایم از همه اون ۲۰۰ تا تابع استفاده کنیم یا استفاده مون محدود میشه به ۱۰ تا دونه از اون توابع؟ کاری به این نداریم که بعضی وقتا میشه به کمک tree-shaking حجم باندل رو کم کرد و فقط توابعی رو توی پکیج نهایی آورد که واقعا استفاده شدن. موضوع اینه که ارزشش رو داره؟پس قبل از اضافه کردن پکیج جدید اول راجع به ضرورت اینکار فکر کنیم، شاید بشه بدون اون پکیج هم اونکار رو انجام داد.اما خب میدونیم که همیشه سناریو اینطور نیست و بعضی وقتا مجبوریم برای صرفه جویی تو زمان و یا دلایل دیگه از پکیج ها استفاده کنیم. پس در ادامه در مورد این صحبت میکنیم که در چنین مواقعی، بهتره چطور این تصمیم رو بگیریم و چه چیز هایی رو در نظر بگیریم.هزینه و مزیت (Cost and Benefit)خب حالا دیگه تصمیم بر اینه که کتابخونه جدید اضافه بشه، به چه چیز هایی باید فکر کنیم؟به طور کلی میتونیم این موارد رو در نظر بگیریم:باندل سایزپشتیبانی و Communityهماهنگی با بقیه اجزای سیستم (Compatibility)وابستگی ها (Dependency)هزینه یادگیری (Learning curve)پرفورمنس (Performance)داکیومنت ها (Documentation)چندتا مورد دیگه هم هست که به نظرم تو دسته بندی خاصی قرار نمیگیرن ولی توضیح میدم.باندل سایزقبل اینکه دستور npm install یا yarn add رو بزنید، میتونید به کمک ابزار هایی مثل bundlephobia حجم شون رو چک کنید. مثلا اگه بین انتخاب ۲ تا کتابخونه مردد هستین، این میتونه گزینه خوبی باشه برای مقایسه و راحت تر کردن انتخاب مون.برای نمونه من ۲ تا کتابخونه Formik و React hook form رو باهم مقایسه کردم:قسمت های مهم رو هایلایت کردم. اول اون ۳ تا مورد کوچیک که اون بالاست داره میگه این کتابخونه قابلیت Tree-shaking داره. یعنی به کمک webpack میشه قسمت هاییش که توی پروژه استفاده نشده رو هرس کرد و ریخت دور که هجم باندل رو زیاد نکنه. خب این یه نکته مثبته. ✅دوم اینکه side-effect ای نداره. یعنی API ها و ابزار هایی که این کتابخونه داره در اختیار شما قرار میده روی بقیه اجزای سیستم تون تاثیری نمیذاره که خب این خیلی نکته خوبیه ✅سوم اینکه این کتابخونه آیا به کتابخونه های ریز و درشت دیگه ای وابستگی داره؟ به بیان دیگه وقتی شما این کتابخونه رو نصب میکنی همراه خودش چه چیزای دیگه ای نصب میکنه. خب طبیعیه که هرچی تعداد این dependency ها کمتر باشه بهتره. که خب اینجا میبینیم که صفر هست ✅نکته بعدی در مورد حجم باندل اش هست. به صورت minimize میبینیم که حجمش چقدره، همینطور به صورت minimize + gzip. کلا رفرنسی از اینکه این عدد چقدر باید باشه وجود نداره یا نمیشه گفت چون کتابخونه های مختلف کارای مختلف میکنن. هرچی کمتر باشه ولی میدونیم که بهتره دیگه. همینطور که مشخصه، پکیج formik در مقایسه با react hook form خیلی ضعف های بیشتری داره. مثلا اینکه پکیج اش ۸ تا dependency داره ❌ولی همچنان tree shakable هست ✅ در مقایسه حجم پکیج هم مشخصا نسبت به react hook form سنگین تره ❌یه نکته مهم: ما اینجا داریم در مورد dependency ها صحبت ‌میکنیم، بنابراین باید دقت کنیم بعضی از ابزار هایی که استفاده میخوایم بکنیم صرفا تو فرایند develop به ما کمک میکنن. بنابراین باید دقت کنیم همیشه که مثلا چیزایی مثلا TypeScript یا ESLint یا Prettier و امثال اینها رو حتما به صورت devDependency نصب کنیم که تاثیری روی باندل سایز ما نگذارن.پشتیبانی و Communityبعضی کتابخونه ها هستن مثل یه چیزی که مثلا من نوشتم 😁 کلا به جز خودم و شااااید چندتا از دوستام کس دیگه ای ازش استفاده نمیکنه. این مدل کتابخونه ها تو اینترنت کم نیستن. اگه از این مدل ابزار ها بخوایم استفاده کنیم میدونیم که آخر و عاقبت خوشی نداره. هر مشکلی یا سوالی یا چیزی پیش بیاد ما ناچاریم که ۰ تا ۱۰۰ اش رو خودمون انجام بدیم. پس برمیگردیم به همون نقطه ای که ازش شروع کردیم. اصلا چرا؟قبل نصب بد نیست یه نگاهی به گیتهاب اون پروژه بندازید. ببینید چقدر issue باز داره و چندتا از issue ها بسته شدن. چقدر اون Contributer ها فعال هستن و سریع جواب میدن. یا چندتا star داره یا روی npm به صورت هفتگی چندبار دانلود میشه.هماهنگی یا Compatibility و وابستگی ها (Dependencies)این مورد خیلی سادس، کلا چقدر این کتابخونه با اپلیکیشن شما هماهنگه. مثال خیلی خیلی سادش این که شما هیچوقت نمیتونید یه پکیج vue رو توی پروژه React نصب کنید! یا خیلی قدیم تر ها یادمه خیلی پکیج هایی که با jQuery کار میکردن رو با کلی دنگ و فنگ میاوردیم توی React که کار کنه. خب چرااا؟؟ 😁خب این موضوع که واضحه ولی واقعا قبل اینکه نصب کنیم مثلا بهتره که چک کنیم نسخه React این کتابخونه با نسخه ری-اکتی که ما داریم هماهنگ باشه. بعضی کتابخونه ها به خاطر اینکه قدیمی تر هستن مثلا با ری-اکت نسخه های بالاتر خوب کار نمیکنن.همینطور بهتره که چک کنیم که کتابخونه ای که داریم اضافه می‌کنیم به جز پکیج اصلیش چه چیزای دیگه ای هم همراهش نصب میشه. طبیعتا هر چی تعداد این dependency ها کمتر باشه بهتره ولی اگر اینطور هم نبود و ما هم انتخاب دیگه ای نداشتیم، دست کم چک کنیم که این dependency ها با پروژه مون هماهنگی داشته باشن.بحث Learning Curveاین موضوع از اون موضوعات به شدت مهمیه که شاید خیلی اوقات ما هم کمتر بهش فکر می‌کنیم. به نظرم اصلا یکی از مهم ترین شاخص های انتخاب یه کتابخونه یا فریمورک موضوع اینه که توی تیم کی اینو بلده از قبل و یا یاد گرفتنش چقدر زمان میبره؟اصلا یکی از دلایلی که میریم سمت کتابخونه های خیلی شناخته شده تر اینه. مثلا شما اگه میخواید سیستم Router به پروژه اضافه کنید تقریبا شاید ۵-۶ تا انتخاب داشته باشید ولی میدونیم که اکثر توسعه دهنده ها ۱-۲ مدل از اونا رو بلدن. انتخاب یه کتابخونه یا فریم ورک که بقیه از قبل باهاش آشنا باشن بحث به شدت مهمیه.یکی از counter argument های خیلی مهم برای اینکه خودمون نیایم راه حل های عجیب و غریب بزنیم یا خودمون برای خودمون یه فریمورک (در سطح کل پروژه) بسازیم از صفر همین موضوعه. کسی که میخواد بعدا با ما کار بکنه و توی تیم اضافه بشه احتمال اینکه مثلا قبلا با react router dom یا حتی خود React کار کرده باشه خیلی خیلی خیلی بیشتره تا اینکه بخوایم همه چیز رو از اول خودمون نوشته باشیم.این یعنی هزینه onboarding افراد جدید به پروژه رو داریم بالاتر می‌بریم.توی انتخاب هامون هم این موضوع مهمیه چون که بعضی از کتابخونه ها یادگیریشون بسیار هزینه بر هست. بنابراین اینجا ما یک trade-off داریم که باید در نظر بگیریم. برای نمونه اگر میخوایم برای data visualization از یه کتابخونه استفاده کنیم باید سعی کنیم چیزی باشه که یا افراد دیگه ی تیم اون رو بلد باشن و یا یاد گرفتن اون کتابخونه جدید براشون کار ساده تری باشه.تو چنین شرایطی انتخاب یه کتابخونه مثل D3 میتونه یه ریسک بزرگ باشه چون هزینه توسعه رو به شدت بالا میبره و سرعت رو میاره پایین. درسته که توی performance شاید خیلی خیلی با اختلاف زیادی نسبت به بقیه گزینه مناسب تری باشه ولی ما چی بدست میاریم و چی از دست میدیم؟ همیشه این موضوع رو باید گوشه ذهنمون داشته باشیم. در مواقعی که پروژه ها ددلاین های محدود دارن باید چیزی رو انتخاب کنیم که بتونیم سریع توسعه بدیم و کار رو برسونیم.از طرف دیگه اینکه اون کتابخونه چقدر community فعالی داره یا چقدر داکیومنت های خوبی داره هم توی فرایند learning curve اش مهمه و در انتخابش تاثیر گذاره. که البته جلوتر راجع بهش صحبت میکنم.پرفورمنس (Performance)البته که شاید خیلی مواقع دلیل اصلی ما (یا شاید یکی از دلایل ما) برای انتخاب کتابخونه هایی که مطرح تر هستن همین بحث Performance هست. میدونیم که هر چه قدر اون کتابخونه جامعه فعال تری داشته باشه و تعداد کاربران بیشتری داشته باشه یعنی edge case های بیشتری رو تونسته هندل بکنه . احتمال اینکه اون وسط یهو یه چیز خیلی تابلویی بترکه خیلی خیلی خیلی کمتر هست!این توی کتابخونه های بزرگ کاملا موضوع طبیعی ای هست چون شما تصور کن یه چیزی مثل bootstrap یا react router dom یا react query بسیار بسیار محبوب هستن. از طرفی اگر کسی issue خاصی روی اینا پیدا کنه سریع تر گزارش میشه و به خاطر community فعالی که دارن سریع تر هم فیکس میشن و کتابخونه ها سلامت تر هستن به طور کلی.موضوع پرفورمنس هم توی همین قاعده بهش نگاه کنیم. کتابخونه های معروف و مطرح که کاربران بیشتری دارن پس احتمالا اپلیکیشن های خیلی زیادی هم دارن ازشون استفاده میکنن بنابراین خیلی پولیش شده تر و سلامت تر و بهینه تر کار میکنن. برای مقایسه من کتابخونه a رو با کتابخونه b مقایسه نمیکنم،‌ اینطور بهش نگاه میکنم که اگر من خودم میخواستم یه ابزار شبیه اونایی که نام بردم بنویسم چقدر مشکل performance داشتن؟ قطعا چیزی که من می‌نویسم نمیتونه با یه چیزی که شاید ده ها توسعه دهنده داره رقابت کنه.البته ناگفته نماند که من حرفم این نیست که کلا توسعه ابزار های local برای پروژه خودمون رو کلا کنار بذاریم، بعضی وقتا شاید حتی چاره ای نداشته باشیم جز اینکه خودمون ابزار خودمونو بنویسیم. حرفم اینه که تا جایی که اون trade-off بیشتر به سمت منفعت داشتن شون (با در نظر گرفتن تمام نکاتی که گفتم)‌ سنگینی میکنه، توسعه یه ابزار توسط تیم خودمون قطعا کار عاقلانه ای نیست.داکیومنت (Documentation)همه چیزایی که تا حالا گفتم خیلی مهم بودن! ولی داکیومنت های یه کتابخونه شاید اولین چیزی هستن که شما رو با اون ابزار آشنا میکنن. در آینده اگر هم بخوایم از اون کتابخونه ها استفاده کنیم همین داکیومنت ها قراره راهنمای ما باشن برای جایی که به مشکل بخوریم‌، کار خاصی بخوایم انجام بدیم و ...داشتن یه داکیومنت خوب بهمون کمک میکنه که هم هزینه یادگیری اون کتابخونه رو کاهش بدیم، هم اگر به مشکلی خوردیم بتونیم راحت تر حلش کنیم، هم از همه مهم تر:قبل از نصب اون کتابخونه مطمئن بشیم که جواب مساله ما این ابزار هست یا نه!یهو نریم تند و تند کتابخونه ها رو اضافه کنیم و از ۱۰۰ اون کتابخونه فقط از ۵ درصدش استفاده کنیم. این کار عاقلانه ای نیست.اگرم میخوایم بدونیم که این کتابخونه داکیومنت های خوبی داره یا نه،‌ ببینیم چطور به سوالاتی که ما داریم جواب میده؟ چقدر راحت به چیزی که میخوایم میرسیم؟ اصلا فرایند ستاپ اولیه اون کتابخونه رو چقدر خوب توضیح داده؟موارد دیگهاین موارد به نظرم نیومد که توی Category خاصی قرار بگیرن. برای همین مدل لیستی من بهشون فقط اشاره میکنم:بعضی کتابخونه ها یک Licence خاصی دارن که ممکنه براتون مشکل ساز بشه. البته ما تو ایرانیم 😁بد نیست بعد اینکه کتابخونه جدید رو اضافه کردین یه بار audit کنید ببینید آسیب پذیری عجیبی نداشته باشه.اجازه ندید توی پروژه تون پکیج هایی اضافه بشن که صرفا و صرفا به خاطر جوگیر شدن بودن. مثلا همه یهو هایپ شدن برن سمت یه چیزی. شما تصمیم درست رو بگیرید.بلند نظر باشید،‌ این رو بدونیم که پروژه ای که روی یه کتابخونه یا فریمورک بنا میشه قراره شاید سال ها روی اون ریل بره جلو پس توی انتخاب تون خیلی دقت کنید.اگه پروژه تون TypeScript هست چک کنید حتما پکیج تون هماهنگ باشه باهاش.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Thu, 14 Mar 2024 10:38:58 +0330</pubDate>
            </item>
                    <item>
                <title>در باب Documentation در Front-end</title>
                <link>https://virgool.io/@hesanam/%D8%AF%D8%B1-%D8%A8%D8%A7%D8%A8-documentation-%D8%AF%D8%B1-front-end-esqq9nvjjco6</link>
                <description>۵-۶ سال پیش وقتی برای اولین بار استخدام شدم، روز اول کاریم رو هیچوقت فراموش نمیکنم. یه اتاق ۳ متر در ۴ متر بود که یک گوشه اش یه نفر دیگه نشسته بود. میزم رو آماده کرده بودن و من نشستم و برای اولین بار توی شرکتی بودم که سیستمی که بهم داده بودن یه Mac بود. خیلی خوشحال و خندون نشستم و منتظر موندم تا بهم بگن دقیقا برنامه چیه.بعد از حدودا نیم ساعت، مدیرم اومد و بعد از خوش و بش کردن، گفت:- خوب بریم سراغ کارمون! برو توی اپ-استور، این اسمی که میگم رو سرچ کن: &quot;RecycleCoach&quot;. دانلودش کن یکم باهاش کار کن و بعد بهم بگو.منم رفتم و دانلود کردم و سعی کردم بفهمم چیکار میکنه. حدودا یک ساعت بعد دوباره مدیرم اومد و خیلی خلاصه و مفید توضیح داد:- ببین این اپلیکیشن رو ما سال ۲۰۰۹ نوشتیم، برای شهرداری های کانادا و امریکا هست. اون زمان اینو با Cordova نوشتیم. از امروز کار تو اینه که اینو با React Native باز نویسی کنی. الان خرداد هست دیگه آره؟ ما اینو تا آخر تابستون میخوایم داشته باشیم. موفق باشی!بعد رفتمن نه تنها نفهمیده بودم که اون اپلیکیشن دقیقا چیکار میکنه!! بلکه حتی React هم بلد نبودم چه برسه به React Native! ددلاین ۳ ماهه؟؟ گفتم این چه جاییه من اومدم کار کنم؟؟؟البته الان که بهش نگاه میکنم میبینم یکی از بهترین تجربه های کاریم بود و اولین جایی که به من برای یه پروژه خیلی جدی (خیییلی جدی) اعتماد شد و من تمام تلاشم رو کردم.هر روز که میگذشت من نه تنها باید سعی میکردم نحوه کار کرد خود اپلیکیشن رو یاد بگیرم و سر در بیارم،‌ بلکه باید React Native هم یاد می‌گرفتم. هیچ داکیومنتی از نحوه کارش وجود نداشت. همه چیز اونجا بود، توی کد. خب یه کدی هم که سال ۲۰۰۹ نوشته شده بود بعد از ۹ سال هیچی نمیشد از توش فهمید. همه چیش قدیمی بود. البته ساختار خوبی داشت اما وقت نداشتم توی ۳ ماه همه چیز رو بخونم و بفهمم و هم توسعه بدم.خیلی وقت ها پیش میومد که توی کد میدیدم یه چیزی هست که انگار هیچ کاری نمیکنه ولی هست! خب چرااا؟؟ من از کجا بدونم این چیه باید چه بلایی سرش بیارم. همینطوریش هم ۹ سال گذشته بود. توی VsCode روی هر فایل و خطی می ایستادم می‌دیدم اینو تو یه سالی یه نفری که اسمش هم غریبه بود نوشته بود و کامیت کرده بود. تقریبا ۴-۵ نفر توی اون مدت رو اون پروژه کار کرده بودن و هرکسی هم یه چیزی بهش اضافه کرده بود.خیلی وضعیت نافرم داشت پیش میرفت. یه موضوعاتی بود که هیچجوره نمیفهمیدم شون. فقط هم کد های پروژه که نبود... خیلی وقت ها اصلا دلیل اتفاقاتی که میوفتاد رو نمیفهمیدم.تا اینکه یه لیست از سوالاتی که داشتم آماده کردم و رفت دست به دامن مدیرم شدم و گفتم آقا بیا یه جلسه بذار توضیح بده چی به چیه؟ اونم اومد و یه توضیحاتی داد که نه تنها من بازم چیزی نفهمیدم، بلکه گمراه تر هم شدم!خلاصه که دهن ما سرویس شد ولی به هر ضرب و زوری که بود اپلیکیشن رو با یک ماه تاخیر انتهای مهر ماه رسوندیم.سخت بود؟ قطعا!!ارزشش رو داشت؟ قطعا!میشد کوتاه تر بشه این زمان؟ قطعا!!تجربه خوبی بود؟؟ در کمال ناباوری خیلی زیااد!!اهمیت موضوعاین داستانی که براتون تعریف کردم، کاملا واقعی بود! من تنها شانسی که آوردم این بود که برنامه شرکت بازنویسی اپلیکیشن بود و نه اضافه و کم کردن امکانات همون قبلیه. عملا هیچ چیزی به عنوان یک مرجع که بشه از روش خوند و فهمید موضوع چیه وجود نداشت. به جز سوالایی که میتونستم از مدیرم بپرسم و اونم جوری که خودش موضوع رو می‌دید به من توضیح بده. که البته خیلی اوقات بیشتر من رو گمراه می‌کرد.این مشکلی بود که من با همه وجودم باهاش مواجه شدم و تازه اهمیت وجود Document برای من اونجا روشن شد. البته من قبل از اون داستان خیلی این بحث رو نمیشناختم. خیلی تجربه ام کم بود.شاید اگر از روز اول یک یا چند تا داکیومنت مختلف برای این وجود داشت که من بتونم راحت تر بفهمم که باید دقیقا چیکار کنم خیلی زمان کمتری می‌برد و قطعا کمتر اذیت میشدم. ولی خب این تجربه به من خیلی کمک کرد که بفهمم چرا این بحث خیلی اهمیت داره.از روی همین داستانی که تا اینجا تعریف کردم میتونید مشکلاتی که من باهاشون مواجه بودم رو ببینید:برای فهمیدن منطق کسب و کار من بیشتر باید خودم توی اپلیکیشن میچرخیدم و میفهمیدم چه خبره.اگر سوالی داشتم باید با یک نفر صحبت می‌کردم که اکثر اوقات من از حرفاش به جایی نمی‌رسیدم.اگر میخواستم از روی کد ها متوجه بشم که چه خبره، هیچ داکیومنتی براش وجود نداشت که مفاهیم رو درست توضیح داده باشه.خیلی از چیز هایی که مدیرم بهم میگفت رو خودش هم درست و حسابی یادش نبود.یه جایی یادمه خوندم که می‌گفت:Documentation is not a luxury but a necessity for creating a high-quality, consistent, and accessible front-end.حالا با توجه به این مسائل و مشکلاتی که گفتم، بریم ببینیم چطوری میتونیم این موارد رو حل کنیم.روش فکر (Mindset)موقعی که داریم یه برنامه ای رو توسعه میدیم و میخوایم همزمان باهاش داکیومنت بنویسیم باید اول روش فکر کردنمون راجع به داکیومنت رو درست کنیم. خیلی ساده بگم:باید بدونیم و یاد بگیریم که چی بنویسیم. چرا بنویسیم. چطور بنویسیم. برای کی بنویسیم.به نظر من باید به جای اینکه تمرکز مون روی &quot;چیستی&quot; اجزای سیستم باشه، باید روی &quot;چرایی&quot; اونها باشه.  یعنی چی؟ مثال ساده ای که میزنم اینه: فرض کنیم توی یه فایلی یه تابعی هست که یه دونه API رو داره صدا میزنه. خب اگه بخوایم برای این تابع توضیحاتی رو بنویسیم میتونیم اینطور بنویسیم:&quot;این تابع یک API را به صورت Async صدا میزند و نتیجه را برمی‌گرداند&quot;. -- مدل چیستییا میتونیم اینطور بنویسیم:&quot;در زمان ثبت نام کاربر، اطلاعات کاربر باید در سرور به منظور ارسال پیامک در آینده ذخیره شود&quot;. -- مدل چراییبه نظر شما اگر مثلا ۶ ماه از زمانی که شما این کد رو نوشته باشید بگذره، کدوم متن توضیحی رو بهتر به خاطر میارید یا میتونه بیشتر کمکتون کنه؟ برای من مدل دوم بوده خیلی اوقات.پس به نظرم بهتره در زمان نوشتن داکیومنت ها به این توجه کنیم که توی متن داکیومنت توضیح بدیم که چرا این اتفاقات دارن میوفتن. اینکه اون اجزا (توابع، فایل ها،‌ متد ها و ...) چه کاری دارن انجام میدن رو کسی که اون زبون یا framework رو بلد باشه میتونه متوجه بشه خودش.داکیومنت کردن چه کمکی به ما می‌کنه؟فکر میکنم تا اینجا این موضوع رو متوجه شده باشید. ولی برای اینکه باهم کاملا هم‌صفحه بشیم:کمک می‌کنه Onaboarding افراد جدید خیییلی راحت تر و سریع تر اتفاق بیوفته.کمک میکنه که فهمیدن هدف، نحوه کارکرد و طراحی برنامه بسیار ساده تر بشه.میتونه از تکرار جلوگیری کنه.وابستگی به افراد رو برای فهمیدن چیز ها تقریبا از بین می‌بره.کمک میکنه ساختار برنامه یکنواخت تر و یکدست تر بشه.شرایط رو برای دیباگ کردن و ریفکتور و تست راحت تر میکنه.چی رو باید داکیومنت کنیم؟داکیومنت ها باید هم جنبه های داخلی و هم جنبه های بیرونی برنامه ای که نوشته شده رو پوشش بدن. حالا این یعنی چی؟منظورم جنبه های بیرونی اینه کهاین برنامه چطور کار میکنه؟اون مشتری یا کاربر نهایی باهاش چطوری ارتباط برقرار میکنه؟چه نیازی از کاربر رو رفع میکنه و چطور اینکار رو انجام میده؟و ... - کلا هر چیزی که به ما کمک میکنه کسب و کار رو بهتر متوجه بشیم.منظور از جنبه های داخلی اینه کهاجزای سیستم چه چیز هایی هستن؟چه ابزار هایی و به چه دلیل استفاده شدن؟ساختار پروژه و معماری به چه صورتی هست؟چطور پروژه رو باید Setup کنیم؟چه چیز هایی Configurable هستند؟و کلا خیلی چیز ها مثل کامنت ها، Annotation ها و نحوه اسم گذاری ها و ... مربوط به این بخش میشه.باید نحوه معماری و ساختار پروژه به طور مفصل توضیح داده بشه. اینکه چرا اینطور توسعه داده شده و چطور داره کار میکنه. الگو های تکرار شونده چی هستند؟ و کلی چیز دیگه.تو ادامه مطلب در مورد این صحبت می‌کنیم که این کار ها رو  چطور توی پروژه های Front-end انجام بدیم.چه ابزار ها و چیز هایی رو باید بلد باشیم؟پس تا اینجا متوجه شدیم که مهم ترین چیز برای نوشتن داکیومنت روش تفکر هست. خب ما طبیعتا داریم در مورد Documentation توی پروژه های Front-end صحبت می‌کنیم گرچه مفاهیم کاملا قابل تعمیم هست و خیلی ابزار ها بین همه مشترکه.این داکیومنت ها میتونن هرجایی باشن. مثلا ممکنه یه تیم به این نتیجه برسه که اگه این داکیومنت ها رو توی Confluence بنویسه راحت تره یکی دیگه ممکنه از Google Docs استفاده کنه. راستشو بخواید واقعا مهم نیست کجا باشه تا زمانی که داره جواب میده براتون. اما چیزی که من بیشتر دیدم اینه که این داکیومنت ها توی فایل های Markdown داخل خود پروژه ها نوشته میشن.در واقع Markdown یک زبون نشانه گذاری که خیلی شبیه به همون HTML خودمونه. حتی خیلی خیلی ساده تر. البته اوایل ممکنه یکم غریبی کنید ولی بعد یه مدت عادت می‌کنید. مزیتی که داره اینه که فایل های داکیومنت داخل خود پروژه قرار می‌گیرن و دسترسی بهشون خیلی خیلی ساده تر از Google Docs و Confluence هست.پس اولین چیزی که یاد می‌گیریم: Markdownاسم فایل ها هم معمولا README.md هست. یه دونه فایل داکیومنت اصلی که داخل root پروژه تون قرار می‌گیره میتونه کارو براتون دربیاره. البته هر فولدری از هرجای پروژه تون میتونه برای خودش یه فایل README داشته باشه.حالا اگر بخوایم راجع به ابزار های دیگه که مخصوص فرانت باشه صحبت کنیم می‌رسیم به Storybook که قبلا یه مطلب راجع بهش مفصل توضیح دادم که پیشنهاد میکنم اونو بخونید حتما.یک سری تکنولوژی دیگه هم هست مثل TypeDoc و JSDoc که برای Annotation ها هستند که میتونه خیلی کمکمون کنه که البته جلو تر نمونه هاشون رو می‌بینیم.از طرف دیگه یکی از مهم ترین ابزار های امروزه برای فرانت-اند، TypeScript هست! خدا میدونه چقدر میتونه روی کیفیت خروجی نهایی کل پروژه و البته داکیومنت ها بهمون کمک کنه. البته اگر درست استفاده بشه و نیایم همه جا از تایپ any استفاده کنیم.چطور کد های Front-end و Component ها رو داکیومنت کنیم؟احتمالا اگر ساختار پروژه مون تر و تمیز و سرراست باشه ما یک سری کامپوننت Reusable داریم که بتونیم بار ها و بار ها ازشون توی جاهای مختلف استفاده کنیم. حالا اگه بخوایم خود این کامپوننت ها رو داکیومنت کنیم میتونیم از Storybook استفاده کنیم که کار باهاش هم واقعا سادست. به ما کمک میکنه حالت های مختلف کامپوننت ها رو پیاده سازی کنیم و ببینیم چطور نمایش داده میشن و دقیقا چه کاری برامون انجام میدن.ولی طبیعتا توی پروژه های بزرگ ما فقط و فقط کامپوننت نداریم! کلی تابع مختلف هست که هر کدوم دارن کاری رو برای ما انجام میدن و بعضیاشون نیاز به توضیح دارن.کامنت Annotationچیزی که پیشنهاد شده اینه که اول حتما توی پروژه از TypeScript استفاده بشه. بعد هم برای توابعی که نیاز به توضیحاتی داره از Annotation ها میتونیم استفاده کنیم. خیلی ابتدایی اگه بخوایم توضیح بدیم که دقیقا اینا چی هستن، میتونیم بگیم که این Annotation ها یک سری کامنت ساده هستند که بالای جایی که تابع تعریف شده نوشته میشن که در مورد تابع اطلاعاتی به ما بدن. مثلا اینکه این تابع چه ورودی هایی داره و چه خروجی ای داره. جنس ورودی ها و خروجی ها و مفهوم شون چی هست.یه مثال ازش ببینید:یه تابع که ۲ تا عدد رو میگیره و جمع میزنه و برمیگردونه. توی خط اول توضیح اینکه تابع چه کاری انجام میده قرار داده شده.خط بعدی یه سینتکس param@ داره که در واقع پارامتر اول رو تشریح میکنه و همین روال برای پارامتر دوم هم تکرار میشه.در نهایت returns@ مشخص میکنه که این تابع چه خروجی ای داره.مزیت این Annotation ها علاوه بر اینکه فهمیدن کد رو ساده تر میکنن اینه که توی ادیتورمون یه suggestion خفن و تر و تمیز بهمون میده که نوشتن کد رو خیلی ساده تر میکنه برامون:همینطور که مشخصه، همون Annotation ها که بالا نوشته بودیم اینجا داره بهمون نمایش داده میشه.درسته که این قابلیت خفنیه،‌ ولی دقت کنیم که یهو جوگیر نشیم همینطوری همه جا بخوایم از اینا بذاریم. معمولا اینو برای توابعی میذاریم که مهم تر هستند،‌ یا کاری که انجام میدن نسبتا کار پیچیده تری باشه که احتیاج به توضیح داره، یا توابعی که به طور مکرر استفاده میشن. یادمون نره که کلا اگر اسم توابع اسم های خوبی باشن خیلی جاها اصلا نیاز به توضیح اضافه نداره و اسم تابع خودش توضیح دهنده کاری که انجام میده هست. مهارت اسم خوب انتخاب کردن هم مهارت خیلی مهمیه که باید بهش توجه بشه.بعد از اینکه تقریبا این Annotation هامون رو نوشتیم (که البته معمولا در حین نوشتن تابع انجام میشه) میتونیم بیایم و به کمک TypeDoc یا JSDoc ازشون یه سری خروجی داکیومنت بگیریم. یه چیزی شبیه API Refrence که بتونیم همه توابع پروژه رو یکجا با داکیومنت خودشون داشته باشیم که من دیگه اینجا راجع به اون صحبت نمیکنم. میتونید توی داکیومنت های خودشون پیداشون کنید.داکیومنت های MDقبل تر راجع به Markdown صحبت کردم، اینجا میخوام بگم بهتره چه چیز هایی داخل این فایل های MD بهتره که قرار بگیره.اگر یه نگاهی به کتابخونه های open-souce بندازید، تقریبا یه الگوی مشخص و تکرار شونده میبینید:این کتابخونه چی هست و چه مشکلی رو حل میکنه؟چطور باید نصبش کنیم؟چه کانفیگ هایی داره؟چه API هایی داره و هر کدوم چه کاری انجام میدن؟سوالات پر تکرارچه کسانی روی پروژه کار کردن و چطور باهاشون ارتباط میتونیم بگیریم.خب همین الگو رو ما میتونیم برای پروژه های تجاری هم استفاده کنیم. فایل Readme.md که توی root پروژه قرار گرفته به نظرم قشنگه که شامل این موارد که اشاره کردم بهشون بشه. لزوما قرار نیست همه چیز هم یکجا باشه. میتونید فایل های مختلف md بسازید و توی فولدر های مختلف که مربوط به بخش خودشون هستن قرار بدید و توی فایل اصلی بهشون لینک بدید. اینطوری ساختارش مرتب تر هم میشه.اگر همه اعضای تیم توی نوشتن این داکیومنت ها مشارکت دارن، دقت کنید که قواعد نوشتاری تون و ادبیات و حسی که انتقال میدید یکدست باشه. اینطوری نباشه که یک جا نوشتار خیلی رسمی باشه و یکجای دیگه خیلی خودمونی.خیلی لازمه که فیدبک بگیرید و با چند نفر چک کنید و بهترش کنید. همیشه جا برای بهتر شدن هست.چه زمانی باید بنویسیم؟اینکه کی داکیومنت ها رو بنویسیم هم به نظرم خیلی موضوعی هست که میشه روش به توافق رسید ولی چیزی که من متوجه شدم اینه که اگر داکیومنت ها همون زمانی که دارید توابع و کامپوننت ها رو می‌نویسید انجام بشه نتیجه بهتره.معمولا اول کار قبل اینکه چیزی پیاده بشه که نمیشه داکیومنتی نوشت، از طرفی آخر کار هم اگر بخواید اینکارو بکنید ممکنه یه چیزایی یادتون بره و از قلم بیوفته.نکته خیلی مهم اینه که یه طوری بنویسید که اگر ۶ ماه دیگه برگشتید و بهش نگاه کردید بتونید بفهمید چی بوده. همیشه هم آپدیت نگه دارید این فایل های داک رو.بحث Code of conductوقتی یه پروژه از یه اندازه ای بزرگ تر میشه، برای اینکه هم داکیومنت ها و هم کد ها یکدست باشن یه داکیومنت بعنوان Code of Conduct یا ساده تر بگیم: How to contribute قرار میگیره که توش به اصول و قواعدی که توافق کردیم تو پروژه،‌ اشاره میکنیم. مثلا:اسم متغیر ها باید نشون دهنده کاری که انجام میدن باشههر فایل ماکزیمم ۷۰ خط باشه و اگر بیشتر شد باید بشکنه به فایل های دیگهاستایل ها بهتره با Styled-component هندل بشه.هر برنچ باید حاوی اسم خودتون و شماره تیکت باشه. توی کد هایی که کامیت میشه تست ها قرار داده بشه که Coverage بالایی داشته باشه.توابع پیچیده حتما شامل Annotation کامل باشه.و مسائلی از این قبیل. این به ما کمک میکنه که افراد جدیدی که وارد تیم میشن، از اینکه چطور میتونن مشارکت کنن آگاه بشن. فرایند Code review ها یکدست اتفاق بیوفته و شاهد چند دستگی بین افرادی که کد رو review میکنن نباشیم. کلی مزیت دیگه هم داره.طبیعی هست که این اصول و قواعد در طول زمان تغییر کنن و کم و زیاد بشن. یادمون باشه که این داک رو همیشه آپدیت نگه داریم.یه نمونه از این مورد میتونید اینجا ببینید.ریلیز نوت (Changelog)پروژه هایی که بزرگ و بزرگ تر میشن،‌ طبیعتا شاید تو یک سال چند نسخه ازشون منتشر بشه که توی هر نسخه مواردی تغییر کردن، فیکس شدن، حذف شدن و ... بهتره که لاگ این تغییرات و اینکه چه زمانی و در چه نسخه ای اتفاق افتادن رو داشته باشیم یکجا. توی هر نسخه که منتشر میشه اشاره کنیم که دقیقا این تغییرات چیا بودن و چه تاثیری روی پروژه گذاشتن. آیا تغییری که داده شده میتونه باعث بشه که پروژه از کار بیوفته؟ آیا برای این نسخه جدید همه استفاده کننده هاش باید کاری انجام بدن؟ مثلا یک بار دیگه npm install رو اجرا کنن و مسائل این چنینی.این فایل رو اسمش رو میذارن changelog.md و توش از نسخه اول همه این موارد رو لاگ میذارن تا بعدا بتونن بهش رجوع کنن. ابزار هایی هم هستند که میتونن برای ما اینکار رو به صورت خودکار انجام بدن. مثلا هر بار که یک ریلیز جدید به کمک Gitlab Pipeline انجام میدیم، خودش به صورت خودکار تغییرات (لیست کامیت ها) به همراه شماره و اسم نسخه جدید رو توی فایل changelog بذاره. دستی هم که میدونیم میشه این فایل رو نوشت و ویرایش کرد و ...کد Self-documentedبه نظرم یه باور غلطی که وجود داره اینه که خیلی از ما فکر می‌کنیم اگر کدی رو انقدر خوب بنویسیم که مشخص باشه چیکار میکنه دیگه نیازی به داکیومنت نداریم و اصطلاحا کد self-documented هست.این حرف به نظر من هم درسته هم غلط. اول باید بفهمیم کد self-doc اصلا یعنی چی و منظورش چیه؟منظور از این مفهوم، اینه که اسم توابع، فایل ها، کامپوننت ها، متغیر ها، ثابت ها و ... درست انتخاب بشه. یه نمونه خیلی ساده ازش بزنم: فرض کنید یه متغیر دارید که مقدارش Boolean هست، برای اسم این متغیر بهتره اول اسمش یه is بیاد. مثلا isActive یا isOpen یا چیزای شبیه به این. این حس رو در زمانی که داریم کد رو میخونیم القا میکنه که این یه متغیری هست که ۲ حالت داره: یا هست یا نیست!یا همون مثلا addNumbers که زدیم. از اسمش معلومه که این تابع ۲ تا عدد رو باهم جمع میکنه. این میشه کد self-doc. ولی دلیل اینکه چرا این اعداد باید جمع بشن که مشخص نیست! پس بنابراین همچنان بعضی جاها نیاز به توضیح بیشتر داره که بالاتر راجع بهش مفصل صحبت کردیم.تست هاممکنه باز هم خیلی هامون فکر کنیم اگر برای پروژه و چیز های مختلف تست بنویسیم دیگه نیازی به داکیومنت نداریم. قطعا تست نوشتن خیلی مهم و خوبه و کلی فایده داره. مثلا اینکه هر تابعی چجوری کار میکنه و خروجیش بر اساس ورودی های مختلف چه چوری میشه.پس بیاید روی این توافق کنیم که وجود داشتن تست ها برامون اگه نگیم ضروریه، مفید میتونه باشه. اما جایگزین داکیومنت نوشتن نمیشه. چون ما لازم داریم درک کنیم که چرا همون تست ها اونطوری که هست نوشته شدن؟ چه هدفی رو دنبال میکنن و چطور باید باهاشون کار بشه.نکته مهم راجع به تست نوشتن ها اینه که متن و عنوان Assertion ها تون باید توضیح خوبی بده از اینکه دقیقا چه چیزی داره تست میشه. پس این خودش یه تمرین خوبه. اینکه چه مدل از تست نویسی رو دارید انجام میدید هم مهمه.فکر کنم همین بود! اگر مورد دیگه ای به ذهن شما میرسه حتما بگید که به مطلب اضافه کنم. اگر دوست داشتید میتونید از طریق لینکدین باهام در ارتباط باشید</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Mon, 05 Feb 2024 09:02:22 +0330</pubDate>
            </item>
                    <item>
                <title>سوالات پر تکرار جلسات مشاوره ADPList در مورد Front-end</title>
                <link>https://virgool.io/@hesanam/%D8%B3%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D9%BE%D8%B1-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1-%D8%AC%D9%84%D8%B3%D8%A7%D8%AA-%D9%85%D8%B4%D8%A7%D9%88%D8%B1%D9%87-tk7nv8cnwp6q</link>
                <description>توی پست قبلی که راجع به گزارش ۱۰۰ جلسه منتور شیپ توی ADPList بود، برداشت خودم رو اومدم و اشاره کردم که حتما توی یه مطلب جداگانه میام و سوالاتی که زیاد تکرار شدن رو میگم.و خب حالا اینجاییم! قبلش بگم که این سوالات در عمومی ترین حالت ممکن هستند و توضیح من راجع به این سوالات هم در عمومی ترین حالت ممکنه! پس شرایط خودتون رو هم توشون در نظر بگیرید.یادتون نره تمام اینا تجربیات منه، قطعا جواب ها قطعی نیستن، برای همین حتما با دیگران هم مشورت کنید.رزومه من خوبه؟اینکه رزومه ای که دارید خوبه یا نه رو من نمیتونم بگم واقعا! من خودم نیاز دارم یه نفر بیاد رزومه من رو ببینه و کمکم کنه برای اصلاحش. ولی چیزی که خیلی میدیدم توی رزومه ها چند تا مورد بود که بهشون اشاره میکنم.اول اینکه پروژه هایی که میذارید تو رزومه تون رو تا جایی که میتونید منحصر به فرد کنید! این پروژه ها باید با هدفی خاص انجام شده باشن. توی هر کدوم از این پروژه ها شما باید یک چیز جدید رو یاد گرفته باشید، پس توی قسمت توضیحات پروژه ها حتما بنویسید که چه چالش هایی داشتید و چطور اونها رو حل کردید.اشاره کنید توی هر پروژه با چه ابزار ها و تکنولوژی هایی کار کردید، لیست همه تکنولوژی ها رو فله ای نریزید تو رزومه تون. اون ها رو به هر کدوم از تجربیاتتون Assign کنید. از این طریق به خواننده رزومه تون کمک می‌کنید که بهتر بتونه تشخیص بده که هرجا چه کار داشتید می‌کردید.از گذاشتن پروژه هایی که همه میذارن تو رزومه شون پرهیز کنید، پروژه Todo و آب و هوا و وب سایت شخصی و وب سایت فروشگاهی و ... اینا تو همه رزومه ها هست. پس اگر من کارفرما باشم تابحال حداقل ۲۰ تا دیگه رزومه عین مال شما دیدم پس فایده ای نداره.در مورد قالب و ساختار کلی رزومه تون حتما با یک نفر که توی کار جذب و استخدام یا منابع انسانی هست مشورت کنید، ازشون کمک بخواید که ساختار رزومه تون رو بهتر کنید.از ابزار هایی مثل ChatGPT عاقلانه استفاده کنید و نه کورکورانهاز آوردن درصد و ستاره و امثال اینها کنار مهارت هاتون پرهیز کنید، مهارت های شما چیزی نیستن که بتونید اونا رو اندازه گیری کنیددر آخر خیلی روی رزومه تون حساسیت زیادی به خرج ندید، تنها کاری که رزومه براتون قراره انجام بده اینه که براتون یه وقت مصاحبه بگیره. رزومه شما براتون کار رو قرار نیست بگیره! همه اتفاقات بعد از مصاحبه میوفته.اگر هم دوست دارید میتونید ویدئو های نیما رو ببینید که لینکش اینجاس.کارآموزی. برم؟ نرم؟کارآموزی اگه در جای درست باشه خیلی هم خوبه و فرصت یادگیری بسیار خوبی هم داره. ولی اینکه بخواید راجع به این فکر کنید که برید یک جایی با اسم کارآموزی، کار های مسخره بدن دستتون و خبری از حقوق هم نباشه اصلا انتخاب عاقلانه ای نیست.از طرفی این شرایط خیلی ایده آل هست. شرکتی که هم فرصت کارآموزی رو فراهم کنه و هم یادگیری خوبی داشته باشه و هم حقوق و مزایاش رو پرداخت کنه خییلی خیلی کم پیدا میشه.اینجا هر ۲ طرف (هم کارفرما و هم کارجو) حق دارند. چون اگر شرکتی یا مجموعه ای بخواد شما رو به عنوان کارآموز استخدام کنه،‌ اگر هزینه مالیش رو در نظر نگیریم، هزینه زمان و انرژی انسانی که برای رشد شما صرف میشه همچنان وجود داره و بیاید قبول کنیم که هر شرکتی حاضر به اینکار نیست. از طرفی ممکنه شما بعد از گذشت ۶-۷ ماه که شرکت روی شما سرمایه گذاری کرده موقعیت بهتری پیدا کنید و بخواید مجموعه رو ترک کنید. این یعنی شرکت روی کسی سرمایه گذاری کرده که منفعتش هم برای خودش نیست. حالا اگر بخواد با شما قرار داد سفت و سخت چند ساله ببنده هم که شما قطعا تن به اون قرار داد نمیدید.ولی چه کنیم؟اگر جایی با شرایط ایده آل سراغ دارید که میتونید برید، که خیلی عالیه!اگر میتونید با شرایط کار کردن بدون حقوق کنار بیاید و مشکل مالی ندارید، میتونید به کارآموزی فکر کنید اما به شرطی که فرصت یادگیری خوبی داشته باشید یا برای خودتون این موقعیت رو بسازید. پس کارآموزی بدون حقوق و بدون امکان رشد کردن = وقت تلف کردناگر جایی که فرصت کارآموزی داره بهتون میده از شما سفته و مدارک برای ضمانت میخواست، عمیقا راجع بهش فکر کنید که بتونید تصمیم درستی بگیرید.اگر فرصت کارآموزی براتون به هیچ طریقی وجود نداشت،‌ به چندجا که دوست داشتید اونجا کار کنید (حتی به رایگان) پیام بدید و سعی کنید با منابع انسانی شون یا تک لید شون صحبت کنید. شاید به شما تونستن این فرصت رو بدن.در نهایت اگر هیچ جوره نشد، سعی کنید با استارتاپ هایی که داخل شتابدهنده ها مستقر هستند ارتباط بگیرید. شانس اینکه اونا شما رو تو تیم خودشون راه بدن خیلی بالاست.چرا بعد این همه مصاحبه، نتیجه نمیگیرم؟ممکنه شما مشکل رزومه نداشته باشید ولی بعد از مصاحبه ها ریجکت میشید. این موضوع دلایل خیلی زیادی میتونه داشته باشه. اول از همه مثبت نگر باشید،‌ خیلی وقت ها مشکل اصلا شما نیستید. صرفا شما برای اون موقعیت مناسب نبودید! شرکت دنبال یک نفر بود که با شرایط خودش همخوان باشه و شما با اون شرایط مطابق نبودید. همش فنی نیست. بعضی وقت ها ممکنه شما از نظر فرهنگی با شرایط اونجا سازگار نبودید. مثلا تصور کنید که شما سیگار می‌کشید ولی هیچکدوم از افراد شرکت سیگاری نیستن (من یه بار دقیقا برای همین یه جا رد شدم). یعنی میتونه دلایل به همین سادگی باشه.از این گذشته، توی جلسه مصاحبه سعی کنید تا جای ممکنه بهترین نسخه خودتون باشه. اشتباه نکنید، منظورم این نیست که ادا در بیارید، منظورم اینه که در عین صداقتی و تواضع سعی کنید خودتونو به بهترین شکل ممکن ارائه بدید.یه سری نکات خیلی کوچیک هست که سعی کنید رعایت کنید،‌ مثلا سر وقت سرجلسه حاضر بشید، خودتونو نسبت به کاری که براش اپلای کردید مشتاق نشون بدید، لبخند بزنید، چیزی که بلد نیستید رو خیلی ساده بگید بلد نیستم! یا نمیدونم! هیچ اشکالی نداره. در کل سافت اسکیل!بعد هم کلا سعی کنید خیلی عمیق مباحثی که مورد نیاز هست رو یاد بگیرید. حفظ نکنید، یاد بگیرید.چه نمونه کار هایی انجام بدم بهتره؟یکی از پر تکرار ترین سوالات همینه، چیزی که میتونم راجع به این بگم اینه همون پروژه های کلیشه ای رو انجام ندید (اپلیکشن Todo و آب و هوا و ...)سعی کنید این پروژه های تستی کار هایی باشن کهشما رو به چالش بکشنبا یک هدف خاص انجام بشن - مثلا تجربه استفاده از zustand یا socket یا extensions و ...کار کنن واقعا و یه کاری انجام بدن - اینطوری نباشه که ناقص انجام شده باشن و یا یه کار مسخره انجام بدنیه مساله دنیای واقعی رو حل کننتکنولوژی های عجیب و غریب و کم کاربرد توشون استفاده نشده باشه که توی هر ۱۰۰ تا پروژه واقعی فقط یه بار به درد بخوره. نمونش کار های جذابی که با three.js انجام میشه ولی تو واقعیت کاربردش خیلی خاص و محدودهاگه شما پروژه تستی پیشنهادی دارید حتما توی کامنت ها بگید و کمک کنید به کسایی که دنبال ایده میگردن.چطور تست نویسی رو یاد بگیرم؟باور کنید، مخصوصا اوایل مسیر کار حرفه ای تون، هیچکس از شما انتظار نداره که تست نوشتن بدونید، حتی شاید بگم تو سطوح بالاتر هم شرکت هایی که این موضوع توی فرایند پیاده سازیشون جا افتاده باشه هنوز اونقدر زیاد نیستند. این اتفاق خوبی نیست و من تاییدش نمیکنم ولی طبق تجربه ام میگم که تست چیزی نیست که شما باید نگرانش باشید.ولی اگر اصرار دارید که تست نوشتن یاد بگیرید، بذارید بهتون یه چیزی بگم و خیالتون رو راحت کنم. کلا تست نوشتن چیزی نیست جز Assertion. یعنی چی؟ یعنی شما یه ورودی داری که اینو بدی به یه تابع/کامپوننت/هرچی انتظار یه خروجی داری: یه عدد، یه رشته، یه چیزی که فلان جور نمایش داده بشه.اینکه چطور اینو انجامش بدی میشه سینتکس و تکنولوژی. چرایی تست رو یاد بگیرید. اینکه اصلا چرا نیازه که تست نوشته بشه؟ چی باید اصلا تست بشه و چرا؟انواع تست ها و کاربرد هاشون رو یاد بگیرید. اینکه شما TDD توسعه بدید خیلی عالیه ولی شرایط شرکت و پروژه و ددلاین و تیم رو نمیشه نادیده گرفت.پس به طور کل خیلی در مورد این موضوع سخت گیری نکنید. برید basic ها رو یاد بگیرید و بقیه اش رو تو مسیر یاد می‌گیرید کم کم.این همه فرانت کار هست، ما شانسی داریم؟به نظرم این سوال اساسا اشتباهه. اول اینکه این احساس شماست که فکر می‌کنید &quot;این همه فرانت کار هست، حالا من چی کار کنم؟&quot; (البته امیدوارم اینطور فکر نکنید). بعد اینکه حتی اگر اینطور باشه، به نظر من اگر شما از نظر فنی و سافت اسکیلی سطح خوبی داشته باشید شانستون از دیگران بالاتر میره. بنابراین نمیشه اول مسیر رو ببینید و بگید خب در مقابل این همه آدم شانسی ندارم پس مسیر رو ادامه نمیدم.مثل این میمونه بگیم این همه سوپرمارکت هست چرا من باید یه سوپر مارکت دیگه بزنم؟ یا این همه کارواش داریم پس من چرا باید یه کارواش دیگه بزنم؟شما برای رسیدن به هدفتون تلاش کنید. کاری به کار دیگران نداشته باشید. دنیا انقدر بزرگ هست که همه کاری برای انجام دادن داشته باشن و کسی بیکار نمونه. قبول دارم شاید بازار کار به اندازه گذشته خوب نباشه ولی دلیل نمیشه ما نا امید بشیم و رها کنیم.برای اینکه شانستون بیشتر باشه، سعی کنید ارزش افزوده داشته باشید. مثال خیلی ساده اینکه چیز هایی رو بلد باشید که احتمال میدید دیگران بلد نباشن. مثلا Docker یا فرایند های CI/CD. اینکه چی بلد باشید بهتره رو شاید بهتر باشه خودتون کشف کنید ولی نکته داشتن یک یا چند چیز به عنوان ارزش افزوده است.البته از حرفم برداشت اشتباه نکنید، مثلا پا نشید برید Three.js یاد بگیرید که کاربردش بسیاااار محدود هست. بله داشتن اون مهارت خیلی عالیه ولی چقدر به کار میاد؟ تو چندتا کسب و کار این تکنولوژی استفاده میشه؟ پس عاقلانه تصمیم بگیرید.آینده کارمون چی میشه؟جواب کوتاه اینه که کسی نمیدونه! ولی مگه چی میخواد بشه؟ یاد بگیرید تغییر کنید و منعطف باشید. بقیه چیزا خودشون حل میشن. تا زمانی که میتونید کاری که خوب بلدید رو انجام بدید و بابتش پول بگیرید، اینکارو بکنید. اگر نیاز شد تغییر کنید، خب تغییر کنید!الگوریتم و ساختمان داده چقدر مهمه؟برای چه کاری؟ ببینید موضوع الگوریتم و ساختمان داده از مباحث پایه ای نرم افزار ها هستند پس اهمیت بلد بودن این چیزا رو خودتون میتونید بفهمید. موضوع اینه که شما هدفتون از یاد گرفتن این چیز ها اینه که بخواید توی مصاحبه ها ازشون استفاده کنید، یا بخواید به عنوان برنامه نویس بهتری فعالیت کنید.در هر دو صورت، یاد گرفتن این موضوعات خیلی میتونه مفید باشه. حالا ممکنه یکی بیاد بگه ما که فرانت کار می‌کنیم برای ما چه اهمیتی داره؟ اتفاقا این موضوع چیزی نیست که محدود به یک سبک کاری یا تکنولوژی باشه، توی هر زمینه ای که کار میکنید میتونه بهتون کمک کنه.کمترین فایده ای که براتون داره همون مصاحبه ها هستند. بماند که اگر خوب درک کنیم این مطالب رو، قطعا روی کیفیت کارمون برای ارائه کیفیت بهتر هم بسیار میتونه برامون مفید باشه.برای یاد گرفتنش هم من سرویس هایی مثل Leetcode و Codewars و Hackerrank رو پیشنهاد میدم. برای شروع جاهای خوبی هستن. کلی هم کتاب و مقاله و ... راجع بهش هست.چه حقوقی رو درخواست بدیم منطقیه؟باز هم یک سوال خیلی سخت! هیچ استانداردی برای این موضوع وجود نداره. یه سیاستی که میشه به خرج داد، مخصوصا اگه اول راه هستیم اینه که توپ رو بندازیم تو زمین طرف مقابل! ببینیم خودشون چه آفری میدن. همه شرکت ها برای نیرویی که میخوان استخدام کنن یه بودجه ای در نظر گرفتن. میتونید اینو بسپرید به خودشون حداقل تو تجربه های اولتون.اشکالی نداره اگر با حقوق کمتر شروع به کار کنید. اما یادتون نره هیچ‌جا با حقوق خییییییلی کم کار نکنید. دیگه در کمترین حالت میشه همون حقوق وزارت کار. اگر شما حاضرید با ماهی ۲-۳ میلیون (خدای نکرده) کار کنید نه تنها به خودتون دارید ظلم می‌کنید بلکه با این شرایط به جامعه شغلیتون هم دارید صدمه می‌زنید.کارفرمایی که عادت میکنه به نیروی کار ارزون، فکر میکنه همه با این قیمت کار میکنن. بنابراین اگه هدفتون کار کردنه یا حقوق منطقی پیشنهاد بدید یا کلا رایگان کار کنید خیلی سنگین تره از حقوق خیلی کم.یه راه دیگه برای پیدا کردن حقوق منطقی اینه که پرس و جو کنید از دور و بری ها و دیگران ببینید با سطوح مختلف اونا شرایط کاریشون چطوری هست. یه رنجی میاد دستتون که تصمیم گیری رو راحت تر میکنه.هیچوقت با کارفرما یا اون شرکت راجع به اینکه دیگران تو سطح شما چقد دارن میگیرن و رنج اونجا با بقیه جاها چقد اختلاف داره، بحث نکنید. این اصلا استراتژی خوبی برای مذاکره راجع به حقوق و مزایا نیست. تمرکز تون رو بذارید روی خودتون. شما چه چیزی دارید که کارفرما باید شما رو استخدام کنه؟ شما چه ارزشی خلق می‌کنید؟ تمرکز رو بذارید روی خودتون به جای توجه به شرایط بقیه جاها.برای افراد با تجربه تر هم که خودتون بهتر میدونید که چقدر پیشنهاد بدید دیگه.دیزاین پترن چی یاد بگیریم؟کلا اینکه باید اینا رو یاد بگیرید یا نگیرید میشه صحبت کرد. اول به یک درک عمیقی از &quot;چرایی&quot; این موضوع برسید و بعد برید سمتش. صرفا اینکه دیزاین پترن یاد بگیرم که خفن تر بشم کافی نیست. شما باید برای استفاده از هر کدوم از این دیزاین پترن ها دلیل داشته باشید. نباید الکی over engineering کنید.دیزاین پترن ها راه حل هایی هستند برای مشکلات یا چالش های رایج. اینکه از کدوم تو چه شرایطی استفاده کنید بستگی به این داره که چقدر تونسته باشید مشکل رو درست تشخیص بدید و با راه حل ارائه شده توسط دیزاین پترن ها مقایسه کرده باشید.برای اینکه یک شمای کلی نسبت به همه شون داشته باشید، چندتا مطلب و ویدئو راجع به هر کدوم ببینید و بخونید که بهتر تو ذهنتون شکل بگیره.چه دوره هایی ببینیم؟دنبال چی هستید؟ برید سراغ یک چیزی که بهتر و راحت تر باهاش ارتباط برقرار می‌کنید. فرقی نمیکنه که چی باشه یا از کجا باشه. هر کسی یه طوری راحت تره. اون راحت تره رو برای خودتون پیدا کنید و همون رو پیش ببرید. پیشنهاد کلی من نسبت به این موضوع که کلا خوندن داکیومنت تکنولوژی ها و ... به طور مستقیم و رسمی هست و یاد گرفتن شون در حین کار.ولی بازم اگه اصرار برای کورس دیدن و ... دارید. تو هر زمینه ای که کار میکنید، یه چرخ بزنید ۱۰۰۰ تا کورس و ... هست. هر کدوم رو چند قسمت ببینید، بعد ببینید با کدوم بیشتر حال می‌کنید. همونو ادامه بدید!مهاجرت کنیم بهتر نیست؟تصمیم برای مهاجرت یک تصمیم کاااملا شخصی هست و انتخاب یا عدم انتخابش به خودتون و شرایط خودتون بستگی داره. بنابراین هیچکس به جز خودتون نمیتونه بهتر به این سوال جواب بده.طبیعتا ممکنه شرایط کاری تون خیلی متفاوت بشه نسبت به چیزی که الان دارید و هستید. این که بر کسی پوشیده نیست. نکته ای که باید حواستون بهش باشه اینه که تفکر های غلط رو بندازید دور. اینکه الان اونجا براتون فرش قرمز انداختن و میرید عشق و حال می‌کنید و ...یا اینکه چون خیلی ها دارن میرن پس ما هم بریم. نه. راجع به چنین تصمیم بزرگی باید عاقلانه فکر کنید و تصمیم بگیرید.چطور تو شرکت های بزرگ کار کنیم؟من قبلا یه مطلب راجع به این موضوع نوشتم در مورد مصاحبه هایی که داشتم با این شرکت ها. اول به این فکر کنید که چرا می‌خواید یه شرکت بزرگ کار کنید. اگه صرفا داشتن اسمش به عنوان یک برند معتبر توی رزومه تون هست که باهاش بتونید بعدا مهاجرت کنید، چیزی که من دیدم این بوده که این موضوع ۵۰-۵۰ هست.من خیلیا رو دیدم بدون داشتم این اسمای بزرگ رفتن و اوکی بودن. خیلی های دیگه هم با سابقه تو این شرکتا رفتن. نتیجه ای که من گرفتم از این موضوع این بوده که بیشتر از اینکه اون اسامی بزرگ توی رزومه تون شما رو ببرن، تجربه ای هست که دارید. حالا میخواد این تجربه توی اون شرکت بزرگ به دست بیاد یا نه.از اینا که بگذریم، چیزی که من متوجه شدم شرکت های بزرگ به دنبالش هستن اینه که شما علاوه بر مهارت های فنی تون، بتونید خوب با تیم شون چفت بشید. بنابراین اگر توی مصاحبه هاشون هم رد شدید،‌ خیلی سخت نگیرید. ممکنه اونا دنبال فردی باشن که فقط با شما متفاوته، نه لزوما از شما بهتر باشه. مثلا من یادمه یه بار برای اینکه سیگار می‌کشم رد شدم! کلا No hard feelingsروی همون موضوع الگوریتم و ساختمان داده و ... تمرکز کنید. وقتی با پروژه های بزرگ طرف هستید همه چیز خیلی جدی تره. دیگه فضا برای اشتباه کمتر میشه. تعهد کاری یه اصل مهم میشه. ارتباط موثر با بقیه داشتن، خیلی پر اهمیت میشه. کار تیمی و فیدبک دادن و گرفتن و کلی سافت اسکیل دیگه.پس کلا برنامه توسعه فردی تون رو جدی تر دنبال کنید. اگه تونستید واردشون بشید که خیلی عالیه! اگه نشد هم فدای سرتون.سافت اسکیل هامون رو چطوری تقویت کنیم؟میتونید کتاب بخونید. یه سری کتاب و پادکست که من خیلی معرفی میکنم برای این موضوع اینا هستن:کتاب Soft Skills: The software developer&amp;amp;#x27;s life manualکتاب Software Engineering at Googleکتاب Software Engineering - The Soft Partsکتاب The Clean Coderپادکست Soft Skills Engineeringپادکست رادیو مرز (البته اصلا ربطی به نرم افزار نداره ولی خیلی روی مهارت Empathy شما تاثیر میذاره)اگه شما هم چیزی میشناسید حتما معرفی کنید توی کامنت ها.علاوه بر این ها، سعی کنید رفتار دیگران رو توی محل کارتون تحلیل کنید (توی ذهنتون). عواقب کار هاشون رو ببینید و درس بگیرید. چه از جنبه مثبت چه از جنبه منفی.همینطور می‌تونید راجع به این موضوع با دوستان و همکاراتون هم مباحثه کنید! مثلا بشینید نیم ساعت راجع به یه شرایط خیالی صحبت کنید که مثلا چه کاری تو چنین موقعیتی بهتره. نظرات مختلف رو بشنوید و سعی کنید بهشون عمیقا فکر کنید.بعد از یه مدتی نتیجه اش رو خودتون توی کار و رفتار و ... می‌بینید.من رشته ام مرتبط نیست، این مهمه؟هم آره هم نه. میتونم بگم که بیشتر بستگی داره. اینکه تو چه سطحی میخواید کار کنید یا تخصصی که میخواید برید سمتش چقدر نیاز به دانش عمیق اکادمیک داشته باشه.من کمتر دیدم افرادی که رشته شون غیرمرتبط بوده ولی مثلا توی موضوع AI یا Data science یا Game development رفته باشن و موفق شده باشن. اگر هم بودن محدود تر بودن.خیلی هارو هم دیدم که با وجود بی ربط بودن رشته شون به نرم افزار بسیار هم موفق عمل کردن.دانشگاه در نهایت اینطوریا هم نیست که به شما هیچ چیز نده. دست کم بهتون یه base خوب میده که یه سری مسائل رو بهتر یاد بگیرید.ولی به طور کل اگر بخوام تجربه ام و مشاهداتم رو بگم، میتونم بگم نه خیلی مهم نیست، گرچه اگر باشه خیلی میتونه مفید باشه.چطوری سنیور بشیم؟راجع به این موضوع من خیلی مفصل قبلا هم تو مطالب ویرگول هم توی لینکدین صحبت کردم. خلاصه بخوام اشاره کنم اینه که راهی مستقیم و سر راستی براش وجود نداره. پیشنهاد میکنم اون موارد رو مرور کنید.البته اینا همه داستان نیستن، ولی میتونن نقطه خوبی برای شروع باشن.در آخر، امیدوارم این مطلب بتونه کمک تون کنه. شرایط سختی هست و باید سعی کنیم به هم کمک کنیم. امیدوارم همه تون بهترین ها براتون رقم بخوره. اگه دوست داشتید میتونید از طریق لینکدین باهام در ارتباط باشید! مخلصیم.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Mon, 29 Jan 2024 09:49:06 +0330</pubDate>
            </item>
                    <item>
                <title>گزارشی از ۱۰۰ جلسه منتورینگ ADPList</title>
                <link>https://virgool.io/@hesanam/%DA%AF%D8%B2%D8%A7%D8%B1%D8%B4%DB%8C-%D8%A7%D8%B2-%DB%B1%DB%B0%DB%B0-%D8%AC%D9%84%D8%B3%D9%87-%D9%85%D9%86%D8%AA%D9%88%D8%B1%DB%8C%D9%86%DA%AF-adplist-m4j9lehvg9ks</link>
                <description>از شهریور ماه پارسال (۱۴۰۱) توی سایت ADPList ثبت نام کردم و به عنوان منتور شروع به فعالیت کردم. با لطفی که دوستان و اطرافیان داشتند تا آخر سال نزدیک به ۷۴ جلسه ست شد و هر جلسه هم حداقل ۳۰ دقیقه طول می‌کشید که این یعنی ۲۲۲۰ دقیقهتوی لینکدین این عکس رو گذاشتم و اعلام کردم که من میرم استراحت و رسیدن به کار و زندگی و تا اطلاع ثانوی دیگه نیستم خدمتتون برای این جلسات مشاوره.تا اینکه سه ماه پیش (مهر ماه ۱۴۰۲) دوباره کرکره رو دادم بالا و گفتم اگه کسی دوست داشت بیاد حرف بزنیم! اکانت ADPList من منفجر شد تقریبا و نزدیک به ۳۰-۴۰ درخواست برام اومد و در نهایت ماه November به عنوان ۱۰ نفر برتر ADP شناخته شدم با ۵۲ جلسه.ادامه پیدا کرد تا دی ماه و مجددا جزو منتور های برتر December شدم ولی من دوباره میرم برای استراحت.تا امروز تعداد جلساتی که رفتم نزدیک به ۱۷۰ تا هست و من میخوام نتیجه این جلسات رو در قالب چند تا پست (شاید)، مشاهداتم رو باهاتون به اشتراک بذارم و باهم نتیجه گیری کنیم.جلسات بی هدفراجع به اون ۷۴ جلسه که سال گذشته داشتم خیلی کامنتی نمیتونم بدم چون فراموشم شده. اما از اون زمان تا الان یکی از مواردی که توی جلسات بعضی اوقات آزار دهنده بوده،‌ جلساتی بوده که انگار Mentee که تایم رو رزرو کرده بود انگار هیچ هدفی برای اینکارش نداشت و صرفا نیاز داشت با یک نفر گپ بزنه.شما این سناریو رو تصور کنید که من وارد جلسه میشم و سلام میدم و حال طرف مقابل رو میپرسم و طرف مقابل هم تشکر میکنه و بعد .... سکوت!خب چرا؟ فردی که یک تایم رزرو میکنه باید برای جلسات آمادگی داشته باشه، اصلا برای چی احساس نیاز کرده که به خودش زحمت عضو شدن و رزرو کردن یک تایم رو داده ولی وقتی وارد جلسه میشه هیچ چیزی برای گفتن نداره و از من میخواد که بحث رو شروع بکنم!لطفا از حرفم برداشت بدی نکنید، من تا جای ممکن حتی با این افراد هم سعی کردم ارتباط برقرار کنم و متوجه بشم چه کمکی میتونم توی اون ۳۰ دقیقه بهش بکنم. اما این مدل رفتار با تمایل فرد Mentee به رشد کردن در تناقضه،‌ چرا که از اول اون فرد احساس نیاز به یادگیری داشته ولی برای اینکارش هیچ هدف و برنامه ریزی ای نداشته که چطور میتونه به بهترین شکل از اون زمان استفاده کنه.و مجددا لطفا از حرفم برداشت بدی نکنید، من ادعا ندارم که زمان من خیلی ارزشمنده و من یه پیرمرد دانا هستم که میتونم به همه چیز جواب بدم پس بنابراین باید افرادی که میان توی جلسه کاملا آماده وارد بشن. حرفم اینه که یک فرد در جایگاه Mentee باید برای زمانی با یک نفر که به نظر خودش میتونه کمکش کنه برای رشد کردن، برنامه ریزی درستی داشته باشه و این وظیفه Mentor نیست که توی ۳۰ دقیقه سعی کنه از طرف مقابل برای کمک کردن بهش دست و پا بزنه.تقریبا توی این ۱۰۰ جلسه این اتفاق با ۴۰ درصد افراد میوفتاد.ابراز قدردانیدوست داشتم راجع به این موضوع هم صحبت کنم، گرچه ممکنه خواسته زیادی باشه اما چیزی بوده که بعضی اوقات آزار دهنده می‌شد. من یک ریال درآمدی از جلساتی که توی این پلتفرم برگزار کردم نداشتم هیچوقت، این یک فعالیت داوطلبانه هست و هیچ یک از افرادی که داخل ADPList فعالیت میکنن انتظار این رو ندارند. بنابراین روی این موضوع که من به خواست خودم پذیرفتم که چنین کاری رو انجام بدم،‌ توافق می‌کنیم.اما با این وجود، افرادی بودند که برای ست کردن این جلسات با یک لحن طلبکارانه ای میومدن و درخواست میدادن یا اگر تایم جلسه مقداری جابجا میشد خیلی شاکی میشدن. البته هیچوقت من برخورد بدی نکردم و با احترام رفتار کردم و عذر خواهی کردم ولی بعضی اوقات این موضوع آزار دهنده بود.البته خیلی ها هم بودن که هم ابتدای جلسه هم انتهای جلسه تشکر می‌کردن که خستگی رو از تن در می‌کرد.افرادی با انگیزه و هدفمندبین تمام این جلسات تعداد انگشت شماری هم بودن که واقعا از هم صحبتی باهاشون لذت بردم و کیف کردم. از اینکه انقدر هدفمند و با انگیزه توی جلسات حاضر بودن و اون سطح بسیار خوبی از Soft skill رو نشون دادن لذت بردم. زمان رو بسیار عالی مدیریت می‌کردن و سوالات بسیار خوبی مطرح کردند.یادم هست با یک دوستی از سوئد ۲ جلسه پشت سر هم داشتم و طوری شد که شبیه یک گفتگوی دوستانه شده بود و برای هر دو طرف مون مکالمه جذاب شده بود و داشتیم از تجربیات همدیگه استفاده می‌کردیم.این جلسات باعث شکل گیری دوستی هایی هم شد که حتی بعد از گذشت یک سال هنوز با هم گپ میزنیم گاه و بیگاه که این خیلی عالیه!دغدغه های تکراریاصلا کسی رو سرزنش یا قضاوت نمیکنم،‌ ولی شاید ۸۰٪ جلساتی که داشتم راجع به چند تا موضوع بود:چی یاد بگیریم؟به نظرتون چرا من پیشنهاد کار نمی‌گیرم؟میشه رزومه من رو بررسی کنید و اشکالاتش رو بهم بگید؟با این همه فرانت-اند دولوپری که توی جامعه هستند به نظرتون اصلا این مسیر درستیه؟چه نمونه کار هایی انجام بدم که شانس مصاحبه رفتنم بیشتر بشه؟آیا کارآموزی برای شروع کار گزینه خوبیه یا نه؟چطور میتونم یه جا به عنوان کارآموز مشغول به کار بشم؟من به تک تک افرادی که چنین سوالاتی رو دارن کمال احترام رو میذارم و دغدغه هاشون رو درک میکنم ولی از یه جایی حس کردم حرفایی که تو هر جلسه به بچه ها میزنم تکراری داره میشه، چون سوالات تکراریه.یکی از اهداف این مطلب که اینجا می‌نویسم جواب دادن به این سوالات هست و استفاده کردن از این مطلب به عنوان یک رفرنس (مرجع) برای افرادی که چنین سوالاتی دارن که البته تو یک مطلب مستقل مفصل بهش اشاره میکنم.احساس مسئولیتدوست دارم راجع به احساسی که خودم در مورد این سوالات داشتم بیشتر صحبت کنم، از طرفی این من رو ناراحت می‌کرد که میدیدیم این همه آدم با این دغدغه ها تنها خواسته ای که دارن یک مقدار اعتماد از جانب شرکت ها/بیزنس ها هست برای اینکه بهشون فرصتی بدن که بتونن خودشونو نشون بدن و من کاری از دستم بر نمیاد جز راهنمایی کردن شون.از طرفی میدیدم که بعضی از Mentee ها اعتماد به نفس خیلی بالایی داشتن راجع به موضوعاتی که نمیدونستن ولی فکر می‌کردن که میدونن و نشون میداد که چقدر عجول هستند! بعنوان مثال خیلی دیدم افرادی که هنوز ۶ ماه از زمانی که آموزششون شروع شده بود نگذشته بود ولی انتظار داشتن وارد شرکت های بزرگ بشن و کار کنن. البته منظورم این نیست که امکان پذیر نیست ولی باید واقع بین بود و صبور.بعضی از این افراد حتی حاضر بودن رایگان، فقط برای کسب تجربه هم که شده،‌ شروع به کار کنن. این همه فرصت هست برای شرکت های حوزه نرم افزار که از این پتانسیل استفاده کنن ولی متاسفانه میبینیم که اقبال شرکت ها به سمت افرادی هست که حداقل ۱-۲ سال سابقه کار دارن. خب این سابقه از کجا باید شروع بشه؟ پس حس اعتمادتون کجا رفته؟البته نه اینکه از این افراد صرفا استفاده کنید (اونم رایگان) بلکه بهشون میدون بدید و بهشون اعتماد کنید تا ببینید جواب اعتمادتون رو چطور میدن.بعضی از دوستان برای آموزششون کلی هزینه کرده بودن،‌ بعضی ها به عنوان کارآموز وارد شرکت هایی شده بودن که بعد اینکه کارشونو انجام داده بودن باهاشون خداحافظی کردن، بدون هیچ حقوق و مزایایی. این خیلی بی انصافیه که از سادگی افراد سو استفاده کنید.خارج از پایتختچند نفر رو یادمه که کار های خییلی بزرگی کرده بودن ولی به خاطر اینکه ساکن تهران نبودن، فرصت هایی که داشتند بسیار محدود بود. در حین حال کاری که داشتند توی شهر خودشون برای شرکت شون انجام میدادن رو اگر توی تهران انجام میدادن درآمد به مراتب بالاتری داشتند. البته منکر هزینه های تهران نشینی نمیشم ولی اینکه دیدم افرادی در این حد و اندازه با استعداد هستند ولی به خاطر شرایط جغرافيایی مجبور هستند با اون شرایط کار کنن،‌ ناراحت کننده بود.البته دیدم خیلی از افرادی هم که به خاطر اینکه صرفا ساکن تهران نیستن، کلا به ادامه مسیر هیچ امیدی نداشتند و تا حدودی هم درست فکر میکردن چون انقدر تمرکز روی تهران برای کار های Tech زیاد هست که واقعا شهر های دیگه سهم خیییلی کمتری توی فرصت های کاری دارن. من چه پیشنهادی میتونستم به این افراد بکنم؟ مهاجرت کنن تهران؟ امید خودشونو از دست ندن؟ شاید فرجی بشه؟ چی بگم والا....شما ایده ای داری؟کار ریموت؟یه سوال خیلی جالبی که دریافت می‌کردم، این بود که چطور کار ریموت پیدا کنیم؟ راستش برای من جواب دادن به این سوال کار مشکلی هست چون من تا حالا هر موقعیت ریموتی هم که تونستم به دست بیارم،‌ این شکلی بوده که من به صورت active کاری براش انجام ندادم و اون افراد خودشون اومدن و به من پیشنهاد همکاری دادن و اینطوری بوده که کارمون انجام شده.ولی چیزی که این سوال رو برام جالب میکنه اینه که چرا افرادی با تجربه های خیلی کم براشون از الان این موضوع دغدغه هست؟ از حرفم اشتباه برداشت نکنید، خوبه که آدم هدف داشته باشه و برای هدفش تلاش کنه اما بیاید با هم صادق باشیم: به ندرت پیدا میشن افرادی با تجربه کمتر از ۲-۳ سال که تونستن کار ریموت به دست بیارن با شرایط پرداخت دلاری و ...پس چیزی که میتونم بگم اینه که مجدد این سرچشمه اش از عجول بودن آدماست. برای بدست آوردن چنین موقعیت هایی علاوه بر مهارت های ارتباطی و زبان و کلی چیز غیر فنی دیگه، نیازه که شما تجربه خیلی بالایی نسبت به تکنولوژی ای که کار میکنین داشته باشین. پس فکر اینکه با ۶ ماه کار کردن بتونید همچین کاری انجام بدید رو کاملا از سرتون بیرون کنید! (من بی رحم و مغرور نیستم، فقط واقع گرا هستم)سوالات فنیچند باری شد که توی جلسات، فرد Mentee شروع کرد به پرسیدن سوال فنی که مثلا من فلان جا یه ارور دارم و چجوری اینو حلش کنم؟ یا کانفیگ فلان چیز رو نمیدونم چطوری باید درست کنم که خوب کار کنه.جالب تر اینجاست که از زمانی که اون فرد برای روز و ساعت انتخابیش درخواست رو ثبت میکنه، تا من تایید کنم و بریم جلسه به طور میانگین حداقل ۴-۵ روز طول می‌کشه! واااقعا توی این تایم و قبلش این مشکل رو نمیشد حل کنید؟؟؟از این که بگذریم، این جلسات در بازه های نیم ساعته برگزار میشن، زمانی نیست که من بتونم کد رو بخونم و متوجه ایرادش بشم و بتونم حلش کنم، از طرفی اصلا هدف این جلسات این مسائل نیست! برای اینطور چیز ها گوگل و ChatGPT و Stackoverflow و کلی چیز دیگه هستند!جمع بندیبه نظرم در آخر اگر بخوام از نتیجه این مدت که توی ADPList فعالیت داشتم بگم، میتونم بگم شاید هنوز خیلی فرهنگ Mentorship توی جامعه برنامه نویسی ما به شکلی که باید باشه هنوز جا نیوفتاده. جواب خیلی از سوالاتی که پرسیده میشد رو راحت میشد جستجو کرد، موارد فنی رو میشد خیلی راحت حل کرد.عموما در حالت درست، Mentor به شما سعی میکنه مسیر رشد حرفه ای رو بگه،‌ سوالات هم باید توی همون راستا باشن. درسته که سوالاتی که قبل تر بهشون اشاره کردم یه طورایی حول محور همین موضوع هستند ولی میزان دغدغه مندی و جنس سوالات،‌ اکثرا چیزی نبودن که بشه با یه جلسه نیم ساعته حلشون کرد. خیلی از حرف هایی که من میزدم بار ها و بار ها توسط افراد دیگه بهشون پرداخته شده و حتی خیلی بهتر و با جزییات بیشتر.از طرفی فرایند Mentorship یه فرایند دنباله دار هست، یعنی یک نفر به عنوان Mentee شاید باید چند جلسه در بازه های مشخص (مثلا هر ۱-۲ ماه) شرکت کنه تا شاید به نتیجه مطلوب برسه. شاید تو کل این جلسات ۳-۴ نفر بودن که این شکلی پیش می رفتن و برمیگشتن تا بحث رو ادامه بدیم.در کل منظورم اینه که شاید بهتر باشه برای یه جلسه نیم ساعته یا حتی ۱ ساعته، سوالاتی پرسیده بشه که اشاره داشته باشه به تجربه اون شخص Mentor در جاهایی که قبلا کار کرده یا تجربیاتی که داشته. چیزی که توی اینترنت نشه به راحتی پیدا کرد.خیلی از من سوال میشد در مورد Roadmap، خب اگر منظور مسیر فنی باشه که روی اینترنت خیلی زیادن این مسیر ها نمونش هم اینجا. شاید سوال درست تر این باشه که این مسیر با توجه به هر شخص و با در نظر گرفتن شرایط اون شخص Mentee چطور باید باشه.دمتون گرم اگر تا انتهای مطلب رو خوندید، اگر دوست داشتید راجع به این موضوع بیشتر صحبت کنیم میتونید از طریق لینکدین باهام در تماس باشید، توی مطلب بعدی سعی میکنم یه مجموعه از سوالاتی که خیلی پرتکرار بودن رو جواب بدم، مطمئنم که دغدغه خیلی هاست و مورد استقبال قرار می‌گیره.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Wed, 03 Jan 2024 09:43:44 +0330</pubDate>
            </item>
                    <item>
                <title>چرا SASS ؟</title>
                <link>https://virgool.io/@hesanam/%DA%86%D8%B1%D8%A7-sass-zj56loxt2vth</link>
                <description>چند روز پیش یک مطلبی خوندم راجع به CSS که قابلیت nesting رو پشتیبانی میکنه و نویسنده مطلب گفته بود که با این حال دیگه چه نیازی داریم به Sass؟تو مطلب اشاره شده دلایل اصلی استفاده از SASS به خاطر قابلیت nesting و variable ها بودن که قبلا توی CSS این موارد وجود نداشت که ما رو مجبور به استفاده از SASS می‌کرد و حالا که خود CSS قابلیت nesting رو اضافه کرده پس دلیلی نداره بازم از اون استفاده کنیم.بعد خوندن این مطلب اول خیلی هیجان زده شدم به خاطر این قابلیت جدید CSS چون به نظرم واقعا خوبه!! دوم به فکرم زد که یه مطلب بنویسم و توضیح بدم چرا همچنان برای پروژه هایی با ابعاد بزرگ همچنان Sass یک گزینه غیر قابل جایگزین هست.البته که این مطلب نمیتونه به تمام وجه های موضوع بپردازه ولی به نظرم یه نقطه شروع خوب میتونه باشه برای اینکه با قابلیت های خفن و ناب Sass بیشتر آشنا بشیم و بدونیم چرا میتونه ابزار خیلی خوبی باشه برامون.نکته مهمی که در حین خوندن این مطلب نباید فراموشش کنیم این هست که این مطلب قرار نیست به شما اطلاعات کاااااملی راجع به موضوع بده. صرفا تجربیات من و پروژه هایی که توشون کار کردم هست راجع به اینکه چطور از Sass میتونیم استفاده کنیم. اگه میخواین بیشتر بدونین حتما از داکیومنت خود Sass و منابع دیگه استفاده کنین.برای اینکه موضوع خیلی بهتر انتقال داده بشه من یه ریپو روی گیت درست کردم که اینجا میتونید ببینید: https://github.com/hesan-aminiloo/why-sass همچنین یه لینک StackBlitz هم دارم که میتونید همه چیو آنلاین ببینید که لازم نباشه کلون کنید و این داستانا (میدونم شما هم مث من حال اینکارا رو ندارید 😉) https://stackblitz.com/~/github.com/hesan-aminiloo/why-sass  https://stackblitz.com/~/github.com/hesan-aminiloo/why-sass قابلیت های کلیهمه راجع به اینکه میشه توی Sass از متغیر ها و Nesting استفاده کرد خبر داریم و روی این موضوع توافق داریم. همچنین Partial ها (همون که تو هر فایل میتونیم فایل های Sass دیگه رو import کنیم) هم که میدونیم. پس اینجا راجع به این چیزا صحبتی نمیکنم.البته میدونیم که توی Sass میشه از Mixin ها و Function ها هم استفاده کرد که توی CSS امکانش وجود نداره اما اینکه چطور و چرا رو من میخوام تجربه خودم رو بگم.با Function هاکاربرد توابع با چیزی که قبلا مثلا توی JS استفاده میکنیم خیلی تفاوتی نداره ولی توی Sass برامون چه کار هایی میتونن انجام بدن؟ من سعی کردم با ساده ترین مثالی که میشه زد این موضوع رو توضیح بدم: https://gist.github.com/hesan-aminiloo/db619ee49cded0415eb6d2bc1066a986 آدرس این فایل توی پروژهیکی از ساده ترین کار هایی که میتونیم انجام بدیم تبدیل کردن تایپ رنگ هاست. اینجا ما یک رنگ با فرمت HEX دریافت میکنیم و با فرمت RGBa برمیگردونیم. البته خیلی هم کار پیچیده ای نیست همینطور که میبینید. ولی بسیار کاربردی میتونه باشه.اینطور که مثلا شما رنگ های دیزاین سیستم تون بر اساس hex هست و نمیخواین دردسر تعریف کردن کلی متغیر رنگ دیگه برای حالت rgb اش رو بکشید، خیلی ساده میشه از این تابع استفاده کرد.یا مثلا میشه حتی فقط اعداد رنگ ها رو برگردوند و برای تعریف css variable های global ازشون استفاده کرد و مقدار alpha رو داینامیک کرد.توی پروژه این قسمت صفحه رنگ هاش تبدیل شده hex به rgb هست که میتونید کدش رو چک کنیدبا Mixin هاخب قابلیت mixin رو که میدونیم، شما میتونید یه تیکه از استایل تون رو reusable کنید، حتی پارامتر بدید و حالت داینامیک داشته باشید. یه نمونه از mixin ها ببینیم: https://gist.github.com/hesan-aminiloo/f05a78ab9c47c44bae6522572792ce27 اینجا mixin بالایی به ما این قابلیت رو میده که هرجا نیاز داشتیم که scrollbar ها رو مخفی کنیم خیلی ساده ازش استفاده کنیم و mixin بعدی کلا محتوای داخلش به کمک @content داینامیک هست! این مدلی هم استفاده اش میکنیم: https://gist.github.com/hesan-aminiloo/72de3a87202e785f4209384178ba9e70 آدرس این فایل توی پروژهدیگه موقع اسکرول کردن scrollbar مخفی میشه - که خروجیش رو پایین میتونید ببینید. توضیح خیلی خاصی نداره اینجا واقعا. کلا هرجا که احساس کردید یه چیزی خیلی داره تکرار میشه میتونید برای جلوگیری از تکرار کد ها از mixin ها استفاده کنید دیگهبا Mixin به همراه Loop هاحالا اگه بخوایم reusability رو بالاتر ببریم و مثلا بخوایم طبق یک دیزاین سیستم همه حالت هال مختلف یک button رو طراحی کنیم میتونیم همه variant های مختلفی که داریم رو توی یک لیست درست کنیم و بعد روش یه loop بزنیم و استایل هاش رو خیلی ساده به کمک mixin ها بسازیم: https://gist.github.com/hesan-aminiloo/3a8ee109c64b7d64c5364001eb5d06d6 آدرس این فایل توی پروژههمینطور که میبینید اول همه رنگ ها رو توی یک لیست تعریف کردیم و بعد به کمک حلقه each روی این لیست بچرخیم و به ازای هر کدوم از حالت هایی که داریم یه کلاس جدید بسازیم.نحوه استفاده اش رو اینجا میتونید ببینید. ولی خیلی ساده است - در واقع هر کدوم از رنگ های این badge ها یک modifier هستند (از متد BEM استفاده شده)خروجی مون در نهایت این شکلیه:با export: و متغیر ها توی JSخیلی وقت ها لازمه که متغیر هایی که توی Sass داریم رو توی JS هم استفاده کنیم. خب نمیشه که یکبار همه چیز رو توی Sass و یکبار دیگه توی JS تعریف شون کرد... کد تکراری؟؟یه کاری که میتونیم بکنیم اینه: https://gist.github.com/hesan-aminiloo/309bda5740256a29ac6e91c78ca4c4be توی یک فایلی مثلا variables.scss به کمک export: خروجی میدیم از رنگ هایی که داریم که متغیر های css رو بسازیم، بعد میتونیم این فایل رو توی یک css ماژول import کنیم: https://gist.github.com/hesan-aminiloo/458146680ead1a7767d70e48e94ab906 و تو مرحله بعد توی فایل JS مون import شون کنیم https://gist.github.com/hesan-aminiloo/65027b9db615f977ca7de77d8823e7ce و خب دیگه حالا میتونیم خیلی راحت ازشون توی JS هم استفاده کنیم: https://gist.github.com/hesan-aminiloo/047d10bf6d8076c2ce80e3297ca40729 شاید یکم پیچیده شد، اگه من جایی اشتباه کردم هم بهم بگید حتما.فایل های این قسمت پروژه رو میتونید اینجا ببینید.در نهایت خروجی ما برای این قسمت هم این شکلی میشه:تو این مطلب سعی کردم خیلی کلی راجع به بعضی از قابلیت های کوچیک Sass صحبت کنم. قطعا که این تمام داستان نیست. برای پروژه هایی با ابعاد خیلی بزرگ میتونه قدرتشو خیلی بهتر هم نشون بده. کلا اصلا طوری نیست که بشه دست کم گرفتش. من اینجا سعی کردم با مثال های خیلی ساده نشون بدم که چه پتانسیل هایی داره و Sass فقط Nesting و Variable نیست!خروجی کلی مااگه مشکلی یا نکته ای توی مطلب بود حتما بهم توی بخش کامنت ها بگید و اگه هم دوست داشتید باهم گپ بزنیم میتونید از طریق لینکدین باهام در تماس باشید.</description>
                <category>حسان امینی لو</category>
                <author>حسان امینی لو</author>
                <pubDate>Thu, 28 Dec 2023 12:28:20 +0330</pubDate>
            </item>
            </channel>
</rss>