<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های علیرضا</title>
        <link>https://virgool.io/feed/@alirezax69prom</link>
        <description>سعی میکنم هرچیز مفیدی که بلدم رو به بقیه هم یاد بدم :)</description>
        <language>fa</language>
        <pubDate>2026-04-15 10:26:34</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2671890/avatar/ZWkywV.png?height=120&amp;width=120</url>
            <title>علیرضا</title>
            <link>https://virgool.io/@alirezax69prom</link>
        </image>

                    <item>
                <title>MQTT</title>
                <link>https://virgool.io/@alirezax69prom/mqtt-bmtdvyuipo3n</link>
                <description>Introچندوقتی هست که درگیر یادگیری RabbitMQ هستم که از پروتکل های مختلفی پشتیبانی میکنه و خب یکی از اونا MQTT هست. شاید سوال این باشه که RabbitMQ چیه؟یک مسیج بروکر به حساب میاد! ایده ی مسیج بروکر ها اینه که به عنوان یک واسطه بین سرویس های مختلف  پیام هارو بین سرویس ها منتقل کنن. با این وجود سرویس A که با پایتون نوشته شده میتونه با سرویس B که با Nodejs نوشته شده بدون مشکل حرف بزنه.فرض کن یک سنسور دماسنج هر چندوقت یکبار باید دمای محیط رو بفرسته به یک یا چند سرویس. شاید تو نگاه اول پروتکل هایی مثل HTTP یا WebSocket بیاد تو ذهنت که واقعیت امر اینه خیلی بکار نمیان! چون سربار زیادی دارن و خب برای یک سنسور که از نظر سخت افزاری محدوده خیلی بهینه نیست. یا حتی موبایل ها رو درنظر بگیر که بحث مصرف باتری توشون هم مهمه. ایده ساخت پروتکل MQTT ازجایی شروع شد که میخواستن دیتای سنسورِ لوله های نفت رو مانیتور کنن و مشکل این بود که سنسور ها هم از نظر سخت افزاری محدود بودن و هم از نظر پهنای باند و مصرف باتری.Let&#x27;s deep dive!پروتکل MQTT از پترن publish/subscribe پیروی میکنه. مسیج بروکر این وسط نقش یک واسطه رو بین فرستنده و گیرنده داره. مفهوم تاپیک (topic) تو این پروتکل باعث میشه فرستنده ها به پیام هایی که میفرستن مسیر بدن. با این وجود وقتی یک فرستنده تو یک تاپیک خاص یک پیام ارسال میکنه بروکر اونو به گیرنده های مربوط به اون تاپیک میرسونه. بریم سراغ تخته سیاهمون :)البته این پروتکل یک ارتباط bi-directional رو فراهم میکنه که این یعنی گیرنده ها هم میتونن فرستنده باشن و به تاپیک های مختلف پیام منتشر کنن. همچنین این معماری باعث شده فرستنده ها و گیرنده ها از هم مستقل باشن و بدون اینکه از هم چیزی بدونن با هم در ارتباط باشن که به لطف بروکر عزیزمونه :)حالا اگه به یک تاپیک که هیچ گیرنده ای نداره یک پیام ارسال کنیم چه اتفاقی میوفته؟ درحالت عادی از بین میره ولی راه هایی هم هست که بشه پیام رو حفظ کرد. در نتیجه تا زمانی که گیرنده ای نیست پیام ها میرن تو یک صف و به محض اینکه یکی اون تاپیک رو دونبال کنه بروکر پیام هارو بهش میفرسته. Quality of Serviceبیاین یکم درباره ی QoS یا Quality of Service حرف بزنیم. در واقع سه لول اصلی داریم که مشخص میکنه پیام چطوری به سابسکرایبر ها برسه.1. Fire and forget توی لول ۰ فرستنده ها انتظار تایید ندارن و این یعنی مهم نیست پیام به گیرنده رسیده باشه یا نه! پیام یکبار فرستاده میشه و از بین میره.QoS 02. Acknowledged deliveryتو این لول تمرکز اصلی اینه که پیام حداقل یکبار تحویل داده شده باشه. وقتی فرستنده پیامی رو ارسال میکنه یک کپی رو پیش خودش نگه میداره و منتظر میمونه یک پَکِت PUBACK دریافت کنه درغیر این صورت پیام دوباره فرستاده میشه. حالا چرا حداقل یکبار؟ فرض کن فرستنده وقتی پیام رو ارسال میکنه از دسترس خارج میشه!‌ در نتیجه با اینکه گیرنده پیام رو گرفته،‌ فرستنده پکت PUBACK رو دریافت نکرده و وقتی دوباره میاد تو شبکه سعی میکنه دوباره پیامش رو بفرسته.QoS 13. Assured deliveryلول ۲ بالاترین لول به حساب میاد و تضمین میکنه هر پیام از فرستنده دقیقا یکبار به گیرنده رسیده باشه. تو قدم اول فرستنده یک پیام ارسال میکنه و صبر میکنه یک پکت PUBREC از گیرنده دریافت کنه. وقتی گیرنده پکت PUBREC رو میفرسته منتظر میمونه فرستنده یک پکت PUBREL برگردونه. وقتی فرستنده پکت PUBREL رو به گیرنده ارسال کرد دیگه پیام مطمعنن ارسال شده و درنهایت گیرنده یک پکت PUBCOMP میفرسته و تموم!QoS 2Conclusionشاید تصور خیلی ها از RabbitMQ صرفا یک صف باشه ولی خب همونطور که دیدیم یک مسیج بروکر هست و از پروتکل های مختلفی پشتیبانی میکنه. میتونین از این لینک درباره ی بقیه ی پروتکل ها مطالعه کنین. موفق باشین!Wiki | Reference 1 | Reference 2 </description>
                <category>علیرضا</category>
                <author>علیرضا</author>
                <pubDate>Mon, 06 Nov 2023 00:48:58 +0330</pubDate>
            </item>
                    <item>
                <title>Data Structures - Linked List</title>
                <link>https://virgool.io/@alirezax69prom/data-structures-linked-list-oqrdayvmtzyr</link>
                <description>Introتوی این قسمت از سری ساختار داده میخوام درباره ی لینک لیست صحبت کنم. بر خلاف آرایه ها که به random-access بودن مشهورن و آیتم ها توی مموری کنار هم قرار میگیرن لینک لیست ها از نود های جدا از هم تشکیل شدن و با pointer  به هم وصل میشن.Array vs Linked ListLet&#x27;s go deeper!معمولا آرایه جزو اولین ساختار داده هایی هست که باهاش آشنا میشین چون تو اکثر زبان ها وجود دارن. توی آرایه شما میتونین با ایندکس به آیتم ها دسترسی داشته باشین و نیاز نیست حتما iterate کنین. توی لینک لیست شما به هیچ عنوان نمیتونین به یک آیتم بصورت مستقیم اشاره کنین (‌ مثلا با ایندکس )‌ و برای اینکه به یک آیتم خاص برسین باید اصطلاحا از Head شروع کنین و iterate کنین. منظور از Head همون اولین نود هست. دقیق تر بخواییم بررسی کنیم شما زمانی که آیتمِ وسطِ یک آرایه رو حذف میکنین (یا اضافه کنین) ایندکس ها تغییر میکنین و همین باعث میشه O(n) رو داشته باشه چون بسته به طول آرایه بقیه آیتم ها باید جاشون تغییر کنه. توی لینک لیست عملیات اضافه و حذف کردن O(1) رو دارن و چرا؟‌ چون همه ی نود ها به هم لینک شدن و اصلا اهمیتی نداره کجا مموری قرار دارن و در این صورت مثلا اگه بخواییم یک آیتم رو به هر جای لیست اضافه کنیم فقط کافیه با لینک کردن نود ها با هم سر و کار داشته باشیم. بریم سراغ تخته سیاه :)حذف یک آیتم از آرایههمونطور که میبینین بعد از اینکه Item 3 رو حذف کردم، Item 4 مجبور شد بیاد تو ایندکس ۲ و حالا فرض کن آرایت چند هزار تا آیتم داشته باشه :) بیاین ببینم تو لینک لیست چه اتفاقی میوفته!چه باحال، توی لینک لیست برای حذف item 3 بدون هیچ عملیات اضافه ای فقط item 2 به item 4 لینک شد و  همینطور که معلومه از آرایه ها بهینه تر هست.لطفا این نکته رو در نظر داشته باشین که هر ساختار داده ای یکجا کاربرد داره و اینکه من دارم آرایه ها رو با لینک لیست مقایسه میکنم صرفا برای اینه که شما بهتر درکش کنین. اگه بخوام صادق باشم خودم تاحالا نیاز نشده بخوام از لینک لیست ها استفاده کنم :)Types of Linked listلینک لیست ها معمولا به یک شکل نیستن و انواع مختلفی دارن. چیزی که من براتون توضیح دادم اصطلاحا Singly Linked-List هستن که یعنی کی طرفه ان (یک نود فقط به نود بعدیش لینک شده). Doubly Linked-List ها به لینک لیست هایی گفته میشن که یک نود هم به نود بعدی لینک شده و هم به نود قبلی :)  و در آخر یک نوع مشهور دیگه هست که به Circular Linked-List ها مشهورن که یعنی آخرین نود (tail) همیشه به اولین نود (head) لینک شده (یک ساختار دایره ای رو فرض کنین).Let&#x27;s codeبیاین یک لینک لیست بنویسیم یا دقیق ترش یک singly linked-list تا بفهمیم دقیقا داستان چیه :) هرچند که من تصمیم دارم با جاوااسکریپت بنویسم اما اگه برنامه نویسی رو درک کرده باشین این نباید براتون مسئله ی خاصی باشه ( زبان های برنامه نویسی صرفا یکسری ابزار هستن ).اول از همه ما به یک نود احتیاج داریم که بتونه یک مقدار تو خودش ذخیره کنه و ریفرنسِ نودِ بعدی رو تو خودش داشته باشه.Node Classحالا یک کلاس احتیاج داریم که Head رو تو خودش نگه داره و همچنین عملیات حذف و اضافه کردن رو انجام بده. Linked List Classبیاین اول یک متد برای اضافه کردن آیتم به لیستمون بنویسیم. روند کار به این صورته که باید از Head شروع کنیم و خودمون رو به آخر لیست برسونیم (‌ هروقت next مقدار null داشته باشه یعنی نود دیگه ای وجود نداره ) و یک نود جدید به آخرین نود لینک کنیم.Add a new item to linked listو حالا یک متد نیاز داریم برای حذف یک آیتم. برای اینکار ما به نود قبل و بعدِ نودی که میخواییم حذف کنیم احتیاج داریم تا این دوتارو لینک کنیم به همدیگه. ًRemove an item from linked listو در آخر به یک متد نیاز داریم تا آیتم های لیستمون رو برامون پرینت کنه.Print itemsخیلی متد های متنوعی میشه نوشت که خودتون میتونین بر اساس نیازتون بنویسین و اگه از کدهایی که زدم چیزی سر در نمیارین ایرادی نداره‌، سعی کنین خودتون هم بنویسین و باهاش کار کنین تا دستتون بیاد. یک توصیه ی دیگه ای که دارم اینه که روی کاغذ بکشین لینک لیستتون رو،‌ اینجوری قشنگ میفهمین کجای کارین.Performanceبرای اینکه از نظر بهینه بودن لینک لیست هارو بررسی کنیم بیاین از دسترسی به آیتم ها حرف بزنیم. برخلاف آرایه  برای دسترسی به یک آیتم (نود) توی لینک لیست مجبورم از Head شروع کنم و تا جایی که لازم باشه iterate کنم و از این نظر O(n) رو خواهیم داشت.اما برای حذف و اضافه کردن چی؟ لینک لیست برای این دوتا عملیات خیلی بهینه هست و O(1) رو داره. همونطور که دیدیم فقط با لینک کردن میشه یک آیتم به لیست اضافه کرد یا حذف کرد.لینک لیست ها یک مزیت دیگه ای هم دارن اگه دقت کرده باشین محدودیتی از نظر طول ندارن. حتی لازم به resize کردن هم نیست (تو زبان های سطح پایین آرایه ها طولی از قبل  تعریف شده دارن) که خب از این نظر هم هرچقدر هم سایز لینک لیست تغییر کنه نیاز به عملیات خاصی نیست و O(1) رو داره. و در آخر برای ساختار داده هایی مثل Queue و Stack از لینک لیست استفاده میشه که تو نوشته های بعدیم دربارشون حرف میزنم.Endبازم به آخر داستان رسیدیم :) امیدوارم  این مقاله هم براتون مفید بوده باشه. توصیه همیشگیم اینه که خودتون درباره ی چیزها بخونین و سرچ کنین. هیچ مقاله یا منبع مشخصی همیشه کامل نبوده و نیست. موفق باشین!Google Data Structurehttps://www.freecodecamp.org/news/how-linked-lists-work/https://www.youtube.com/watch?v=Hj_rA0dhr2I&amp;amp;pp=ygULbGlua2VkIGxpc3Q%3D</description>
                <category>علیرضا</category>
                <author>علیرضا</author>
                <pubDate>Fri, 29 Sep 2023 14:28:11 +0330</pubDate>
            </item>
                    <item>
                <title>Data Structures - HashMaps</title>
                <link>https://virgool.io/@alirezax69prom/data-structures-hashmap-vsgjn1bgow6u</link>
                <description>Introزمانی که تازه شروع کردم برنامه نویسی رو یاد بگیرم یکی از چیزایی که فکر میکردم دونستنشون به هیچ دردی نمیخوره انواع ساختار داده بود. وقتی مثلا یاد میگرفتم لینک لیست چیه، بعدش با خودم میگفتم خب که چی :)البته نمیخوام بگم برنامه نویس کهنه کاریم، هنوز یکسال نشده که شروع کردم :) ولی خب درحال حاضر حداقل درک و اهمیت ساختار داده برام روشن تر شده. توصیه ی شخصی من اینه که قبل از یادگرفتن ساختار داده و حتی خوندن بقیه ی این مقاله، اول درک کنین Big O notation چی هست. بهتون دید خوبی میده.What are HashMaps?یکی از محبوب ترین ساختار های داده که معمولا لازم نیست پیادش کنین HashMap ها هستن. اگه با زبان پایتون آشنا باشین همون دیکشنری خودمونه :) که یک ساختار key-value داره. Dictionary In Pythonپشت صحنه ی این ساختار داده، از یک آرایه استفاده میشه و یک فانکشن که کارش هش کردن کلید هست. ولی چرا مستقیم از یک آرایه استفاده نمیکنیم؟ برای هر آیتمِ داخلِ یک آرایه هم یک ایندکس داریم و هر زمان که لازم باشه با ایندکس بهش دسترسی خواهیم داشت. جواب اینه که آرایه ها طول مشخصی دارن :) ولی توی این ساختار داده ما عملا محدودیتی نداریم و لازم نیست مشخص کنیم قراره چندتا کلید داشته باشیم. همچنین دیگه لازم نیست با ایندکس ها سرکار داشته باشیم، چون کلیدمون میتونه یک استرینگ خوانا و قابل فهم تر باشه. ولی اگه دقیق تر شیم توی بعضی از عملیات HashMap ها خیلی بهینه تر از بقیه ی ساختار های داده هستن که آخر این مقاله خواهیم دید.  HashMap(v1)همونطور که میبینین سمت چپ کلیدهامون رو داریم. اون وسط یک فانکشنِ هش داریم که هر کلیدی بهش بدیم تبدیل به یک عدد میکنه و در آخر سمت راستمون یک آرایه داریم با سایز مشخص.به عنوان مثال میخواییم کلیدی به اسم Alireza تعریف کنیم که مقدارش banana باشه. توی مرحله اول کلیدمون(Alireza) توسط فانکشنِ هش تبدیل به یک عدد میشه. این عدد درواقع همون ایندکسی خواهد بود که قراره مقدارِ کلیدمون(banana) رو توی آرایه (سمت راست توی تصویر) ذخیره کنیم. با این حساب هروقت هشِ Alireza رو حساب کنیم به یک عدد(ایندکس) یکسان میرسیم و مقدارش رو از توی آرایه برمیگردونیم.Collision in HashMaps...فانکشنِ هَشِمون که تو تصویر بالا دیدین، درنهایت عددی که تولید میکنه توی محدودیه آرایمون هست. پس اگه آرایه ی من طولش 5 باشه، فانکشنِ هش عددی خارج از 0 تا 4 نخواهد داد. سوالی که پیش میاد اینه که بالاخره دوتا کلید متفاوت به یک عدد ختم میشن و خب چطوری باید این مسئله رو حل کنیم؟ اگه با الگوریتم های هش آشنا باشین، یکی از مهم ترین خصوصیت هایی که باید داشته باشن اینه که نباید به ازایه دوتا ورودی متفاوت به یک خروجی یکسان بدن. اصطلاح Collision یا برخورد وقتی به وجود میاد که دوتا ورودی متفاوت هش یکسانی دارن ولی چه ربطی به HashMap داشت؟ تو HashMapها هم بالاخره دوتا کلید خواهیم داشت که به یک عدد (ایندکس) اشاره کنن. چرا که فانکشنِ هش عددی که تولید میکنه محدود به سایز آرایه هست. بیاین یکم HashMapمون رو آپدیت کنیم! HashMap(v2)یکم پیچیده شد:) ولی بیاین ببینیم چی شده دقیقا. سمت چپ همون ساختار حفظ شده و فانکشنِ هش هم سرجاشه. اما سمت راست کلا تغییر کرده. توی مثال قبل ایندکس ها به مقدارِ کلیدامون اشاره داشتن ولی الان هرکدوم از ایندکس ها یه یک آرایه اشاره دارن. تو این پیاده سازی اول هشِ اون کلید رو حساب میکنم و توی ایندکسِ مربوطه که یک آرایه هست کلید و مقدار رو باهم توی یک آرایه ذخیره میکنیم. با این حساب دیگه مشکل collision یا برخورد حل میشه. هر زمان که بخواییم دونبالِ مقدارِ کلیدی بگردیم هم کافیه با هش کردن کلید، توی آرایهِ مربوطه بگردیم دونبال مقدار کلیدمون.Let&#x27;s code!از اونجایی که خودم آدمی هستم که تا کد نزنم آروم نمیگگیرم :) گفتم باهم یه Hash Map بنویسیم و درک کنیم چه اتفاقی داره میوفته. تصمیم دارم با Javascript بنویسمش و برای هر مرحله یک توضیح مختصر هم میدم که چیکار کردم ولی انتظار میره که درک نسبتا خوبی از برنامه نویسی داشته باشین تا بفهمین چی شده :)Hash Functionکاری که این فانکشن میکنه اینکه یک کلید میگیره و یک سایز، که سایز آرایه ای خواهد بود که Hash Map قراره پشت صحنه ازش استفاده کنه و درنهایت یک عدد برمیگردونه که تو محدوده ی سایر آرایمون خواهد بود.پیاده سازی یک HashMap تعریف کردیم که یک storage داره که همون آرایمونه و یک size که سایز آرایمونه. اضافه کردن کلیدفانکشن add یک کلید و مقدار میگیره. کلید رو هش میکنه که همون ایندکسمون خواهد بود. و درنهایت کلید و مقدار رو توی اون ایندکس که یک آرایه هست ذخیره میکنه.گرفتن مقدار کلیدفانکشن get  توی ورودی یک کلید میگیره. همونطور که انتظار میده اونو هش میکنه و در نهایت توی اون ایندکسِ مربوطه که یک آرایه هست، حلقه میزنه و درصورت پیدا کردن کلید، مقدارش رو میگردونه. حذف کردن کلیدو در آخر یک فانکشن remove تعریف کردیم که کارش حذف کردن کلید هست. یه این صورت که توی ورودی یک کلید میگیره و طبق معمول هش میکنه، و توی اون ایندکس که یک آرایه هست با متد filter کلید رو حذف میکنه.اگه با خوندن کد و توضیحات نفهمیدین چی شده، یک ادیتور باز کنین و کدش رو بنویسین، اینجوری بهتر میفهمین چی به چیه :)Performanceروشی که ما HashMapمون رو نوشتیم قطعا خیلی بهینه و اصولی نبوده و همچنین تمرکزمون هم بیشتر روی پیاده کردنش بود. ولی درکل توی یک HashMap عملیات اضافه کردن، حذف کردن و گرفتن یک کلید بطور متوسط O(1) رو داره یا به اصطلاح constant time هست و خب همونطور که معلومه خیلی بهینه هست.And in the end...امیدوارم مفید بوده باشه :» توصیم اینه که دربارش حتما سرچ کنین و عمیق تر شین. اینجا من فقط میتونم یک درک کلی بدم بهتون و بقیه ی راه رو خودتون باید برین. موفق باشین :)https://www.youtube.com/watch?v=eMymKAFYaCshttps://www.youtube.com/watch?v=h2d9b_nEzoAhttps://leetcode.com/explore/learn/card/hash-tablehttps://www.youtube.com/watch?v=F95z5Wxd9ks</description>
                <category>علیرضا</category>
                <author>علیرضا</author>
                <pubDate>Sat, 16 Sep 2023 18:21:57 +0330</pubDate>
            </item>
                    <item>
                <title>ارور cors دیگه چی بود!</title>
                <link>https://virgool.io/@alirezax69prom/%D8%A7%D8%B1%D9%88%D8%B1-cors-%D8%AF%DB%8C%DA%AF%D9%87-%DA%86%DB%8C-%D8%A8%D9%88%D8%AF-qp6kbvgtg5sv</link>
                <description>زمانی که یک ریکوئست به سمت یه سرور ارسال میشه ( تو مرورگرتون )،  SOP که مخفف کلمه ی Same-Origin Policy هست فقط درصورتی که دامنه، پورت و پروتکل مبدا با مقصد یکسان باشه اجازه ی ارسال ریکوئست رو میده.مثلا اگه سایتی با ادرس https://a.com یه ریکوئست به https://b.com  ارسال کنه، سیاست SOP این درخواست رو بلاک خواهد کرد (چون دامنه ی متفاوتی دارن). ولی با ورود مکانیزم CORS که مخفف کلمه ی Cross-Origin-Resource-Sharing هست باعث میشه سخت گیریه سیاست SOP کمتر بشه تا دوتا Origin متفاوت بتونن تحت یک شرایطی به هم درخواست بدن.پس ارور CORS اساسا زمانی اتفاق میوفته که قرار باشه دوتا Origin متفاوت به هم درخواست بدن. البته برخوردن به این مشکل بستگی به کلاینتی که ازش درخواست میفرستین هم داره که به عنوان مثال مرورگر ها روی این موضوع حساسن ولی ابزار هایی مثل Postman اهمیتی به این موضوع نمیدن و شما به این ارور نخواهید خورد. در واقع کلاینت تصمیم میگیره به این مسئله توجه کنه یا نه.What are preflight requests?خب حلا برای اینکه مکانیزم CORS به ما این اجازه رو بده که به یک Origin متفاوت درخواست بدیم، مرورگر قبل از اینکه درخواست اصلی شما رو به سرور بفرسته، خودش یه ریکوئست تحت عنوان OPTION میفرسته تا مطمئن شه درخواست شما از نظر سرور معتبر هست یا نه! به این نوع درخواست که از طرف مرورگر انجام میشه اصطلاحا میگن Preflight Request که اگه رد بشه مرورگر اجازه فرستاد درخواست اصلی رو نمیده و اینجاس که شما با یه ارور رو مخی به نام CORS مواجه میشین :)CORS ErrorHeaders that are sent in a preflight requestاینکه تو یه درخواست OPTION مروگر چی میفرسته رو میخوام توضیح بدم که چیزی نیست جزء یکسری هدر!Origin: دامنه ای که ازش درخواست رو ارسال میکنینAccess-Control-Request-Headers: هدر هایی که قراره ست کنینAccess-Control-Request-Methods: متدی که قرار درخواست ارسال باهاش بشهو جوابی که سرور به درخواست OPTION میده هم چیزی جزء یه سری هدر نیست :)Access-Control-Allow-Origin: دامنه هایی که مجاز هستن درخواست بدنAccess-Control-Allow-Headers: هدر هایی که یک درخواست مجاز هست ارسال کنهAccess-Control-Allow-Methods: متد هایی که مجاز هست باهاش ریکوئست ارسال بشهالبته ممکنه که هدر های دیگه ای هم تو جواب ببینم که در ادامه میگم چیا هستن ولی به هر حال تا الان تا حدود خوبی اشنا شدیم.Which requests require preflight?همونطور که گفتم مرورگر یک درخواست OPTION میفرسته، اما یکسری شرایط خاص داره که اگه شامل موارد زیر باشه، دیگه خبری از درخواست preflight نخواهد بود. درخواست با یکی از متد های GET, HEAD یا POST باشه.هدر هایی که ارسال میشه محدود به Content-Type, Content-Language, Accept,   Accept-Language باشه.و همچنین Content-Type شامل application/x-www-form-urlencoded, text/plain, multipart/form-data باشه.List of response headersهمونطور که اشاره کردم جوابی که سرور در یک درخواست preflight میده، شامل موارد بیشتری میشن که اینجا یه لیستی از همشون رو براتون اوردم.Access-Control-Allow-Origin: شامل دامنه ای که سرور درخواست هارو از اون origin میپذیره.2.  Access-Control-Allow-Methods:نشون میده سرور از کدوم متدها های HTTP پشتیبانی میکنه.3.  Access-Control-Allow-Headers:هدر های مجاز هستن در یک درخواست ست بشن.4.  Access-Control-Allow-Credentials:اگه مقدارش True باشه به این معنیه که کد های ران شده توسط مرورگر به cookie ها، authorization header ها و یا به TLS client certification ها دسترسی خواهند داشت.5.  Access-Control-Max-Age:درخواست های preflight توسط مرورگر کش میشن، که این هدر مدت زمان کش رو مشخص میکنه.6.  Access-Control-Expose-Headers:مشخص میکنه چه هدر هایی میتونن در معرض کد های ران شده توسط مرورگر باشن.End of story!امیدوارم خوندن این پست براتون مفید بوده باشه. اگه جایی اشتباه کردم واقعا معذرت میخوام و اگه تو کامنت بنویسین حتما تصحیح میکنم. شاد و خندون باشین :)Referencesdeveloper.mozilla.org</description>
                <category>علیرضا</category>
                <author>علیرضا</author>
                <pubDate>Fri, 04 Aug 2023 17:08:29 +0330</pubDate>
            </item>
                    <item>
                <title>MongoDB backup tutorial (Basic)</title>
                <link>https://virgool.io/@alirezax69prom/mongodb-backup-tutorial-basic-ol74kitdvw2y</link>
                <description>گفتم حالا که دارم درباره ی بک آپ گرفتن مطالعه میکنم، چیزایی که یاد میگیرم رو اینجا هم منتشر کنم :)  من علیرضام و  این اول پست آموزشی من به حساب میاد و امیدوارم مفید هم باشه براتون.Introروش های مختلفی برای بک آپ گرفتن از دیتابیس هاتون وجود دارد که به طور کلی به دو شاخه ی Logical و Physical تقسیم میشن. تو روش Logical خود دیتابیس یکسری API به ما میده که که به صورت خودکار دیتاها رو میخونه و برمیگردونه که معمولا تو فایل هایی با پسوند json, bson یا csv ذخیره میکنه. همونطور که معلومه اگه از حجم زیادی از دیتا میخواییم بک آپ تهیه کنیم این روش زیاد کارآمد نیست و فشار زیادی رو تحمیل میکنه که در این صورت باید به روش دوم پناه ببریم. من تو این پست فعلا کاری بهش ندارم :) اما در روش Physical که بهش Filesystem backup هم میگن یک کپی یا snapshot از فایل های دیتابیس به کمک یکسری ابزار میگیریم.درضمن تو این مقاله من از MongoDB ورژن 6.0.3 استفاده کردم. بریم ببینیم چه خبره! Mongodumpابزاری که تو روش Logical برای بک آپ استفاده میشه Mongodump هست که اگه نصب ندارین میتونین از این لینک دانلود کنین. این ابزار خودش به دیتابیس وصل میشه و دیتاهارو میخونه و درنهایت یکجا ذخیره میکنه که بعدا دوستش Mongorestore (بعدا میفهمیم چی هست) در صورت نیاز بتونه فایل های بک آپ رو بخونه و restore کنه. Optionsمثل خیلی از ابزار های دیگه، Mongodbump هم یکسری سوئیچ داره که من مهم هاش رو براتون اوردم:برای بحث connect شدن به دیتابیس ار سوئیچ uri– استفاده میکنیم.برای اینکه تو خروجی جزئی تر بنویسه که داره چیکار میکنه  از سوئیچ v- استفاده کنیم. (اصطلاحا پرحرف بشه)برای اینکه تعیین کنین از چه دیتابیسی میخوایین بک آپ بگیرین یا باید تو uri مشخص کنین یا از سوئیچ db– استفاده کنین. ( اگه معلوم نکنین بطور خودکار از کل دیتابیس ها بک آپ گرفته میشه)با سوئیچ c- میتونین مشخص کنین از کدوم کالکشن خاص میخوایین بک آپ بگیرین. (اگه مثل بالا مشخص نکنین بطور خودکار از همه ی کالکشن ها بک آپ گرفته میشه)با سوئیچ out– مشخص میکنین فایل های بک آپ تو چه دایرکتوری ذخیره بشن.با سوئیچ archive– میتونین خروجی رو بصورت یک فایل از نوع آرشیو ذخیره کنین. (سوئیچ های out– و archive– نمیتونین همزمان با هم استفاده بشن)برای اینکه خروجی زیپ بشه از سوئیچ gzip– استفاده کنین.پیشنهاد: بهترین کار اینه که خودتون هم داکیومنتش  رو از این لینک بخونین :)نکته: حتما حواستون باشه که بک آپ هاتون کجا و با چه اسمی ذخیره میشن، اگه همنام باشن درنهایت overwrite خواهند شد.Let&#x27;s backup!بیاید با یه دستور ساده شروع کنیم.mongodump -v --uri=&quot;mongodb://localhost:27017/test&quot; --out=&quot;./backup&quot;با این دستور خیلی ساده از دیتابیس test ( که تو uri مشخص کردم ) یک بک آپ تهیه کردم که تو دایرکتوری فعلیمون ذخیره خواهد شد.برای اینکه خروجیه بک آپ تو یک فایل از نوع آرشیو ذخیره شه از دستور زیر استفاده میکنیم.mongodump -v --uri=&quot;mongodb://localhost:27017/test&quot; --archive=&quot;./test.archive&quot;با اجرای این دستور یک فایل آرشیو  تو دایرکتوریه فعلیمون با اسم test.archive ذخیره خواهد شد.نکته: اگه تو هر دوتا مورد بالا از سوئیچ gzip-- استفاده کنین، فایل های بک آپ فشرده هم خواهند شد. مثلا بیاید بیاید یک بک آپ از دیتابیس test بگیریم و خروجی رو بصورت یک فایل آرشیو که فشرده شده باشه ذخیره کنیم.mongodump -v --gzip --uri=&quot;mongodb://localhost:27017/test&quot; --archive=&quot;./test.archive.gz&quot;این مثال رو زدم چون یک نکته ی کوچیک داره و اونم اینه که  باید پسوند gz. رو هم حتما به اخر اسم اضافه کنید.Mongorestoreبرای اینکه از بک آپ هامون استفاده کنیم و دیتاهامون رو اصطلاحا restore کنیم، از یک ابزار دیگه به اسم Mongorestore استفاده میکنیم که میتونین از این لینک دانلود کنین. نکته: دقت کنین که اگه دیتابیسی که ازش بک آپ تهیه کردین ورژنش 4.0 هست، دیتابیسی که قراره روش دیتاها رو restore کنین هم باید ورژنش 4.0 باشه. و همچنین اگه از یک Mongodump با 100.7.0 بکاپ تهیه شده، ورزژن Mongorestore هم باید 100.7.0 باشه. Let&#x27;s restore the backups!مثل همیشه اول با یک مثال ساده شروع میکنیم.mongorestore -v --uri=&quot;mongodb://localhost:27017/&quot; --dir=&quot;./backup&quot; --nsFrom=&quot;test.*&quot; --nsTo=&quot;restore.*&quot;با سویچ های v- و uri--  آشنا شدیم. اما بیاید سویچ های جدید رو یک بررسی کوچیک بکنیم:سویچ  dir-- به دایرکتوریی که بک آپ ها ذخیره شدن اشاره داره.سویچ nsFrom-- به دیتابیس و کالکشنی که میخوایین دیتاهاش رو restore کنین اشاره داره. تو مثال بالا گفتم از دیتابیس test همه ی کالکشن هاش رو میخواییم restore کنیم.سویچ nsTo-- به دیتابیس و کالکشن مقصدمون اشاره داره. تو مثال بالا گفتیم دیتاها رو به دیتابیس restore منتقل کن.نکته: توجه کنین که اگه دیتابیس مقصدتون وجود نداشته باشه، خودش یکی میسازه و اگه وجود داشته باشه هم سعی میکنه تو همون دیتابیس دیتاها رو restore میکنه.حالا فرض میکنیم فایل بک آپ، یک فایل از نوع آرشیو هست.mongorestore -v --uri=&quot;mongodb://localhost:27017/&quot; --archive=&quot;./test.archive&quot; --nsFrom=&quot;test.*&quot; --nsTo=&quot;restore.*&quot;همونطور که میبینیم همه مراحل مثل بالا هست فقط به جای dir-- از سویچ archive-- استفاده کردیم چون فایل بک آپ یک فایل از نوع آرشیو هست.امیدوارم گیج نشده باشین :) ولی مثل همیشه پیشنهاد میکنم خودتون داکیومنتش رو حتما یه نگاه بندازین.حالا بیاید یک فایل بک آپ از نوع آرشیو که فشرده هم شده رو restore کنیم. mongorestore -v --gzip --uri=&quot;mongodb://localhost:27017/&quot; --archive=&quot;./test.archive.gz&quot; --nsFrom=&quot;test.*&quot; --nsTo=&quot;restore.*&quot;میبینید که چون فایل بک آپ یک فایل آرشیو و فشرده شدس، از سوئیچ gzip-- استفاده کردیم.یه سویچ دیگه هم هست که میتونه خطرناک باشه پس حتما دقت کنین چون ممکنه گرون تموم شه براتون :) با سویچ drop-- اگه دیتابیسی همنام با دیتابیس مقصدتون وجود داشته باشه، اول اونو پاک کنه و بعد شروع به restore کردن میکنه.امیدوارم مفید بوده باشه براتون :) من فقط سعی کردم یک مقدمه ای براتون گفته باشم که برای شروع کمک کننده باشه.ReferencesMongodump MongorestoreMongoDB Database Backup</description>
                <category>علیرضا</category>
                <author>علیرضا</author>
                <pubDate>Fri, 21 Jul 2023 18:41:08 +0330</pubDate>
            </item>
            </channel>
</rss>