<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد محمدعلیان</title>
        <link>https://virgool.io/feed/@MohammadAlian_1383</link>
        <description>یه ممد 21 ساله که برنامه‌نویس بک-انده. لینکای من: https://redl.ink/Mohammadalian_1383</description>
        <language>fa</language>
        <pubDate>2026-06-07 10:39:21</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/28841/avatar/nmtigH.png?height=120&amp;width=120</url>
            <title>محمد محمدعلیان</title>
            <link>https://virgool.io/@MohammadAlian_1383</link>
        </image>

                    <item>
                <title>اول زیرساخت رو بساز</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%A7%D9%88%D9%84-%D8%B2%DB%8C%D8%B1%D8%B3%D8%A7%D8%AE%D8%AA-%D8%B1%D9%88-%D8%A8%D8%B3%D8%A7%D8%B2-f8hwqrzcfpfr</link>
                <description>بعد از یه دوره طولانی سلام ??چند وقتی بود که حس عقب موندگی زیادی از دنیا رو حس می‌کردم و خیلی دنبال راه حل های سریع‌السیر برای رسیدن به حداقل های زندگیم بودم، مثلا می‌خواستم سریع پولدار بشم!البته که می‌دونم تنها نیستم و خیلیا دنبال این موضوعن متاسفانه، به خصوص که انقدر داره ارزشمند و راحت جلوه داده میشه توی رسانه‌ها ☹️ بعد از یه مدت تلاش و صحبت کردن با بقیه افرادی که بنظرم سریع پولدار شده بودن دیدم نه اونقدرام شاید سریع نبوده و نیاز به یه تجدید نظر تو این باورم داشتم ?تزئینی می‌باشد :)نهایتا بعد از چند تلاش ناموفق در راستای این روش‌های فست‌فودی (سریع‌السیر) به خودم اومدم و دیدم که این افرادی که بنظر می‌رسه توی مدت کمی تونستن به هدف ارزشمندی دست پیدا کنن یه سری زیرساخت داشتن که یه زمانی استفاده ازش خیلی پول‌ساز شده.اما منظورم از زیرساخت چیه؟بخوام یه سری هم‌معنی بگم براش، کلمات «پیش‌نیاز» و «زمینه» بنظرم مناسبن و حق مطلب رو ادا می‌کنن.یعنی یه سری چیزا که برای رسیدن به یه هدفی لازمه ولی چون توی حاشیست و اصل داستان نیست بهش به اندازه کافی توجه نمی‌کنیم.خود اون زیرساخته شاید خیلی به تنهایی آورده زیادی برامون نداشته باشه ولی در ترکیب با یه سری چیزای دیگه ارزش واقعیش رو نشون میده. بخوام مثال بزنم می‌تونم به زبان انگلیسی، ارتباطات و حساب بانکی بین‌المللی و حضور آنلاین اشاره کنم.مثال ترکیبی زیرساخت و یه مهارت اصلی زبان انگلیسی + مهارت برنامه‌نویسی + حساب بانکی بین‌المللی = کار تمام وقت خارجی و درآمد دلاری ماهانه  مهارت برنامه‌نویسی + ارتباطات خوب = پروژه هایی با رقم بالا ?مهارت برنامه‌نویسی + حضور آنلاین = شناخته شدن و ساخت برند  ?البته فقط محدود نمی‌شه به همین مواردی که گفتم، چیزی که به عنوان «مهارت‌های نرم» یا به قول آقای سایمون سینک «مهارت‌های انسانی» می‌شناسیم هم توی کار روزمرمون به طور مثال به عنوان یه زیرساخت برای رشد در سازمان به حساب میاد.توصیه خودم به افراد زیر ۲۰ سالبا توجه به این نکاتی که توی بالا گفتم بنظرم این سنین خیلی زمان خوبین برای زمان گذاشتن روی زیرساخت‌ها و البته که قرار نیست توی سنین بالاتر زمان نذاریم برای ساخت زیرساخت‌های لازممون برای رفتن به پله بعدی ولی توی این بازه سنی زیرساخت‌های نساخته‌ی خیلی زیاد و گسترده‌ای داریم که زمان هم به اندازه کافی برای ساختشون داریم ✌️نکته خیلی مهم: این چیزی که توی این مطلب خوندید بخشی از تجربه و درک شخصی من از این دنیا بود، نمی‌دونم پایه علمی داره یا نه ولی اگه نداشته باشه آگاه باشید که قرار نیست شما هم با پیاده‌سازی این روش نتیجه مثبت بگیرید لزوما.محمد محمدعلیان − ۲۷ اسفند ۱۴۰۱</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Sat, 18 Mar 2023 20:35:54 +0330</pubDate>
            </item>
                    <item>
                <title>الگوریتم TF-IDF یا بصورت پیش‌فرض چطوری Elasticsearch تصمیم می‌گیره کدوم رکورد مرتبط تره؟</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-tf-idf-%DB%8C%D8%A7-%D8%A8%D8%B5%D9%88%D8%B1%D8%AA-%D9%BE%DB%8C%D8%B4-%D9%81%D8%B1%D8%B6-%DA%86%D8%B7%D9%88%D8%B1%DB%8C-elasticsearch-%D8%AA%D8%B5%D9%85%DB%8C%D9%85-%D9%85%DB%8C-%DA%AF%DB%8C%D8%B1%D9%87-%DA%A9%D8%AF%D9%88%D9%85-%D8%B1%DA%A9%D9%88%D8%B1%D8%AF-%D9%85%D8%B1%D8%AA%D8%A8%D8%B7-%D8%AA%D8%B1%D9%87-fyewuyacae5w</link>
                <description>سلام ?شاید برای شما هم این سوال وجود داشته باشه که Elasticsearch یا سایر ابزار های جستجو، چطوری تصمیم می‌گیرن که کدوم نتیجه بیشترین ارتباط رو با کلمه‌ی مورد جستجو داره ?یکی از راه‌ها برای رسیدن به این هدف، استفاده از الگوریتم TF-IDF هستش که قراره توی این مطلب، اون رو خیلی خلاصه توضیح بدم و یه نمونه از پیاده‌سازیش رو با هم ببینیم.TF-IDF = Term Frequency Inverse Document Frequencyاین الگوریتم، بر اساس دفعات تکرار کلمه توی متن به اون یه امتیازی رو اختصاص میده، هرچی اون امتیاز بیشتر باشه یعنی اهمیت اون کلمه بیشتره.حالا Term Frequency یعنی چی؟یعنی چقد اون عبارت مورد جستجوی کاربر توی document تکرار شده و هرچی این عدد بیشتر باشه یعنی مرتبط تره.و Inverse Document Frequency یعنی چی؟یعنی چقد عبارت مورد جستجوی ما توی همه‌ی document ها تکرار شده و هرچی این عدد بیشتر باشه یعنی بی ربط تره نتیجه جستجو.مثالفرض‌کنید می‌خوایم نام محمد رو جستجو بکنیم، کلمه‌ی محمد توی یه متن 500 کلمه‌ای 10 بار تکرار شده پس TF کلمه‌ی محمد میشه 500 / 10 = 0.02حالا اگه بخوایم IDF رو حساب بکنیم نیازه که بدونیم کلا چندتا document داریم که شامل کلمه‌ی محمد هستن. اگه تعداد کل document های ما 100.000 تا باشن و کلمه‌ی محمد توی 20.000 تا از این داکیومنتا باشه مقدار IDF میشه 20.000 / 100.000 = 5و در نهایت TF-IDF ما میشه =&gt; 5 * 0.02 = 0.1حالا بیاید یه مورد دیگه رو بررسی کنیم، فرض کنید کلمه the توی یه داکیومنت 500 کلمه‌ای 100 بار تکرار شده و از 100.000 تا داکیومنتمون توی 80.000 تاش هست.اینجا TF میشه =&gt;  500 / 100 = 0.2و IDF میشه =&gt; 80.000 / 100.000 = 1.25و TF-IDF میشه =&gt; 1.25 * 0.2 = 0.25حالا فرض کنید که کلمه‌ی محمد حسین رو جستجو کردیم، اینجا چه اتفاقی میوفته؟برای هر کدوم از کلمات به صورت جداگونه TF-IDF محاسبه میشه و نتیجشون جمع میشن با هم و هر داکیومنتی که score بیشتری داشت به عنوان اولین نتیجه بر گردونده میشه.در نتیجه اگه مثلا عبارت The New Age رو جستجو بکنیم تاثیر عبارت The توی نمره خیلی کم خواهد بود، چرا؟ چون این عبارت تقریبا توی همه داکیومنت ها به تعداد زیادی وجود داره، امتیاز پایینی میگیره و به همین دلیل تاثیر کمی هم داره.یه پیاده‌سازی خیلی ساده از این الگوریتم رو نوشتم، که می‌تونید ببینید (اگه کد رو نمی‌بینید فیلترشکنتون رو روشن کنید و صفحه رو رفرش کنید، کد داخل gist هستش و بعضی وقتا gist با فیلترشکن باز میشه فقط) https://gist.github.com/mhmda-83/830522209728be8fac39bc1287109176 اگه می‌خواید بیشتر راجع به این الگوریتم بدونید می‌تونید از لینک‌های زیر استفاده کنید ?WikipediaMonkey Learnممنون از اینکه وقت گذاشتید و خوندید ?محمد محمدعلیان - 5 شهریور 1400 نوشته شده! و 30 اردیبهشت 1401 منتشر شده.کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Fri, 20 May 2022 19:18:15 +0430</pubDate>
            </item>
                    <item>
                <title>وب‌هوک(Webhook) چیه؟ + بررسی یه مثال عملی</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D9%88%D8%A8-%D9%87%D9%88%DA%A9webhook-%DA%86%DB%8C%D9%87-%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%DB%8C%D9%87-%D9%85%D8%AB%D8%A7%D9%84-%D8%B9%D9%85%D9%84%DB%8C-znyismdkixbj</link>
                <description>سلام، اگه سابقه توسعه ربات تلگرام رو داشته باشید یکی از مفاهیمی که احتمالا درگیرش بودید وب‌هوک هستش اما واقعا این وب‌هوک چیه؟ روش جایگزینی نبوده؟ به غیر از توسعه ربات تلگرام کجا ها استفاده میشه؟زمانی که یه سرویس خارجی (سرویسی که شما توسعش ندادید) رو استفاده می‌کنید و می‌خواید از تغییراتی که اون سمت ایجاد میشه مطلع بشید چه کارهایی می‌تونید بکنید؟ یکی از گزینه ها Polling هست و یکی دیگه از گزینه ها WebhookPollingتوی توسعه ربات تلگرام یه API وجود داره که مسیرش(path) getUpdates هست و لیست اتفاقات جدیدی که از سمت یوزر ها با ربات افتاده(مثل استارت کردن ربات، ارسال یه عکس یا ...) رو داخل یه آرایه بهمون بر می‌گردونه و بر اساس اون ما می‌تونیم تصمیم بگیریم که چه پاسخی رو به کاربر بدیم.اما یه سوال، هر چند وقت یکبار باید به این API ریکوئست بزنیم؟ اگه فقط یکبار بزنیم فقط آپدیت‌ها رو تا اون لحظه‌ای که ریکوئست زدیم داریم، پس نیازه که توی یه بازه زمانی مشخص درخواستامون رو به سرور های تلگرام ارسال کنیم، مثلا هر ۵ ثانیه یک‌بار.اما حالتی رو تصور کنید که ساعت 15:00:05 هست و ما یه درخواست فرستادیم برای تلگرام و درخواست بعدیمون قراره ساعت 15:00:10 باشه، تکلیف کاربری که توی ثانیه 6 یه عملیاتی رو توی ربات انجام میده چیه؟ هیچی! باید تا ثانیه 10 صبر کنه تا تازه تصمیم بگیریم چیکار کنیم براش :(اینجاست که روش Webhook میاد که بهمون یه راه حلی رو عرضه کنه.Webhookروش قبلی توی دنیای واقعی مثل این بود که شما یه گمشده‌ای داشته باشید و هر چند وقت یک‌بار تماس بگیرید با افراد و بگید خبر جدیدی نشد؟اما وب‌هوک یعنی به اون شخص اطلاع بدید که دنبال چی هستید و بگید به محض اینکه خبری گرفت به اون شماره تلفنی که بهش میدید زنگ بزنه و خبر بده.مثلا توی مورد تلگرام یه API با مسیر /setWebhook وجود داره که یه URL رو ورودی می‌گیره تا هر اتفاق جدیدی که میوفته رو به اون URL در قالب یه POST Request اطلاع بده.پس برای اینکه از Webhook استفاده کنیم قدم اولش اینه که اون سرویس خارجی‌ای که قصد داریم ازش استفاده کنیم این امکان رو بهمون بده که اکشن هایی که از سمت کاربر استفاده کنندش انجام میشه رو به آدرسی که می‌گیم ارسال بکنه.مثال عملیگیت‌هاب یکی از سرویس هاییه که از Webhook پشتیبانی می‌کنه و باهاش می‌تونید تغییراتی که روی ریپازیتوریتون ایجاد میشه رو ببینید.اگه آدمی هستید که خیلی حوصله داکیومنت خوندن ندارید و می‌خواید ببینید چه دیتاهایی رو اون سرویس براتون ارسال می‌کنه یه وب‌سایت ساختن برامون به اسم webhook.site که یه URL می‌ده تا بدیم به سرویس مورد نظرمون و اون اطلاعات رو به این آدرس ارسال بکنه و می‌تونیم جزئیات ریکوئست ارسال شده رو ببینیم :)همونطور که توی تصویر بالا مشخصه توی تنظیمات ریپازیتوری های گیت‌هاب یه قسمت Webhooks وجود داره که میشه آدرسی که مد نظرمون هست برای ارسال تغییرات رو وارد کنیم.همه‌ی جزئیات تصویر بالا تقریبا از اسمشون مشخصه که کارشون چیه ولی اون پارامتر secret چیه؟بذارید یه سوال بپرسم تا جواب سوال بالا مشخص بشه! اگه یکی آدرسی که ما به عنوان گیرنده webhook ایجاد کردیم رو پیدا بکنه چه اتفاقی میوفته؟ می‌تونه هر دیتایی که می‌خواد برامون بفرسته و باعث اختلال توی روند کارکرد سیستممون بشه. پس باید یه روشی رو بهمون بده اون سرویسی که webhook رو پشتیبانی می‌کنه تا ما بتونیم با یه درصد قابل قبولی اطمینان پیدا کنیم که سرویس ما فقط از سمت اون سرویس فراخوانی شده.که اینجا گیت‌هاب بهمون Secret رو میده که نحوه کارش رو می‌تونید اینجا بخونید. تلگرام هم توی این داکیومنت توضیح میده که چطوری مطمئن بشیم درخواست از سمت سرورای تلگرام اومده.حالا اگه یه اکشنی انجام بدم توی اون ریپازیتوری (مثل star کردن) یه ریکوئست برام به اون آدرسی که مشخص کردم ارسال میشه و توی body اون ریکوئست اطلاعات تغییرات موجوده. (مثل تصویر زیر)مرسی ازتون که زمان گذاشتید و خوندید ?مطالعه بیشترWebhooks for Beginners - Full Courseمحمد محمدعلیان | 23 اردیبهشت 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Fri, 13 May 2022 20:51:55 +0430</pubDate>
            </item>
                    <item>
                <title>مقدمه‌ای بر HTTP Caching</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D9%85%D9%82%D8%AF%D9%85%D9%87-%D8%A7%DB%8C-%D8%A8%D8%B1-http-caching-bdxtopl28uef</link>
                <description>وقتی راجع به کش کردن با یه بک‌اند دولوپر صحبت می‌کنید عمدتا فکرشون میره سمت ذخیره کردن دیتاهایی که زیاد تغییر نمی‌کنن توی RAM و استفاده از ابزارهایی مثل Redis.ولی چرا به این فکر نمی‌کنیم که اگه API هایی که توسعه می‌دیم قراره یکی از کلاینتاش مرورگر کاربرامون باشه بیایم و از حافظه Cache مرورگر استفاده کنیم؟هدر Cache-Controlمقدار این هدر مشخص می‌کنه که مرورگر ما با اطلاعاتی که دریافت می‌کنه به لحاظ کش کردن چطوری رفتار بکنه و مهم نیست که این اطلاعات از نوع تصویر، ویدیو، JSON، HTML یا .... باشه. همه رو میشه کش کرد.البته به لحاظ فنی فقط مرورگر نیست و این هدر توی لایه Proxy Server هم می‌تونه کش رو انجام بده.یه مثال ببینیمتوی عکس زیر یه وب‌سرور Node.jsی داریم که قراره یه JSON برگردونه و همچنین هدر Cache-Control با مقدار private, max-age=60 هم داره که یعنی این صفحه رو روی مرورگر شخص و نه سرور پراکسی تا ۶۰ ثانیه کشش کن!توی درخواست اول همونطور که توی تصویر زیر مشخصه ریکوئست به سرور اصلی (origin server) اومده و لاگ request received هم چاپ شده.اما توی درخواست دوم ریکوئستی به سرور ما نیومده و ریسپانس کاربر از دیسک واکشی شده!یه نکته‌ای که باید در نظر داشته باشید اینه که مرورگر موقع رفرش صفحه داخل request header ها مقدار cache-control: max-age=0 رو تنظیم می‌کنه که باعث میشه از کش خونده نشه ولی اگه یه تب جدید باز کنید و یا از fetch استفاده کنید برای لود کردن اون مسیر از کش استفاده میشه.توی این مثال ما چی به دست آوردیم؟ ذخیره کردن قدرت پردازشی سرور با نیومدن ریکوئست بهش، ذخیره کردن پهنای باند.اما لایو بودن دیتامون رو از دست دادیم.مرورگر به صورت پیش‌فرض تلاش می‌کنه چیزهایی که دریافت می‌کنه رو کش کنه. یه سری هدر ها وجود دارن برای بررسی اینکه محتوا لایو هست یا نه تا اگه اطلاعات لایو بود از همون کش استفاده بکنه بجای اینکه کل محتوا رو دوباره ارسال بکنیم برای مرورگر. مثل چی؟ ETag, Last-Modifiedوقتی از این هدر ها استفاده می‌کنیم لایو بودن دیتامون حفظ و پهنای باندمون ذخیره میشه.هدر ETagمخفف Entity Tag هست و مقدار اون رو هر چیز رشته‌ای می‌تونیم تنظیم کنیم ولی باید در نظر داشته باشید که قراره بعدا مقدار این هدر با سرور ما چک بشه پس چیز بیخود نباید تنظیمش کنیم.اینجا با رفتن به آدرس http://localhost:3000 فایل index.html برای کاربر ارسال میشه و بعد از اون طبق تصویری داخل فایل index.html داریم یه درخواست میره به مسیر wallpaper.jpg و میخواد که یه تصویر 5.1 مگابایتی رو دانلود بکنه که حجم قابل توجهی هست.درخواست اول ?اگه بخش timing ریکوئست wallpaper.jpg رو ببینیم واضحه که ۵۰ میلی ثانیه زمان برده تا محتوا دانلود بشه. (Content Download)اما با رفرش کردن صفحه و درخواست دوم شرایط متفاوت میشه و چون توی دیسک داریم اون تصویر رو دیگه نیازی به Download کردن نیست ?و همونطور که توی اسکرین شات بالا مشخصه مرورگر برای بررسی ETag یه هدر ست می‌کنه به اسم if-none-match و مقدار اون برابر با ETag ارسال شده ما خواهد بود.Last-Modifiedتوی استفاده از ETag ما اومدیم و فایل رو خوندیم کامل و هشش رو حساب کردیم که این فرآیند هرچی حجم فایل ما بیشتر باشه باعث میشه قدرت پردازشی بیشتری رو درگیر بکنه اونم با هر بار لود شدن تصویر!توی file system زمان آخرین تغییر انجام شده روی فایل مشخص هست چرا نیایم و به مرورگر زمان آخرین تغییر رو بدیم و اونم سری بعدی با استفاده از این مورد بهمون جواب نده؟!و اما بریم برای دیدن نتایج تست توی ریکوئست اول (بدون کش) ?و ریکوئست دوم (با کش) ?تکبیر!و اگه به هدر ها هم نگاه کنیم می‌بینیم که مرورگر هدر if-modified-since رو تنظیم کرده و مقدارش رو گذاشته اون چیزی که ما به عنوان last-modified بهش داده بودیم.یه سری نکته هست که توی بخش های بالا نتونستم اضافشون کنم به بحث و در نتیجه اینجا می‌نویسم (این بخش الان حکم پوشه utils توی تعیین folder structure رو داره که هرکی نمی‌دونه چیز جدیدی که داره به سیستم اضافه می‌کنه رو توی کدوم پوشه باید بذاره میذاره داخل utils ?)همونطور که توی عنوان نوشتم این یه مقدمه‌ای بر HTTP Caching بود و هدفم بیشتر آشنا کردنتون با این موضوع بود تا این رو هم به عنوان یه لایه کش اگه براتون فایده داره اضافش کنید و می‌تونید چیزایی بیشتری رو توی لینک هایی که پایین براتون می‌ذارم مطالعه بکنید و یاد بگیرید.شاید براتون سوال باشه که چرا کد های بالا رو با اکسپرس ننوشتم که آسون تر باشه کارم توی routing؟ جواب اینه که اکسپرس خودش ETag و Last-Modified رو ست می‌کنه (البته که قابل دیزیبل کردن هست) ولی از اونجایی که هدف آموزشی هست اینکه هیچی توسط فریمورک بهمون داده نشه و خودمون دقیقا بنویسیم چی میخوایم و چطوری کار بکن باعث میشه بهتر متوجه مغز مطلب بشیم.به دلایل نا مشخص برای تصویر وقتی از last-modified استفاده می‌کنید دیگه اون هدر if-modified-since رو ارسال نمی‌کنه و حتما باید هدر cache-control: max-age=0, must-revalidate رو ست کنید!دلیل اینکه ما کم کردن میزان استفاده از پهنای باند مهمه بحث مالیش نیست چون توی ایران حداقل پهنای باند قیمت بالایی نداره، ولی اگه تعداد ریکوئست های همزمان زیادی به سرورمون بیاد و برای یه محتوای حجیم این ریکوئستا زده شده باشه از اونجایی که پهنای باند محدوده سرعت برای کلاینتامون کم میشه.مطالعه بیشترCache-ControlEverything you need to know about HTTP CachingRFC 2616 (13- Caching in HTTP)امیدوارم علاقه مندتون کرده باشم برای بیشتر خوندن راجع به HTTP Cachingمحمد محمدعلیان | 16 اردیبهشت 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Fri, 06 May 2022 14:26:13 +0430</pubDate>
            </item>
                    <item>
                <title>طراحی یه سیستم کوتاه کننده لینک ساده [قسمت سوم: کش]</title>
                <link>https://virgool.io/Rocket/%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%DB%8C%D9%87-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%B3%D8%A7%D8%AF%D9%87-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-%DA%A9%D8%B4-ewquxcyiowld</link>
                <description>سلام، تا اینجای کار ساختار پایگاه داده و سیستم احراز هویتمون رو چیدیم و یه صحبتیم راجع به ذخیره سازی آمار های بازدید کردیم و الان هم قراره راجع به کش کردن اطلاعاتی که دسترسی بهشون زیاده صحبت کنیم.ابزاری که برای cache کردن اطلاعات استفاده می‌کنیم Redis هست، اما چرا؟ استفاده ازش خیلی سادست، کامینیتی بزرگی داره، کاملا نیاز های ما رو برطرف می‌کنه.من در نظر دارم همه‌ی لینک های کوتاه شده، بدون زمان انقضاء کش بشه. اینجاست که قضیه احتمالا خیلی عجیبه چون معمولا کلید های ردیس رو با یه زمانی درنظر می‌گیرن که لایو بودن دیتا از دست نره.ولی منم قصد ندارم لایو بودن دیتا رو از دست بدیم!همونطور که توی شکل بالا مشخصه برای ساخت/حذف/آپدیت یه لینک کوتاه علاوه بر اینکه تغییرات توی لایه دیتابیس اتفاق میوفته همون زمان توی redis هم اون تغییرات اعمال میشن.احتمالا الان یه سوال براتون پیش میاد: ردیس اطلاعات رو توی رم می‌نویسه و رم فضای ذخیره سازی محدودی داره و اینکه بخوایم همه‌ی لینک ها رو داخلش ذخیره کنیم باعث میشه خیلی زود رممون پر بشه، پس چرا داریم همچین کاری می‌کنیم؟نکته اینجاست که ردیس یه تنظیمی داره که می‌تونیم مشخص بکنیم حداکثر چقد مموری استفاده بکنه و با کلید هایی که بعد از اون میزان قراره ساخته بشن چطوری رفتار بکنه. (maxmemory &amp; maxmemory-policy)که با ست کردن maxmemory-policy به allkeys-lfu می‌تونیم بگیم زمانی که مموری بیشتری برای استفاده نداشتی برو اون کلید هایی که کمتر استفاده شدن رو پاکشون کن و این کلید جدیده رو اضافه کن :)توی این صفحه این تنظیمات ردیس دقیق توضیح داده شده.اما یه حالتی هست که باعث میشه از این هم سریع‌تر باشه! اونم زمانی که از سمت کلاینت کش بشه و اصلا ریکوئست به سرور ما نرسه :)))برای رسیدن به این حالت جذاب میشه از هدر Cache-Control استفاده کرد.البته اینطوری نیست که توی همون ریکوئست اول از مرورگر بتونه جوابش رو بگیره طبیعتا!بلکه توی ریکوئست اول هدر ارسال میشه و باعث میشه مرورگر کشش بکنه و توی درخواست های بعدی در صورتی که از max-age مشخص شده نگذشته باشه از اون بخونه.ایده این جنس کش کردن رو از bitly گرفتم (نمونه ریکوئستش رو می‌تونید توی تصویر پایین ببینید)لطفا به کامنت های این پست اهمیت بدید چون ممکنه دوستان اشتباهات من رو اصلاح کرده باشن و نظرات متفاوتی رو ببینیم.محمد محمدعلیان | 5 اردیبهشت 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 25 Apr 2022 09:50:13 +0430</pubDate>
            </item>
                    <item>
                <title>طراحی یه سیستم کوتاه کننده لینک ساده [قسمت دوم: احراز هویت و نحوه ذخیره سازی بازدید]</title>
                <link>https://virgool.io/CodeLovers/%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%DB%8C%D9%87-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%B3%D8%A7%D8%AF%D9%87-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AA-%D9%88-%D9%86%D8%AD%D9%88%D9%87-%D8%B0%D8%AE%DB%8C%D8%B1%D9%87-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-frgcwpluwenr</link>
                <description>سلام، توی این قسمت از طراحی سیستم کوتاه کننده لینک، قراره راجع به نحوه احراز هویت و استراتژی ذخیره سازی بازدید ها به شیوه کارآمد صحبت کنم.توی احراز هویت گزینه های خیلی زیادی با مزایا و معایب و کاربرد های خاص خودشون جلومون قرار دارن که دسته بندی های مختلفی هم مثل Session-Based و Token-Based دارن.انتخاب من برای احراز هویت این سیستم، JWT هست. با یه access-token و یه refresh-token اما چرا JWT؟ با ذخیره سازی اطلاعات مورد نیازمون از یوزر توی payload توکن می‌تونیم به دیتابیس کوئری نزنیم که البته این قضیه trade-off های خودش رو مثل out-date شدن اطلاعات داره که اینجا برای ما دغدغه جدی‌ای نیست چون سیاست refresh-token رو هم داریم و این باعث میشه access-token هامون توی یه بازه زمانی مشخص re-new بشن و اطلاعات هم آپدیت بشن طبیعتا.دیاگرام احراز هویتمون به شکل بالا میشه.فِلوی کلیمون اینطوری میشه که کاربر میاد با identifier (که در حال حاضر email کاربر هست) و رمز عبورش احراز هویت می‌کنه و access_token و refresh_token رو دریافت می‌کنه و refresh_token روی رکورد User ذخیره میشه تا در صورتی که access_token کاربر لو رفت بریم و refresh_token رو عوض کنیم تا بعد از تموم شدن expire time توکن دیگه نتونه رفرش بکنه.زمان انقضای access_token رو من ده دقیقه مد نظرم هست و refresh_token رو هم یک هفته. (دلیل خاصی هم ندارم که چرا دقیقا این دو تا زمان رو انتخاب کردم)پس جدول یوزرمون نیاز به یه فیلد جدید داره برای ذخیره سازی refresh_token.دیاگرام آپدیت شده دیتابیسمونتوی ذخیره سازی refresh_token توجه داشته باشید که باید اون رو hash کنیم و ذخیره بکنیم، اما چرا؟ بیاید حالتی رو بررسی کنیم که بدون هش ذخیره سازی کردیم، اگه به هر دلیلی یه مشکل امنیتی پیش بیاد و بشه رکورد های جدول User رو بیرون کشید، رفرش توکن همه یوزرهامون لو میره پس هکر می‌تونه حساب بخش زیادی از کاربرامون رو استفاده بکنه. (دلیل اینکه تمام حساب ها رو نمی‌تونه استفاده بکنه اینه که ممکنه یه سری از رفرش توکن هامون منقضی شده باشن و کاربر هم اخیرا لاگین نکرده باشه در نتیجه غیر قابل استفاده باشه)الگوریتمی که برای هش password و refresh_token توی دیتابیس استفاده می‌کنیم bcrypt هست تا امکان استفاده از rainbow table برای رسیدن به مقدار اصلی وجود نداشته باشه.موضوع دومی که قراره مطرح کنم راجع به نحوه ذخیره سازی بازدیدها هست. منظور من اینجا این نیست که توی چه دیتابیسی ذخیره کنیم یا با چه ساختاری ذخیرش کنیم، اون رو قبلا راجع بهش تصمیم گرفتیم.زمانی که من به عنوان یه کاربر آدرس xxxx.ir/gxqw1 رو توی مرورگر باز می‌کنم نیازم اینه که سریع به آدرس مقصد redirect بشم و اینکه ما می‌خوایم بازدید رو ذخیره کنیم نباید باعث بشه کاربر کندی رو حس بکنه و insert کردن توی جدول با دیتای بالا مخصوصا زمانی که index وجود داره روی فیلد هاش یه میزان زمانی رو می‌طلبه. اینجاست که Job Queue رو نیاز داریم استفاده بکنیم تا صرفا یه کار (ذخیره اطلاعات بازدید) رو تعریف بکنیم که نیازه انجام بشه ولی اینکه دقیقا کی انجام میشه برامون مهم نیست.درسته که اینجا برای اضافه کردن Job مد نظرمون به Job Queue هم زمان نیازه ولی نسبتش وابسته به مکانی که برای ذخیره سازی Job ها در نظر می‌گیریم می‌تونه خیلی کمتر باشه.اینطوری باعث میشیم مدت زمانی که لازمه برای ذخیره سازی بازدید به response time کاربر اضافه نشه.لطفا به کامنت های این پست اهمیت بدید چون ممکنه دوستان اشتباهات من رو اصلاح کرده باشن و نظرات متفاوتی رو ببینیم.محمد محمدعلیان | 29 فروردین 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 18 Apr 2022 10:36:02 +0430</pubDate>
            </item>
                    <item>
                <title>طراحی یه سیستم کوتاه کننده لینک ساده [قسمت اول: تعریف قابلیت ها و دیاگرام دیتابیس و انتخاب DBMS]</title>
                <link>https://virgool.io/CodeLovers/%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%DB%8C%D9%87-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%84%DB%8C%D9%86%DA%A9-%D8%B3%D8%A7%D8%AF%D9%87-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-%D9%82%D8%A7%D8%A8%D9%84%DB%8C%D8%AA-%D9%87%D8%A7-%D9%88-%D8%AF%DB%8C%D8%A7%DA%AF%D8%B1%D8%A7%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D9%88-%D8%A7%D9%86%D8%AA%D8%AE%D8%A7%D8%A8-dbms-kwcskey3qtat</link>
                <description>سلام، میخوام توی این سری از مطالب یه سیستم کوتاه کننده لینک رو دیزاین بکنم و درباره چرایی همه تصمیماتم توضیح بدم و همونطور که احتمالا می‌دونید سیستمی نیست که بدون نقض باشه و همیشه جا برای بهبود هست پس ازتون می‌خوام این لطف رو در حق من بکنید و نقض های طراحیم رو بگید.توی این مطلب قراره اول از همه مشخص بکنیم که از سیستممون چه انتظاراتی داریم.کاربر های ما توی دو حالت احراز هویت شده یا نشده می‌تونن یه لینک رو کوتاه بکنن و ما نمی‌خوایم لینک های کوتاه شدمون خیلی طولانی باشه تا بشه راحت به یه نفر بیانش کرد.برای احراز هویت امکان ورود با گوگل هم وجود داره.امکان دیدن آمار های بازدید از لینک ها هم برای کاربران ایجاد کننده وجود داره.اسم این سیستم هم با توجه به کارش گذاشتم کوچیکوک ? (در لهجه یزدی به یه چیز خیلی کوچیک میگن کوچیکوک)طراحی دیتابیسدیاگرام بالا با استفاده از diagrams.net ساخته شده و دلیل استفادم ازش اینه که رایگانه و فایلش رو می‌تونید ذخیره کنید و مجبور به ذخیره سازی فقط روی سرورهای خودش نیستید، همچنین داشتن اپ دسکتاپشم برام مزیت به حساب میاد چون نیاز دارم بتونم آفلاین هم کارهای دیاگرامیم رو پیش ببرم. همونطور که توی دیاگرام مشخصه ما توی سیستمون سه تا موجودیت داریم که User, Link و View هستش.موجودیت User برای احراز هویت کاربر استفاده میشه، Link برای ذخیره سازی لینک های کوتاه شده توسط کاربرا و  View برای نمایش آمار.فیلد provider توی موجودیت User برای اینکه که بتونیم بفهمیم User ما از چه طریقی رجیستر کرده یعنی عادی یا با استفاده از حساب گوگلش؟فیلد statistics_key برای اینه که اگه یه کاربر لاگین نکرده بود و یه لینک کوتاه ساخت بتونه با دادن مقدار این فیلد آمار بازدید از لینک کوتاهش رو ببینه.فیلد deleted_at توی موجودیت‌هامون برای حذف منطقی داده ها استفاده میشه. یعنی توی سیستمون هیچ داده‌ای رو قرار نیست واقعا حذف بکنیم و فقط قراره اونا رو نشون ندیم و یه برچسب حذف شده بزنیم بهشون.مزیت حذف منطقی چیه؟ می‌تونیم تمام داده های تولید شده توسط سیستمون رو داشته باشیم و همچنین اگه مشکلی پیش اومد بتونیم برگردونیم.این دیاگرام صد در صد تکمیل نیست و به مرور که میریم جلو نیاز به یه سری فلید های دیگه پیدا می‌کنیم که همون‌جا اضافشون می‌کنیم.انتخاب دیتابیسمن دیتابیس مورد انتخابم برای پیاده سازی این سیستم PostgreSQL هست. ولی چرا؟ توی این سیستم ما رابطه داریم و بر اساس رابطه هایی که داریم می‌خوایم کوئری بزنیم و برای اینکار یه سیستم مدیریت پایگاه داده رابطه‌ای انتظار میره بهتر جوابمون رو بده. همچنین schema جداولمون مشخصه پس schema-less بودن برامون مزیت نیست.حالا بین این همه RDBMS  چرا PostgreSQL؟ چون بیشتر دوستش دارم و جواب نیازم رو میده :)از کجا بفهمم این تکنولوژی من رو کند نمی‌کنه؟بنچمارک می‌گیریم :)یه اسکریپت برای seed کردن دیتاها داخل دیتابیس نوشتم و هر بخش رو با کامنتی که بالاشه جدا کردم.چند تا نکته راجع به اسکریپت ها ?سعی کردم حالت های مختلف داده‌ای رو داخلش ایجاد کنم تا بتونیم یه قضاوت منطقی داشته باشیم.توی قسمت insert کردن view ها دلیل اینکه صد هزارتا صد هزارتا insert می‌کنم اینه که حافظه Heap جاوااسکریپت پر می‌شد و امکانش وجود نداشت که همه رو با هم بریزم توی دیتابیس.خب حالا وقت اینه که سنگین ترین کوئری‌ای که توی نیازمندی هامون وجود داره و میزان فراخوانیش هم بالاست رو بزنیم و ببینیم چقد طول می‌کشه ریسپانس بده.سنگین ترین جدولی که داریم برای view ها هستش پس انتظار میره گرفتن view های یه link کندترین کوئریمون باشه.آیدی‌ای که بر اساسش کوئری زدم پر بازدید ترین لینک موجودمونه که 84 تا بازدید داره.روی کامپیوتر من این کوئری با وجود ده میلیون رکوردی که وجود داره و عدم وجود ایندکس برای فیلد link_id، فقط 1.4 ثانیه طول کشید که بسی جذابه.حالا با ایندکس چقد می‌شه؟ ۱۰ میلی ثانیه :))))مشخصات سیستمی که باهاش بنچمارک گرفتم ?Intel Core i7 7500 U (4 Cores)16GB DDR4 RAMSSDالبته در حینش اپلیکیشن های دیگه ای هم باز بود که باعث میشه PostgreSQL نتونه همه‌ی ظرفیت سیستم رو استفاده کنه.لطفا به کامنت های این پست اهمیت بدید چون ممکنه دوستان اشتباهات من رو اصلاح کرده باشن و نظرات متفاوتی رو ببینیم.محمد محمدعلیان | 22 فروردین 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 11 Apr 2022 18:44:15 +0430</pubDate>
            </item>
                    <item>
                <title>چطوری با وجود کوئری‌های کند کاربرای کمتری رو عصبی کنیم یا چرا Connection Pool توی اتصال به دیتابیس مهمه؟</title>
                <link>https://virgool.io/@MohammadAlian_1383/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%D8%A8%D8%A7-%D9%88%D8%AC%D9%88%D8%AF-%DA%A9%D9%88%D8%A6%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%DA%A9%D9%86%D8%AF-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%A7%DB%8C-%DA%A9%D9%85%D8%AA%D8%B1%DB%8C-%D8%B1%D9%88-%D8%B9%D8%B5%D8%A8%DB%8C-%DA%A9%D9%86%DB%8C%D9%85-%DB%8C%D8%A7-%DA%86%D8%B1%D8%A7-connection-pool-%D8%AA%D9%88%DB%8C-%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D9%87-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D9%85%D9%87%D9%85%D9%87-cokumskaem4s</link>
                <description>تمامی کارهایی که در ادامه انجام شده با دیتابیس PostgreSQL بوده و ممکنه در DBMS های دیگه رفتار متفاوتی وجود داشته باشه.چند روز پیش داشتم ویدیو Connection Pooling in PostgreSQL with Node.js رو از Hussein Nasser عزیزم :) می‌دیدم که یهو یه سوالی برام پیش اومد: اگه یه کوئری سنگین داشته باشیم و فقط یه کانکشن به دیتابیس داشته باشیم انتظار میره که اون کانکشن منتظر جواب اون مونده باشه و خب اگه یه کوئری دیگه داشته باشیم که سبکم هست نتونه کار بکنه چون کانکشنمون دستش بنده ?این عکس جهت گذاشته شدن به عنوان کاور پست اضافه شدهاین شد که رفتم یه ادیتور باز کردم و شروع کردم بررسی اینکه آیا این فرضیه من درست هستش یا خیر؟که در نهایت کد زیر رو نوشتم ?برای بنچمارک گرفتن این کد اومدم یه کد دیگه نوشتم که توی عکس زیر مشخصه ?همونطور که توی عکس زیر که نتیجه اجرای کد بالا هست مشخصه، زمانی که من ریکوئست به آدرس slow/ زدم باعث شده که چون اونجا سبب مشغول شدن کانکشن شده آدرس fast/ هم که بهش ریکوئست می‌زنم نتونه بهم جواب بده و منتظر بمونه تا کوئری اول تموم بشه و بعد کوئری دوم رو اجرا کنه.یه راه حل ساده‌ای که می‌تونیم داشته باشیم اینه که بیایم و توی هر ریکوئست که کلاینت می‌زنه یه کانکشن جدید بسازیم. این راه‌حل مشکل قبلی ما رو حل می‌کنه ولی یه مشکل جدید بوجود میاره و اونم اینه که زمان کانکت شدن به دیتابیس و احراز هویتش و مسیری که توی شبکه طی می‌کنه هم به ریسپانس تایم یوزر اضافه میشه و این بده.اینجاست که Connection Pool میاد و به دادمون می‌رسه.کلا مفهوم Pool توی علوم کامپیوتر یعنی ما یه مجموعه از منابع داریم که آماده استفادست که این منابع می‌تونه Object, File, Thread, Connection و ... باشه.پس توی یه تعریف ساده Connection Pool یعنی یه مجموعه کانکشن با دیتابیس ایجاد کنیم و اینا رو باز نگه داشته باشیم تا توی کوئری‌ها هر کدوم رو بدیم به یه کانکشن بیکار تا اجراش بکنه و بخاطر کندی یه کوئری دیگه که با درخواست کاربر X به دیتابیس زده شده کاربر Y رو معطل نکنیم.همون کد بالا رو بخوایم بجای یه کانکشن یه استخر (pool) از کانکشن ها رو داخلش داشته باشیم اینطوری میشه:‌حالا بریم ببینیم این سری اگه اسکریپت بنچمارکمون رو اجرا کنیم خروجیش چی میشه:همونطور که واضحه مشکلی که داشتیم به سادگی اضافه کردن یه خط کد و ویرایش یه کلمه حل شد! ولی برای همین نیاز بود یه مقاله بخونید ?خب پس بیایم یه Pool بسازیم با 1000 تا کانکشن که خیالمون راحت باشه؟نه دیگه همینطوری کانکشن بزنیم به دیتابیسم قرار نیست برامون بازدهی مثبت داشته باشه، چون کانکشن هایی که داریم ایجادشون هزینه بر هستن برای سرور دیتابیس و میزان قابل توجهی مموری مصرف می‌کنن.حالا چقد مموری مصرف می‌کنه؟برای بررسی این مورد اومدم یه کانتینر داکر با دستور زیر آوردم بالا که منابعش رو به صورت مستقل مانیتور کنمdocker run --name postgres -e POSTGRES_PASSWORD=randompassword -e POSTGRES_USER=application -p 5433:5432 -d postgres:alpine -c max_connections=1001برای مانیتور منابع کانتینرم از دستور docker stats postgres استفاده کردم و میزان مصرف منابع در حالتی که یک کانکشن به دیتابیس وجود داره رو می‌تونید توی عکس زیر ببینید:و اینم از میزان مصرف بعد از برقراری 1001 کانکشن به دیتابیسهمونطور که مشخصه بی‌خودی اضافه کردن سایز pool مون می‌تونه نتیجه عکس داشته باشه توی پرفرمنس.امیدوارم تونسته باشم توی درک اهمیت و نحوه استفاده بهینه Connection Pool کمک کنم.محمد محمدعلیان | 15 فروردین 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 04 Apr 2022 08:40:52 +0430</pubDate>
            </item>
                    <item>
                <title>چطوری یه PDF فارسی بر اساس HTML توی Node.js بسازیم؟</title>
                <link>https://virgool.io/@MohammadAlian_1383/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%DB%8C%D9%87-pdf-%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-%D8%A8%D8%B1-%D8%A7%D8%B3%D8%A7%D8%B3-html-%D8%AA%D9%88%DB%8C-nodejs-%D8%A8%D8%B3%D8%A7%D8%B2%DB%8C%D9%85-jywl9igrlsz9</link>
                <description>سلام ✋باورتون میشه که برای ساخت PDF توی Node.js یه پکیج مخصوص نداریم که بتونه با متن فارسیم کنار بیاد و فایل html css font و ... بدید تا تبدیلش کنه به PDF ؟! (حداقل الان نداریم) (شایدم من نتونستم پیدا کنم)خب دیگر نگرانی کافیست چون من امروز اومدم که یه راهکار بدم بشوره ببره همه این مشکلات رو و بتونید خیلی ساده PDF رو با بهترین کیفیتی که می‌تونید خروجی بگیرید ?این عکس از کاور یه مقاله انگلیسی کپی شده است.مشکل چیه؟داستان از اونجایی شروع شد که من یه فایل HTML داشتم، یه فایل CSS و یه سری تصویر و فونت و باید بر اساس دیتاهایی که سمت خودم دارم حین انجام یه اکشن خاص به PDF تبدیلش کنم.برای اینکه بتونم دیتاهای توی HTML رو داینامیک کنم که از تمپلیت انجین ejs استفاده کردم بعد برای PDF هم رفتم خیلی ریلکس و خوشحال مثل همیشه توی NPM یه سرچ بزنم که یه پکیج پیدا کنم که اینکار رو برام بکنه و رسیدم به پکیج html-pdf و از اونجایی که دانلود زیادی داره انتظار داشتم که گزینه مطلوبی باشه ولی دیدم فیت نیاز من نیست و با کلی بالا پایین نتونستم کاریش بکنم که با متن فارسی کنار بیاد و استایلا و فایل فونتم رو هم استفاده کنه.این سری توی گوگل بیشتر سرچ کردم و پکیجا و ابزارای دیگه‌ای که معرفی کرده بودن رو هم سعی کردم ازشون استفاده کنم ولی دیدم واقعا دارن اذیت می‌کنن و یه ابزار perfect پیدا کردم که اسمش رو الان یادم نیست ولی اینطوری بود که با داکر میومد بالا و شما بهش ریکوئست میدادی و فایل PDF رو بهت میداد اون و خروجیشم تمیز و خوب بود ولی نسخه رایگانش یه واترمارک بزرگ می‌زد اون پایین که باعث شد ازش استفاده نکنم.راه حل من چی بود؟توی سرچایی که داشتم دیدم که یکی اومده و اینکار رو با puppeteer انجام داده و منم چون قبلا باهاش کار کرده بودم گفتم چرا که نه؟اگه نمی‌دونید puppeteer چیه باید بگم یه پکیج نوده که می‌تونید باهاش browser رو کنترل کنید، یعنی همون مرورگر chrome رو فرض کنید که می‌تونه رابط گرافیکی نداشته باشه و از امکاناتش استفاده کنید. حالا یکی از امکانات مرورگر چیه؟ آفرین! ساخت PDF ?دغدغم توی استفاده از puppeteer یه چیز بود: پرفرمنس.فرض کن: قراره کروم باز کنی رو سرور! یا حسین ? ولی دیدم نه واقعا خیلی زیاد منابع مصرف نمی‌کنه و میشه تو production ازش استفاده کرد.البته باید یه نکته رو توجه کنید که من فقط یه مرورگر باز داشتم و برای ساخت هر PDF صرفا تب جدید می‌ساختم و بعد از تموم شدن ساخت PDF هم تب رو می‌بستم که منابع بیخودی هدر نره.توجه کنید که با puppeteer می‌تونید مرورگر رو با رابط کاربری گرافیکیش باز کنید (یعنی توی مود غیر headless) ولی برای ساخت PDF حتما باید تو حالت headless باشید.نمونه کداین پروژه چون تعداد فایلاش زیاده نتونستم توی gist بذارم و توی این ریپازیتوری قرارش دادم. (star یادتون نره ?)جواب سوالات احتمالی راجع به نمونه کدچرا مستقیم page.setContent رو استفاده نکردم و قبلش goto زدم به فایل ejs ؟! از اونجایی که آدرس دهی فایلای assetم به صورت relative بود نیاز بودش که مرورگر توی اون مسیر باشه تا بتونه فایلای font و image و ... رو resolve کنه پس اول رفتم به اون فایل ejs که طبیعیه مرورگر نتونه parseش کنه و بعد با اون فایل تمپلیت، HTMLم رو رندر کردم.چرا از پکیج puppeteer-core استفاده کردم؟ چون موقع نصب پکیج puppeteer میره و باینری مرورگر رو دانلود می‌کنه و از اونجایی که تحریمیم روی سرور های ایران به مشکل می‌خورره پس از puppeteer-core استفاده کردم تا مسیر فایل باینری مرورگر رو خودم بهش بگم.چرا ساختار پروژه روی گیتهاب انقد درب و داغونه :) ؟ چون نمونه کده و قرار نیست همین برداشته بشه و توی production استفاده بشه ?امیدوارم تونسته باشم یخورده کمک کنم.محمد محمدعلیان | 8 فروردین 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 28 Mar 2022 18:08:39 +0430</pubDate>
            </item>
                    <item>
                <title>صف کارها (Job Qeueu) چیست؟</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%B5%D9%81-%DA%A9%D8%A7%D8%B1%D9%87%D8%A7-job-qeueu-%DA%86%DB%8C%D8%B3%D8%AA-ygqi7ssuko9t</link>
                <description>سلام ? اگه یه مدت باشه که توی حوزه بک‌اند فعالیت می‌کنید یکی از اصطلاحاتی که احتمالا شنیدید Job Queue هستش، توی این مطلب می‌خوام در قالب یه مثال عملی کارش رو توضیح بدم ?این عکس تزئینی می‌باشد تعریف مشکلبیاید یه پروژه فروشگاهی رو فرض بکنیم که نیازه بعد از اینکه کاربر پرداختش رو انجام داد ما PDF رسید رو سمت سرور تولید بکنیم و در قالب یه لینک کوتاه برای کاربر SMS کنیم.توی ابتدایی ترین حالت میایم و توی بخشی که پس از خرید کاربر فراخوانی میشه پیاده‌سازی های مربوط به ساخت PDF و ارسال SMS رو اضافه می‌کنیم.حالا بعد از گذشت چند روز از زمانی که فیچر رو فرستادیم روی production کاربرا بهمون پیام میدن که فرآیند پرداخت خیلی کند شده و ما بعد از بررسی‌ای که انجام میدیم متوجه می‌شیم که ساخت PDF و ارسال SMS داره 6 ثانیه کاربر رو معطل می‌کنه و این باعث کندی و نارضایتی کاربرامون شده.راه حلیه سوال: آیا واقعا نیازه که همون لحظه‌ای که کاربر خرید رو انجام داد ما PDF رو بسازیم و تا ساخته نشده کاربر رو معطل نگه داریم و بعدم برای ارسال SMS این روند رو تکرار کنیم؟ احتمالا نه.بجاش می‌تونیم بیایم و یه صف (اگه نمی‌دونید صف توی برنامه‌نویسی به چه معنیه این مطلبم رو بخونید)  از کارهایی که نیازه انجام بشن ولی الزامی نیست که کاربر رو بخاطرش معطل کنیم بسازیم و بعد از پرداخت کاربر صرفا یه کار دیگه به اون صف اضافه بکنیم.حالا یه سری Worker وجود دارن اینجا که دارن این کارهایی که به صف اضافه شده رو می‌خونن و یکی یکی انجامشون میدن.توی این فرآیند ما یه جادو استفاده نکردیم که اون فرآیند ساخت PDF و ارسال SMS رو سریع‌تر بکنه! ما صرفا کاری کردیم که اون زمان لازم برای انجام اینکار ها به response time کاربر اضافه نشه و توی پس زمینه بره جلو.نمونه کد پیاده سازی Job Queue با Node.js و کتابخونه bull https://gist.github.com/mhmda-83/ff5e5245bbed2801da0c02c6e1d671d8 امیدوارم تونسته باشم یخورده از ابهامی که دارید کم کرده باشم.محمد محمدعلیان | 1 فروردین 1401کانال تلگرامم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 21 Mar 2022 13:14:03 +0330</pubDate>
            </item>
                    <item>
                <title>آمار بازدید پست‌های من در سال ۹۹</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%A2%D9%85%D8%A7%D8%B1-%D8%A8%D8%A7%D8%B2%D8%AF%DB%8C%D8%AF-%D9%BE%D8%B3%D8%AA-%D9%87%D8%A7%DB%8C-%D9%85%D9%86-%D8%AF%D8%B1-%D8%B3%D8%A7%D9%84-%DB%B9%DB%B9-bn7oyxtlyhkx</link>
                <description>در طول تاریخ از اعداد استفاده کردیم تا اغلب داد و ستد کنیم و آن‌چیزی که شمردنی است را بشماریم. برای هر عدد واحد درست کردیم تا عددهای زندگی قاطی نشوند و از اعداد، شفاف‌تر استفاده کنیم؛ مثلا وقتی می‌گوییم ده هزار تومان به پول اشاره داریم و وقتی می‌گوییم ده هزار بلیط به بلیط!روز به روز که در زندگی جلو‌تر رفتیم عددها فرقی نکردند ولی این واحدها بودند که زیاد شدند. واحد کریپتو، واحد اصله درخت، واحد فاصله و …«واحد» یک توافق عمومی است برای شمردن؛ تا همانطور که گفتم شمردن‌ها قاطی نشود. مشاهده افراد دارای ثروت (اجتماعی یا مالی) به من ثابت کرده اینکه چه چیزی را بشماریم از اینکه چطور بشماریم مهم‌تر است. هرکس با واحد خاصی مسائل زندگی را می‌شمارد. اینطور به نظرم آمده که مشخص کردن واحد یعنی مشخص کردن اینکه من در زندگی برای چه چیزهایی ارزش قائلم و می‌خواهم چه چیزهایی را در زندگی بشمارم. https://cdn.virgool.io/annual-report/1399/ildkizkky5lm-tEJHC.mp4 اعدادی که بدون واحد ثبت کردمبه ویدیویی که ویرگول برایم ساخته که نگاه می‌کنم میبینم که در سال ۹۹، من در مجموع ۹,۵۲۰ کلمه در ویرگول نوشتم و منتشر کردم و مخاطبین، پست‌های من را ۴۶۱ مرتبه پسندیدند و  ۱۲۰ بار هم نظر خود را روی پست‌های من به اشتراک گذاشتند. در سال ۹۹، ۱۳۵ نفر در ویرگول من را دنبال کردند تا پست‌های بعدیم را بخوانند. این اعداد نشان میدهند من کاری کرده‌ام. هرکدام به واحدی وصل هستند. از خودم می‌پرسم من کدام واحد را شمارش کرده‌ام؟ کدامیک از واحدهای بالا از همه برای من مهم‌تر است؟ ادامه ویدیو را می‌بینم.آمار از اثر بیرونی می‌گویندطبق آمار پست‌های من ۴,۳۹۷ بار خوانده شدند و ۷۱۶,۲۳۶ ثانیه صرف مطالعه آنها شده است، که با توجه به جمعیتی که در ایران به اینترنت دسترسی دارند، ویرگول به من می‌گوید که توانستم  ۰/۰۰۹۸۱۹۵۲۳ ثانیه، سرانه مطالعه دیجیتال کشور را بالا ببرم.از طرف دیگر ویرگول به من می‌گوید که اگر قرار بود پست‌هایم را چاپ و به دست تک تک خوانندگان برسانم باید ۱۷,۹۸۹ کاغذ مصرف می‌کردم.آن عددهای کوچک ابتدای ویدیو حالا تبدیل شده‌اند به عددهای بزرگ به اینکه من جلوی مصرف این تعداد کاغذ را گرفتم یا به اینکه من  ۰/۰۰۹۸۱۹۵۲۳ ثانیه، سرانه مطالعه دیجیتال کشور را جابه جا کرده‌ام. واحد این عددها برای من ملموس‌تر است.واحد نوشتن چیست؟همه عددهای بالا و همینطور اثر بیرونی که روی خوانندگان و همینطور در مقیاس بزرگتر طبیعت و جامعه اطرافم گذاشتم اعدادی هستند که من دوستشان دارم و به آنها افتخار می‌کنم. اگر چنین ویدیویی دست شما نیز رسید به شما بابت تک تک اعداد تبریک می‌گویم.اثر هر نوشته تا حدودی معلوم است، اگر بنویسید جلوی قطع درخت را می‌گیرید، به سرانه مطالعه کشور اضافه می‌کنید و خوانندگانی جذب می‌کنید که شما را از طریق نوشته‌هایتان می‌شناسند و …به نظرم می‌رسد که نوشته‌های من و شما واحد ندارند ولی اثر بیرونی دارند.</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 22 Mar 2021 16:45:19 +0430</pubDate>
            </item>
                    <item>
                <title>چطوری لوکال هاستمون رو با بقیه به اشتراک بذاریم؟</title>
                <link>https://virgool.io/CodeLovers/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%D9%84%D9%88%DA%A9%D8%A7%D9%84-%D9%87%D8%A7%D8%B3%D8%AA%D9%85%D9%88%D9%86-%D8%B1%D9%88-%D8%A8%D8%A7-%D8%A8%D9%82%DB%8C%D9%87-%D8%A8%D9%87-%D8%A7%D8%B4%D8%AA%D8%B1%D8%A7%DA%A9-%D8%A8%D8%B0%D8%A7%D8%B1%DB%8C%D9%85%D8%9F-szidf8qvwz4h</link>
                <description>سلام ?احتمالا برای شما هم پیش اومده که داشته باشید روی یه پروژه‌ای کار بکنید روی سیستم خودتون و یکی از دوستان، همکاران یا هرکس دیگه‌ای بخواد پروژه شما رو ببینه، ولی هنوز پروژه تکمیل نشده که شما بخواید فرآیند های مربوط به deploy پروژه رو انجام بدید، خب توی این موقعیت یه راه اینه که بگیم صبر کنن تا پروژه تموم بشه و شما دیپلوی بکنید، یه راه دیگه اینه که سورس کد پروژه رو بهش بدیم و نحوه راه‌اندازی رو هم بهش بگیم[البته این راه خیلی دردسر داره خصوصا اگه از دیتابیس های خاصی استفاده بکنید رو پروژه یا ...] و البته یه راه دیگه که برای این مورد از همه عقلانی تره! اونم استفاده از یه سری سرویس که بهمون یه آدرس public توی اینترنت بدن تا بدیم به بقیه تا از چیزی که ساختیم لذت ببرن و کلی قربون صدقمون برن ?البته توجه داشته باشید آدرس‌هایی که می‌گیریم به صورت موقت در دسترس هستن و زمانی که اجرای دستور متوقف بشه اون آدرس‌ها هم دیگه در دسترس نیستن.localhost.runاین سرویس نیاز به نصب نداره و با یه دستور می‌تونید به هدفتون برسید :)البته لازمه که ssh رو داشته باشید روی سیستمتون و همچنین یه ssh key که توی این صفحه گیتهاب آموزشش وجود داره.ssh -R 8080:localhost:3000 ssh.localhost.runکافیه بجای 3000 پورتی که پروژتون روش listen می‌کنه رو بنویسید.ویدیو آموزشی استفاده از localhost.runngrokبرای استفاده از ngrok [بخونید اِن‌جی‌روک] لازمه که فایل اجراییش رو دانلود بکنید و بعد از اینکه ثبت‌نام کردید و authtoken‌تون رو گرفتید با دستور زیر authtoken اتون رو بهش بدید.ngrok authtoken YOUR_TOKENو بعد با دستور زیر آدرس public اتون رو بگیرید.ngrok http PORT_NUMBERهمونطور که میشه از تصویر بالا متوجه شد ngrok یه اینترفیس وب روی پورت 4040 ارائه می‌کنه که می‌تونید ریکوئستایی که اومده همراه با جزئیات ببیند و حتی اونا رو تکرار کنید.ضمنا با استفاده از ngrok tcp 22 می‌تونید اجازه دسترسی به کامپیوترتون از طریق ssh رو به هرکسی که توی اینترنت هست بدید ??ویدیو آموزشی استفاده از ngroktunneltoبرای استفاده از این ابزارم لازمه که فایلش رو دانلود کنید و بعد با دستور زیر پورت مورد نظرتون رو share کنید.می‌تونید subdomain شخصی هم تعریف کنید (حتی توی پلن رایگان)برای اینکار کافیه access key داشته باشید و بعد با دستور زیر اون رو به ابزار بدید.tunnelto set-auth --key YOUR_KEYو بعد به شکل زیر می‌تونید ساب‌دومین مد نظرتون رو بهش بگید.به همین خوشمزگی ?امیدوارم که چیزایی که گفتم به کارتون بیاد ?اگه سوالی، ابهامی چیزی بود می‌تونید توی کامنتا بپرسید تا من یا سایر دوستان جوابش رو بهتون بگیم.محمد محمدعلیان | 11 دی 1399کانال تلگرامم | توییترم | لینکدینم</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Thu, 31 Dec 2020 12:30:38 +0330</pubDate>
            </item>
                    <item>
                <title>چند درس موفقیت از ورزش سی‌دقیقه‌ای که داشتم!</title>
                <link>https://virgool.io/@MohammadAlian_1383/%DA%86%D9%86%D8%AF-%D8%AF%D8%B1%D8%B3-%D9%85%D9%88%D9%81%D9%82%DB%8C%D8%AA-%D8%A7%D8%B2-%D9%88%D8%B1%D8%B2%D8%B4-%D8%B3%DB%8C%D8%AF%D9%82%DB%8C%D9%82%D9%87%D8%A7%DB%8C-%DA%A9%D9%87-%D8%AF%D8%A7%D8%B4%D8%AA%D9%85-pkooqe0gsy2q</link>
                <description>اول از همه سلام ?خب داستان اینه که من امروز پس از مدتها رفتم سراغ ورزش و توی ورزشی که داشتم تصمیم گرفتم بتونم 5 طناب به صورت ضربدری بزنم (شاید خیلی آسون باشه براتون ولی برای من که اونقدرم آسون نبود?) و توی این روند رسیدن بهش یه سری درس گرفتم که فکر می‌کنم توی زندگی و برای موفقیت هم این موضوعات پابرجا باشه.منظور من از موفقیت توی این مطلب رسیدن به هدفی که تعیین کردید هست.هدف دست‌یافتنی داشته باشیدمن برای رسیدن به این هدفم توی ورزش چیزی نزدیک به پونزده بار یا بیشتر شکست خوردم! حالا اگه این هدف بجای 5 طناب، 100 طناب می‌بود چقدر تعداد این شکست ها بیشتر می‌شد؟ ?اگه شکست بیشتری می‌خوردم ادامه می‌دادم؟ اصلا شروع می‌کردم به تلاش برای رسیدن بهش؟ جواب این سوال کاملا وابسته به شخص شماست ولی منِ الان که از یجایی به بعد خسته می‌شدم و ادامه نمی‌دادم.پس حواستون به دست‌یافتنی بودن هدف‌هایی که میذارید باشه.زمان رسیدن به هدف رو منطقی تعیین کنیدمن توی مدت زمان 20 دقیقه‌ای می‌خواستم به هدفم برسم، حالا اگه همین هدف رو توی مدت زمان پنج دقیقه‌ای می‌خواستم بهش برسم چی‌میشد؟ برای من که حداقل توی چهار سال گذشته یکبار هم طناب ضربدری نزدم منطقی بود؟شاید بعد از تموم شدن زمانی که برای هدفم گذاشتم باز هم تلاش می‌کردم ولی بعد از اون، رسیدن به هدفم به همون میزانی لذت داشت که اگه سر وقت تموم می‌کردم لذت داشت؟ اصلا حاضر بودم تلاش کنم براش بعد از گذشتن زمانش یا صرفا خودم رو یه بازنده می‌دونستم؟ الگوی شکست‌هاتون رو پیدا کنیدمن تا یه مدتی به دومین طناب نمی‌رسیدم که طناب به پام برخورد می‌کرد و نمی‌تونستم بیشتر ادامه بدم تا متوجه یه الگو شدم و اون این بود که من اول میومدم پایین بعد طناب تازه میخواست رد بشه (امیدوارم متوجه شده باشید ?)خب چیکار کردم؟ سرعت دستم رو بیشتر کردم موقعی که میخواستم طناب رو از زیر پام رد کنم، به همین سادگی!پس صرفا سخت کوشی و تلاش بی وقفه نیست که شما رو به هدفتون می‌رسونه بلکه چیزایی مثل درس گرفتن از اشتباهات هم توی این داستان دخیل هستن.در جای درستی قرار بگیریدمی‌تونستم توی یه فضای یک متر در یک متر من به هدفم برسم؟ اصلا می‌شد طناب زد که من بخوام ضربدری هم بزنم؟پس اگه دوست دارید یه کارآفرین باشید شاید قرار گرفتن توی جمع آدمای بیکار یا کارمند سرعت شما توی رسیدن به هدفتون رو کم بکنه و شایدم ناممکن بکنه البته شایدم هیچ‌کدوم ?‍♂️به شکست عادت نکنیدمن انقدی شکست خورده و خسته بودم که دیگه به خودم زحمت شمردن تعداد دفعاتی که طناب می‌زنم رو نمی‌دادم و خیلی راحت می‌تونم بگم که شاید دو یا سه بار اون هدفم رو رد کردم ولی خب چون نشمرده بودم حس موفقیت نداشتم ?پس حواستون به دست‌آوردهایی که دارید باشه.استراحت کنیداز اونجایی که فعالیتی که انجام می‌دادم بدنی بود خسته می‌شدم و نفسم سخت بالا می‌اومد و ... نیاز بود که استراحت کنم، ولی یه استراحت کوتاه تا refresh بشم نه اینکه کلا جا بزنم.حالا اگه می‌خواستم به حرفای چرت و پرت انگیزشی گوش بدم باید مث یه حیوان چهارپا جون می‌کندم و خودم رو به کشتن می‌دادم تا بتونم 5 تا دونه طناب بزنم ?به لذت انتهای کار فکر کنیدچیزی که باعث شد من این تعداد از شکست رو هندل کنم و همچنان ادامه بدم این بود که به آخرش فکر می‌کردم که بنظرم یه آدم ارزشمندتر شده بودم که بر خلاف گذشته با پنج شش تا شکست کاری رو ول نکرده!و همچنین به داستانی که برای تعریف کردن داشتم فکر می‌کردم ?همچنین اون عرقی که بعد از انجام دادن این کار روی پیشونیم نشسته بود به قدری برام ارزشمند بود که نگم براتون ?در نهایت، همه این ها یه نوشته بود که شاید بهتون یه انگیزه کوچیکی بوده ولی تا زمانی که عملی نشده هیچ ارزشی نداره پس عملگرا باشید.ولی کی فکرش رو می‌کرد توی سی دقیقه ورزش بشه این همه چیز یاد گرفت؟ ??سپاس که خوندید ? -- محمد محمدعلیان | 21 آذر 1399</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Fri, 11 Dec 2020 15:35:23 +0330</pubDate>
            </item>
                    <item>
                <title>معرفی MongoDB - دیتابیس رؤیایی برای توسعه‌دهندگان</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D9%85%D8%B9%D8%B1%D9%81%DB%8C-mongodb-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D8%B1%D8%A4%DB%8C%D8%A7%DB%8C%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AA%D9%88%D8%B3%D8%B9%D9%87%D8%AF%D9%87%D9%86%D8%AF%DA%AF%D8%A7%D9%86-xo6ksa9w4haz</link>
                <description>سلام، خداقوت توسعه دهندگان عزیز :)مقدمهاکثر نرم‌افزار های بزرگ و کوچیک توی خودشون نیاز به کار با دیتا دارن و بعضی از این نرم‌افزارا نیازمند این هستن که دیتاهاشون persistent(دائمی) بشه و نمی‌خوان بعد از اینکه کاربر از اون نرم‌افزار خارج شد همه دیتاهاش بپره، اصلا جذاب نیست که وقتی وارد یه نرم‌افزار میشید مجدد بخواید ثبت‌نام یا لاگین بکنید مگه نه؟!احتمالا اولین راهکار براتون استفاده از فایل هست که کاملا هم جوابگو هست ولی اینکه داده رو چطوری توی فایل ذخیره کنید، به چه شکل از فایل بخونید و .... کاملا به عهده خودتونه! و اصلا هم مسئولیت کمی نیست و در دراز مدت با مشکلات پرفرمنسی و هزارجور مشکل دیگه باید دست و پنجه نرم کنید پس یا مطمئن بشید که کاری که انجام میدید خیلی کوچیکه یا استفاده نکن از فایل برادر من!اما یه راهکار دیگه هم هست که خیلی جوابه و بیشتر اونایی که نیاز به persistent کردن دیتا دارن ازش استفاده می‌کنن و اونم استفاده از دیتابیسه :) یک‌سری تیم نشستن و هزارجور مشکلی که بالا مطرح شد رو حل کردن و برامون این دیتابیس ها رو آماده کردن(دمشون گرم ?)حالا ما یه دغدغه جدید داریم، چه دیتابیسی استفاده کنیم و اصلا چه نوع دیتابیسی به درد پروژمون میخوره؟!توی این مطلب میخوام چندتا کار انجام بدم.معرفی دیتابیس های SQL و NoSQLمقایسهمعرفی MongoDBچرا MongoDB؟معرفی دیتابیس های SQL و NoSQLعکس کپی می‌باشد ?معرفی دیتابیس‌های SQL و NoSQLدر جهان هستی دو نوع دیتابیس وجود دارد یکی SQLای ها و یکی NoSQLای ها :)هرکدام را بهر کاری ساختند و نمی‌توان گفت که یکی از دیگر برتری بسیار دارد و هرکس اینگونه گفت بدانید که متعصبی بیش نیست و فاصله اجتماعی را با وی رعایت نمایید!مقایسهبه دیتابیس‌های SQLای در عمده مواقع میگن دیتابیسای رابطه‌ای یا RDBMS که مخفف Relational Database Management System هست و به دیتابیسای NoSQLای هم غیررابطه‌ای یا توزیع‌شده(distributed) میگن.دیتابیس‌های SQL بر پایه جداول هستن ولی دیتابیس های NoSQL بر پایه سند(document)، کلید و مقدار (key-value)، گراف و ... هستند.دیتابیس‌های SQL داده های داخلشون یه فرم خاصی دارند و فرم این داده‌ها از قبل مشخص شده ولی دیتابیس های NoSQL می‌تونن داده‌هایی که دارای یک شکل و شمایل یکسان نیستند رو هم ذخیره کنند.دیتابیس‌های SQL به صورت عمودی مقیاس پذیرن (البته به صورت افقی هم می‌تونن بزرگ بشن ولی چالشاش بیشتر از NoSQLای‌ها هست) و دیتابیس های NoSQL هم به صورت افقی و هم به صورت عمودی.مقیاس عمودی یعنی شما اگر داده های توی دیتابیستون خییللللییی زیاد بشن و نیاز به منابع بیشتر داشته باشید باید سرورتون رو از لحاظ سخت افزار ارتقا بدید، مثلا اگر هاردش 256 گیگابایت SSD هست بکنید یک ترابایت NVME!مقیاس افقی یعنی در صورت بالا رفتن حجم داده و میزان پردازش شما می‌تونید سرور اضافه بکنید مثلا دو تا سرور با رم 8 گیگ رو در کنار هم استفاده کنید!نکته:‌ مقیاس عمودی تا یه جایی امکان پذیره (مگه چقدر منابع رو میشه ارتقا داد؟) ولی مقیاس افقی شما می‌تونید هرچی دلتون میخواد سرور اضافه کنید و در صورت نیاز همون سرورا رو ارتقا بدید :)چند نمونه از دیتابیس‌های اس‌کیوال: MySQL, Oracle, Sqlite, PostgreSQLچند نمونه از دیتابیس‌های نو اس‌کیوال:  MongoDB, Redis, BigTable, CouchDB, Cassandraمعرفی MongoDBتا به اینجای کار فهمیدیم که MongoDB یه دیتابیس NoSQL هستش، اما بریم با بقیه فیچر های این بزرگوار آشنا بشیم.قبل از اون باید بگم که Mongo از کلمه humongous اومده که به معنی عظیم هست!‍ساختار داده توی MongoDB به صورت BSON هست یعنی JSON به شکل Binrary پس شمایی که به عنوان برنامه‌نویس به شکل آبجکتی فکر می‌کنی الان باید خیلی خوشحال باشید چون دیتابیستونم همینکارو میکنه!یه زبان کوئری خفن و تو دل برو!db.users.find({ name: &amp;quotMohammad&amp;quot }).sort({ birthDate: 1 })به همین سادگی کاربرایی که اسمشون محمد هست(که کمم نیستن ?) رو بر اساس تاریخ تولدشون به شکل صعودی مرتب کردیم. مونگو دی‌بی تمام قابلیتای دیتابیس های SQLای رو داره حتی بیشتر!ضمنا MongoDB یه سرویس آنلاین هم داره به اسم Atlas که همونطور که احتمالا متوجه شدید یه DBaaS هست (Database As A Service) و اونم کلی قابلیت به صورت جدا گونه داره!حالا چرا نوشتم رویایی برای توسعه‌دهندگان؟ آخه شما نحوه کوئری زدن رو ببین، یه دل نه، صد دل عاشقش میشی ❤️دیگه مجبور به استفاده از دستورات گاها وحشتناک SQL هم نیستید ?اگه تجربه‌ای داشتید از لذت یا عذاب توی استفاده از این دیتابیس توی نظرات بگید که من و بقیه مطلع بشیم و با چشم بازتر انتخابمون رو انجام بدیم.محمد محمدعلیان --- 12 آبان 1399</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 02 Nov 2020 05:35:46 +0330</pubDate>
            </item>
                    <item>
                <title>25 چنل یوتوب برای برنامه‌نویسان</title>
                <link>https://virgool.io/@MohammadAlian_1383/25-%DA%86%D9%86%D9%84-%DB%8C%D9%88%D8%AA%D9%88%D8%A8-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%D9%86%D9%88%DB%8C%D8%B3%D8%A7%D9%86-rtiehiqtalpy</link>
                <description>توی این بلاگ می‌خوام چند تا از چنل های یوتوب که ویدیوهایی مرتبط با برنامه‌نویسی منتشر می‌کنن رو بهتون معرفی کنم و از معروف ها مثل Web Dev Simplified یا Traversy Media می‌گذرم.و البته فقط راجع به برنامه‌نویسی نیست چنل ها و بعضی هاشون راجع به سیستم عامل یا شبکه و ... هم هستن، ولی به عنوان برنامه‌نویس حداقل آشنایی با این ها براتون می‌تونه مفید باشه.در ضمن بین چنلا هم فارسی هست هم انگلیسی.لیست چنل هاAbbas YazdanpanahDistroTubeCoding Dojo - باشگاه کدزنیKalle HalldenFireshipFaraday AcademyEngineer ManDavid BombalJadi MirmiraniLuke SmithAaron JackAl SweigartAlireza AyinmehramirhosseinabcodedamnCoder CodercodeSTACKrFilledStacksLiveOverflowJSConfTyler&amp;#x27;s TechHussein NasserCaleb CurrybuildwithpythonMosallas Groupاگر چنلی رو میخواید به این لیست اضافه بکنید توی کامنتا بنویسید تا من و دوستان استفاده کنیم.محمد محمدعلیان - 6 آبان 1399</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Tue, 27 Oct 2020 05:27:07 +0330</pubDate>
            </item>
                    <item>
                <title>داستان یک مهاجرت (ویندوز --&gt; گنو/لینوکس)</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%AF%D8%A7%D8%B3%D8%AA%D8%A7%D9%86-%DB%8C%DA%A9-%D9%85%D9%87%D8%A7%D8%AC%D8%B1%D8%AA-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-%DA%AF%D9%86%D9%88%D9%84%DB%8C%D9%86%D9%88%DA%A9%D8%B3-ktpcdyzp65ax</link>
                <description>سلام به همگی، من چندوقت پیش یه مطلب نوشتم تحت عنوان &quot;گنو/لینوکس، ذوقی که کور شد&quot; و اونجا از تجربه بد مهاجرتم به گنو/لینوکس گفتم و خیلی هم پست جنجالی‌ای شد(45 کامنت در حال حاضر) پس چی شد که برگشتم؟تصویری از مهاجرت یه عده پرنده :)یک نیازمن از عمر لپتاپم یه سه سالی می‌گذره و طبیعتا قدرت و سرعت اون ابتدا رو نداره و از طرفی ویندوز با حریصی هرچه تمام از منابع استفاده می‌کنه و خودش چندوقت یک‌بار تصمیم میگیره Microsoft Windows Search Indexer و یه سری سرویس دیگه ران بکنه که به شدت CPU من رو درگیر می کنه پس اینجا تصمیم به مهاجرت گرفتم و این رو هم پذیرفتم که قراره اوایلش دهنم سرویس بشه و همه چیز قرار نیست سرراست باشه و با این دید از یه سری از دوستان کمک گرفتم برای انتخاب توزیع و DE که بهم آرچ رو پیشنهاد دادن منم می‌دونستم که آرچ نصبش قرار نیست ساده باشه ولی تصمیم گرفتم که پاش وایسم و هرطور شده نصبش کنم و این کار رو هم کردم ولی از اونجایی که درگیر یک سری پروژه ها بودم و خیلی وقت نداشتم نرفتم تا درگیر نصب چیزای گرافیکی بشم و بخاطر همین یه توزیع arch base انتخاب کردم به اسم Manjaro و نسخه XFCE رو دانلود کردم و الان حدودا 5 روزه که دارمش و انصافا هم خیلی خوشگله :)پ.ن: من اول گنو/لینوکس رو به صورت Standalone نصب کردم ولی بخاطر کارای مدرسه مجبور به نصب ویندوز به صورت dual boot شدم.مشکلات هنگام نصبمثل دفعه پیش نصب انجام می‌شد ولی سیستم بالا نمیومد این‌دفعه پاش وایسادم و توی فوروم خود لپتاپ دنبال جواب گشتم و بالاخره یکبار برای همیشه این مشکل رو راه حلشو فهمیدم.توصیه های شخصیبازم مثل پست قبل میگم که اگر دلیل خاصی نداشته باشید که بیاید گنو/لینوکس یا آدم سختی پذیری نباشید و یا وقتش رو ندارید گنو/لینوکس براتون سیستم عامل مناسبی نیست چون اینجا خیلی چیزا رو لازمه که خودتون کانفیگ بکنید و همه چیز هم ساده و سرراست مثل ویندوز نیست ولی از طرفی همین باعث میشه که شما با سیستم عامل بیشتر آشنا بشید و به میزان خیلی زیادی چیزای جدید یادبگیرید.من که خودم عاشق این سیستم عامل شدم و از این میزان light weight بودن در عجبم :)محمد محمدعلیان - 28 مهر 1399</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Mon, 19 Oct 2020 06:10:33 +0330</pubDate>
            </item>
                    <item>
                <title>شروعی دوباره!</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%B4%D8%B1%D9%88%D8%B9%DB%8C-%D8%AF%D9%88%D8%A8%D8%A7%D8%B1%D9%87-r6pg1ffrgxb2</link>
                <description>سلام، بعد از سه ماه اومدم با یه مطلبی که هیچ محتوای آموزشی‌ای نداره ولی اگر دوست دارید مطالب آموزشیمو بخونید، حتما این مطلب رو هم بخونید.چی‌شد سه ماه نبودی؟همونطور که توی پست اولم گفتم شما هرچی جلوتر میرید توی برنامه‌نویسی عمق بیشتری رو می‌بینید و بیشتر متوجه میشید که هیچی بلد نیستید!به همین دلیل منم دیگه خودم رو لایق آموزش دادن نمی‌دونستم و از این فضا کناره گیری کردم و فکر می‌کردم مطلبی نیست که بتونم اضافه کنم به جامعه ولی امروز تصمیم به شروع مجدد گرفتم، چرا؟ چون این کارو دوست دارم ? و درضمن قطعا یه سری چیزا هست که بتونم توضیحش بدم.اما از اشتباهات قبلیم سعی می‌کنم درس بگیرم و دیگه مثل قبل، خودم رو قرار نیست موظف بکنم هفته‌ای دو مقاله بنویسم بلکه هرموقع یه موضوعی اونقدر برام جذاب بود که برم راجع بهش بخونم، زمان بیشتری میذارم برای خوندن که بتونم راجع بهش بنویسم!اماااااا لطفا انتظار بی نقص بودن نداشته باشید و لطفا من رو اصلاح کنید اگر جایی اشتباه گفتم و اگر جایی باعث شدم چیزی رو به اشتباه یاد بگیرید حلال کنید! البته یه راه دیگش هم اینه که اگر خیلی می‌خواد منبع معتبری داشته باشید برای یادگیری منو آنفالو کنید :)دمتون گرم که خوندین، یا حقمحمد محمدعلیان - 16 مرداد 1399</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Fri, 07 Aug 2020 15:05:04 +0430</pubDate>
            </item>
                    <item>
                <title>چرا کمتر مینویسم؟</title>
                <link>https://virgool.io/@MohammadAlian_1383/%DA%86%D8%B1%D8%A7-%DA%A9%D9%85%D8%AA%D8%B1-%D9%85%DB%8C%D9%86%D9%88%DB%8C%D8%B3%D9%85-xnzkedkl3kb8</link>
                <description>عکس ربطی به نوشته نداردسلام :)الان که دارم این مطلب رو مینویسم از آخرین مقاله‌ای که نوشتم 16 روز میگذره و خلاصه تصمیم گرفتم تا دلیل کاهش تعداد نوشته هام رو بنویسم و یخورده از تاریخچه فعالیتم بگم.لُب مطلب: برای افزایش کیفیت محتوا!!آمدنم بهر چه بود؟توی مطلب اولم با عنوان &quot;حقایقی راجع به برنامه‌نویسی که گذرزمان بهم یاد داد! (1)&quot; نوشتم که برای یادگیری چیزای جدید و پرسنال برندینگ اومدم و می‌نویسم و واقعا هم همین‌طور بود اما بعد از یه مدت هدفم عوض شد و بیشتر داشتم مینوشتم چون یاددادن به بقیه برام جذاب بود و اصلا اون هدف های اولیم گاها یادم میرفت ولی همچنان یادگیری چیزای جدید پابرچا بود چون خود به خود اتفاق میوفتاد!بعد از گذشته یه مدت دیگه واقعا مطلب کم آورده بودم! و نمی‌دونستم چی بنویسم و چیکار بکنم یا اگر چیزی به ذهنم میومد بنظرم خیلی مفصل بود و حوصله نوشتنش رو نداشتم!ولی یخورده که جلوتر رفتم دیدم نه خیلیییی چیزا هست که می‌تونم بنویسم راجع بهش فقط یخورده باید از تله دانش دور می‌شدم!هدف: روزانه یک پستمن خوشبختانه یا متاسفانه آدم کمال‌گرایی هستم و دوست دارم همه چیز در بهترین سطح خودش یا نزدیک به اون باشه حداقل به همین خاطر تصمیم گرفتم روزی یه پست بنویسم تا کمیت باعث افزایش کیفیت بشه، ولی نه نتنها نشد بلکه همینطور داشت بدتر و بدتر و بدتر میشد!نکته:‌اگر میخواید کمیت باعث افزایش کیفیت باشه باید به پیشرفت کارِتون اهمیت بدید، هر قدمی که بر می‌دارید یه بهبود نسبت به قبل باید همراهش باشه.[نظر شخصی]بلد نیستی خب ننویسدر راستای همون هدف &quot;روزانه یک پست&quot; رفتم سراغ چیزایی که بلد نیستم تا یه چیزایی هم یادبگیرم بالاخره به همین خاطر شروع به نوشتن مجموعه مطالب SOLID کردم و این مطالب رو براساس محتواهای خارجی و ایرانی نوشتم در صورتی که خودم یکبار هم از این اصول استفاده نکردم!بخاطر همین کیفیتش از دید خودم به شدت پایینه :(مطالبی که بهشون افتخار می‌کنمچیزایی که قشنگ درک کرده بودم رو مطالب فوق العاده‌ای نوشتم براشون از دید خودم (البته در آینده‌ای نه چندان دور احتمالا این مطالب هم دیگه قابل افتخار نیستن!) https://virgool.io/@mhmda_83/%D8%AD%D9%82%D8%A7%DB%8C%D9%82%DB%8C-%D8%B1%D8%A7%D8%AC%D8%B9-%D8%A8%D9%87-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%DA%A9%D9%87-%DA%AF%D8%B0%D8%B1%D8%B2%D9%85%D8%A7%D9%86-%D8%A8%D9%87%D9%85-%DB%8C%D8%A7%D8%AF-%D8%AF%D8%A7%D8%AF-1-fy8gobe8tgp9  https://virgool.io/JavaScript8/%DA%86%D9%86%D8%AF%D8%AA%D8%A7-%D9%84%D8%A7%DB%8C%D8%A8%D8%B1%D8%B1%DB%8C-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%DA%A9%D9%87-%D8%A7%D8%AD%D8%AA%D9%85%D8%A7%D9%84%D8%A7-%D9%86%DB%8C%D8%A7%D8%B2-%D8%AE%D9%88%D8%A7%D9%87%DB%8C%D8%AF-%D8%AF%D8%A7%D8%B4%D8%AA-1-yfrnf3yxjyc3  https://virgool.io/JavaScript8/%D8%A7%D9%86%D9%BE%DB%8C%D8%A7%D9%85npm-%D8%AF%D8%B1-1500-%DA%A9%D9%84%D9%85%D9%87-htiagsi9cnvf مطلب بالا طولانی ترین مقاله من هست :) https://vrgl.ir/aDs5G  https://vrgl.ir/6PS5q  https://vrgl.ir/LeSRe  https://vrgl.ir/1PXtP اصل مطلببعد از گذشت زمان الان به این نتیجه رسیدم که وقتی یه مطلب عالی راجع به اصول SOLID هست چرا من باید بیام یه بی کیفیتش رو بنویسم که اونی که میخواد یادبگیره انتخابای بیشتری داشته باشه و خدایی نکرده تصمیم اشتباه بگیره؟چرا فک میکنم یکی با چوب بالا سرم وایساده میگه تولید محتوا بکنننننننن؟چرا باید کیفیت رو فدای کمیت کنم؟توصیه من به اونایی که می‌نویسن یا میخوان بنویسناگر داری یه مطلبی مینویسی و یه چیزی رو یاد میدی قبلش مطمئن شو که یکی بهتر از تو اینکارو نکرده باشه و درکل وقتی چیزی رو یادبده که واقعا بدونی که داری یه چیزی اضافه میکنی به دنیا و یه ارزش مثبت داری میذاری :)این چیز اضافه کردن میتونه قابل هضم کردن یه موضوع سنگین باشه حتی!دوست داری به بقیه کمک کنی؟ نوشتن تنها راهش نیستاگه کمک به بقیه رو دوست دارید می‌تونید توی گروه تلگرامی و در کل جامعه های مربوط به رشتتون فعال باشید و به سوال بقیه پاسخ بدید و کمکشون کنید، می‌تونید با کامنت گذاشتن زیر پست یکی حالش رو خوب کنید و کلی کار دیگه که فقط یخورده کافیه بهش فکر کنید.توصیه به خوانندگانمی‌تونید با مطالب بد هم یادبگیرید به شرط اینکه بلد باشید یادگیری رو یا بهتره بگم بخواید یادبگیرید!ببینید اون مطلب چرا بده و چه ویژگی هایی داشت تا بعدا دیگه به تور این‌طور مطالب نخورید!!در نظر داشته باشید همه می‌تونن بنویسن پس لزوما هرکی مینویسه خفن و کار درست نیست.و نکته دیگه اینکه برید از آدم کار بلد یادبگیرید آدمی که پختگی پشت مطالبش موج میزنه و آدمی که به عمل بسته باشه دانشش رو.حرف آخرمن از همه کسایی که توی این مدت با مطالب ضعیف من به اشتباه افتادن عذرخواهی می‌کنم.محمد محمدعلیان | 25 اردیبهشت 1399 - ایام الکرونا</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Thu, 14 May 2020 15:51:03 +0430</pubDate>
            </item>
                    <item>
                <title>ابزار Postman چیست؟</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%A7%D8%A8%D8%B2%D8%A7%D8%B1-postman-%DA%86%DB%8C%D8%B3%D8%AA-gaitripz70gb</link>
                <description>اول اینکه Postman در حال حاظر یه نرم‌افزار هست ولی چرا توی عنوان صریحاً ننوشتم؟ چون قبلا افزونه کروم بوده و ممکنه یه عده‌ای اون زمان اسمش رو شنیده باشین!همونطور که متوجه شدید الان یه مدتیه که افزونه Postman منسوخ شده و دیگه باید سوییچ بکنید روی نرم‌افزارش که از اونجایی که با Electron.js توسعه داده شده روی پلتفرم‌های ویندوز، مک و لینوکس در دسترستون هست :)چرا از نرم‌افزارش استفاده کنیم؟چون می‌تونید مستقیما با cookie ها کاربکنید.بر خلاف افزونه کرومش افزونه مجزایی برای استفاده از قابلیت &quot;interceptor&quot; نمی‌خواد.پراکسی داخلی داره که می‌تونید باهاش ترافیک شبکه رو capture کنید.دیگه محدودیت های کروم برای منوبار رو نداره و شما خیلی ساده می‌تونید برای بررسی نسخه جدید اقدام کنید، پنجره و تب جدید Postman بسازید و تنظیمات رو دستکاری کنید :)می‌تونید هدرهایی مثل Origin و User-Agent بفرستید که توی کروم دسترسی به اینا قفله ?گزینه &quot;don&#x27;t follow redirects&quot; رو داره که میگه آقا اگه ریکوئست ریدایرکت شد، شما نرو اونطور جاها و این باعث میشه دیگه ریسپانس‌های سری 300 نداشته باشید، برای استفاده از این قابلیت توی کروم باید افزونه &quot;interceptor&quot; رو داشته باشید.نرم‌افزارش یه console داخلی داره که می‌تونید جزئیات ریکوئست‌هایی که ارسال می‌کنید رو ببینید.چیکارا می‌کنه؟وقتی میرید توی سایت یه جمله جلوی چشمتون اونم اینهThe Collaboration Platform for API Developmentیعنی یه بستر داریم که می‌تونیم به صورت تیمی و مشارکتی API توسعه بدیم :) به همین باحالی!ولی یخورده انتزاعی هست و جزئیات بیشتری رو میطلبه.وقتی توی سایت یخورده میاید پایین‌تر نوشته &quot;What is Postman&quot; و پایینش اومده 6 تا ویژگی رو لیست کرده که به گفته خودش باعث میشه هر مرحله از توسعه API رو ساده‌تر بکنه و مشارکتی کار کردن رو ساده و موثر بکنه که در نتیجه باعث توسعه API های بهتر به شکل سریع‌تر میشه :)حالا بذارید ببینیم این 6 تا ویژگی که باعث میشه چنین ادعایی بکنه چیه!؟API ClientAutomated TestingDesign &amp; MockDocumentationMonitorsWorkspaces[عناوین بالا رو فارسی می‌نویسم برای اینکه متن چپ به راست نشه و به هم بخوره]اِی‌پی‌آی کِلایِنت: بعد از توسعه یک API شما قطعا نیاز دارید که ببینید اون کار می‌کنه یا نه، حالا نیاز به یه API Client دارید که باهاش به API خودتون ریکوئست بفرستید و response رو بررسی کنید و خلاصه اقدامات لازم رو انجام بدید :)حالا شما چندتا انتخاب دارید: بیاید مستقیم توی کروم ریکوئست بزنید(اگر درخواستتون GET هست)، بیاید خودتون یه کلاینت بنویسید(اپ موبایل یا وب‌سایت یا ...) که بیاد به API ریکوئست بزنه یا اینکه از API Clientهای آماده استفاده کنید مثل Postman, Swagger و یا یه سری افزونه های کروم و VSCode و ... استفاده بکنید.Postman بهتون این امکان رو میده که ریکوئست هایی از نوع REST, SOAP و GraphQL بزنید :)آتومِیتِد تِستینگ: فرض کنید یه چندتا endpoint جدید اضافه کردید یا شایدم یک‌سری تغییرات توی بخش‌های مختلف ایجاد کردید، اینجا لازمه که تست بکنید ببینید وضعیت API ها مثل قبل پایداره یا نه، حالا می‌تونید اینکار رو دستی انجام بدید که خیلی رو مُخه یا با فیچر Automated Testing جناب Postman بیاید یه‌سری تست بنویسید براش و بعد فقط رانش کنید :)))دیزاین اَند ماک: قبل از اینکه شروع کنید به توسعه back-end می‌تونید اون رو طراحی کنید به وسیله شبیه سازی endpointهاتون و ریپانس‌هاش :)داکیومِنتِیشن: می‌تونید مستندات قابل فهم برای ماشین بسازید و اونا رو منتشر کنید، اینجوری استفاده ازش هم راحت میشه :) مثلا در حد فشردن چندتا دکمه!مانیتورز: می‌تونید توی بازه‌های زمانی مختلف تنظیم کنید که خودکار به APIهاتون ریکوئست زده بشه تا مثلا ببینید response time چقدره یا اصلا سالمه یا نه!وُرک‌اِسپِیسِز: یه محیط اشتراکی برای توسعه و استفاده از APIها و مشارکت(collaborate) در لحظه(real-time) با سیستم version controlای که توی خودش داره!حالا می‌تونیم بهش حق بدیم بابت اون ادعا!چرا Postman رو انتخاب کنیم؟رایگانه و شروع کار باهاش سادست.پشتیبانی گسترده از همه APIها و schemaها رو داره.توسعه پذیره و می‌تونید بر اساس نیازهاتون شخصی سازیش کنید.پشتیبانی و کامیونیتی قوی‌ای که داره.گستردگی استفادش توی ایران بیشتر از بقیه نرم‌افزارهاست(اینو خودم اضافه کردم)تمام اطلاعات این مطلب از وبسایت خود Postman برداشته شده و من صرفا یخورده قابل هضم ترش کردم.محمد محمدعلیان | 9 اردیبهشت 1399 -- ایام الکرونا!</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Tue, 28 Apr 2020 12:13:55 +0430</pubDate>
            </item>
                    <item>
                <title>ایونت visibilitychange در جاوااسکریپت</title>
                <link>https://virgool.io/@MohammadAlian_1383/%D8%A7%DB%8C%D9%88%D9%86%D8%AA-visibilitychange-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-mrsgrwobfxjt</link>
                <description>سلام و خداقوت به همه javascript دولوپرای عزیز :)توی این مطلب میخوام یکی از ایونت‌های کاربردی ولی کمتر شناخته شده جاوااسکریپت به اسم visibilitychange رو معرفی بکنم.کی فراخوانی میشه؟این ایونت روی آبجکت document زمانی فراخوانی میشه که وضعیت نمایش محتوای صفحمون حالتش عوض بشه! مثلا اگر الان از این تب به تب google.com برید وضعیت نمایش این تب تغییر پیدا می‌کنه به hidden و اگر برگردید وضعیتش به visible تغییر پیدا می‌کنه!کاربردش چیه؟مثلا اینستاگرام وقتی شما داشته باشید یه ویدیو رو ببینید و برید به یه تب دیگه ویدیو رو استوپ می‌کنه.اگر یک ویدئوپلیر توی وبسایتتون داشته باشید قاعدتا زمانی که کاربر توی وبسایت نیست اون ویدئو باید پخشش متوقف بشه و وقتی دوباره برگشت ادامه ویدئو پخش بشه...نحوه استفادهبه کد زیر دقت کنید https://gist.github.com/mhmda-83/fe546bc3bd2849003f7d34dd03e68067 این کد کاربردش اینه که تعیین می‌کنه کاربر چندثانیه هست که توی این تب نیست و داره جاهای دیگه سِیر می‌کنه!یه نکتهوضعیت visible بودن صفحه توی آبجکت event قرار نداره ولی با استفاده از document.visibilityState می‌تونیم وضعیت رو بفهمیم و براساس اون دستورات مختلف خودمون رو اجرا بکنیم.جایزهآموزش ساخت ایونت اختصاصی =&gt; آپارات | یوتوبمتدهای find, map, reduce =&gt; اینستاگراموبسایت pluralsight دوره‌هاش رو تا انتهای آپریل 2020 رایگان کرده!محمد محمدعلیان | 19 فروردین 1399 | ایام الکرونا!</description>
                <category>محمد محمدعلیان</category>
                <author>محمد محمدعلیان</author>
                <pubDate>Wed, 08 Apr 2020 15:33:31 +0430</pubDate>
            </item>
            </channel>
</rss>