Syntax | سینتکس
Відкрити в Telegram
Focus: Web Lan: Python & Go Website: https://syntaxfa.ir Quick connect: https://quick-connect.syntaxfa.ir Github: https://github.com/syntaxfa Group: https://t.me/Syntax_fa_group
Показати більше3 155
Підписники
+124 години
+267 днів
+11130 день
Триває завантаження даних...
Схожі канали
Хмара тегів
Вхідні та вихідні згадування
---
---
---
---
---
---
Залучення підписників
липень '26
липень '26
+158
в 3 каналах
червень '26
+134
в 2 каналах
Get PRO
травень '26
+71
в 0 каналах
Get PRO
квітень '26
+27
в 0 каналах
Get PRO
березень '26
+11
в 1 каналах
Get PRO
лютий '26
+50
в 3 каналах
Get PRO
січень '26
+25
в 0 каналах
Get PRO
грудень '25
+64
в 3 каналах
Get PRO
листопад '25
+95
в 3 каналах
Get PRO
жовтень '25
+56
в 0 каналах
Get PRO
вересень '25
+54
в 2 каналах
Get PRO
серпень '25
+49
в 1 каналах
Get PRO
липень '25
+94
в 2 каналах
Get PRO
червень '25
+140
в 0 каналах
Get PRO
травень '25
+69
в 2 каналах
Get PRO
квітень '25
+44
в 2 каналах
Get PRO
березень '25
+74
в 1 каналах
Get PRO
лютий '25
+148
в 2 каналах
Get PRO
січень '25
+168
в 3 каналах
Get PRO
грудень '24
+120
в 2 каналах
Get PRO
листопад '24
+120
в 1 каналах
Get PRO
жовтень '24
+125
в 1 каналах
Get PRO
вересень '24
+84
в 1 каналах
Get PRO
серпень '24
+158
в 4 каналах
Get PRO
липень '24
+184
в 1 каналах
Get PRO
червень '24
+288
в 1 каналах
Get PRO
травень '24
+91
в 1 каналах
Get PRO
квітень '24
+103
в 0 каналах
Get PRO
березень '24
+142
в 3 каналах
Get PRO
лютий '24
+222
в 3 каналах
Get PRO
січень '24
+593
в 1 каналах
Get PRO
грудень '23
+597
в 1 каналах
Get PRO
листопад '23
+522
в 3 каналах
Get PRO
жовтень '23
+242
в 3 каналах
Get PRO
вересень '23
+406
в 0 каналах
| Дата | Залучення підписників | Згадування | Канали | |
| 27 липня | +5 | |||
| 26 липня | +5 | |||
| 25 липня | +5 | |||
| 24 липня | +10 | |||
| 23 липня | +4 | |||
| 22 липня | +3 | |||
| 21 липня | +6 | |||
| 20 липня | +2 | |||
| 19 липня | +4 | |||
| 18 липня | +7 | |||
| 17 липня | +6 | |||
| 16 липня | +4 | |||
| 15 липня | +5 | |||
| 14 липня | +17 | |||
| 13 липня | +1 | |||
| 12 липня | +6 | |||
| 11 липня | +4 | |||
| 10 липня | +5 | |||
| 09 липня | +5 | |||
| 08 липня | +5 | |||
| 07 липня | +9 | |||
| 06 липня | +3 | |||
| 05 липня | +13 | |||
| 04 липня | +8 | |||
| 03 липня | +11 | |||
| 02 липня | +3 | |||
| 01 липня | +2 |
Дописи каналу
🔥 اگه با Go کار میکنی و هنوز از Air استفاده نمیکنی، وقتشه نصبش کنی!
حتماً برات پیش اومده که بعد از هر تغییر توی کد، دوباره این دستور رو اجرا کنی:
go run .
بعد دوباره کد رو تغییر بدی، دوباره go run دوباره تغییر، دوباره اجرا...
اینجاست که Air وارد میشه.
Air یه ابزار Hot Reload برای Go هست که پروژه رو مانیتور میکنه و هر بار فایلی تغییر کنه، خودش برنامه رو دوباره Build و Run میکنه. یعنی فقط یک بار اجراش میکنی و تا آخر توسعه دیگه لازم نیست هی go run بزنی.
📦 نصب:
go install github.com/air-verse/air@latest
🚀 اجرا:
airاگه خواستی فایل تنظیماتش هم ساخته بشه:
air init
با فایل .air.toml هم میتونی مشخص کنی چه فایلهایی مانیتور بشن، چه پوشههایی نادیده گرفته بشن و دستور Build چطور اجرا بشه.
ریپو پروژه :
https://github.com/air-verse/air
#programming #backend #go
@Syntax_fa| 2 | 🔥 اگه با Go کار میکنی و هنوز از Air استفاده نمیکنی، وقتشه نصبش کنی!
حتماً برات پیش اومده که بعد از هر تغییر توی کد، دوباره این دستور رو اجرا کنی:
go run main.go
بعد دوباره کد رو تغییر بدی، دوباره go run دوباره تغییر، دوباره اجرا...
اینجاست که Air وارد میشه.
Air یه ابزار Hot Reload برای Go هست که پروژه رو مانیتور میکنه و هر بار فایلی تغییر کنه، خودش برنامه رو دوباره Build و Run میکنه. یعنی فقط یک بار اجراش میکنی و تا آخر توسعه دیگه لازم نیست هی go run بزنی.
📦 نصب:
go install github.com/air-verse/air@latest
🚀 اجرا:
اگه خواستی فایل تنظیماتش هم ساخته بشه:
air init
با فایل .air.toml هم میتونی مشخص کنی چه فایلهایی مانیتور بشن، چه پوشههایی نادیده گرفته بشن و دستور Build چطور اجرا بشه.
به نظرم Air جزو اون ابزارهاییه که بعد از چند روز استفاده، یادت میره قبلاً بدونش چطور کار میکردی. 😄
#golang #go #air #backend #syntaxfa | 1 |
| 3 | پکیج پایتونی gevent
چرا gevent اصلاً متولد شد؟
قبل از اینکه کلمات کلیدی async و await وارد پایتون شوند، برنامهنویسها برای مدیریت هزاران درخواست همزمان (مشکل C10k) یک دردسر بزرگ داشتند.
استفاده از Threadهای سیستمعامل برای پایتون بسیار سنگین بود و حافظه زیادی مصرف میکرد. فریمورکهایی مثل Twisted هم بودند که بر اساس Callback کار میکردند، اما خواندن و دیباگ کردن کدهای آنها شبیه یک کابوس (Callback Hell) بود.
اینجا بود که gevent با یک ایده درخشان وارد شد: کد را به شکل ساده و همگام (Sync) بنویس، اما ما آن را در پسزمینه به صورت ناهمگام (Async) و با سرعت نور اجرا میکنیم! gevent این کار را با استفاده از گرینلتها (Greenlets) که میکروتردهای بسیار سبکی در سطح C هستند، انجام داد.
الان با وجود asyncio، پرونده gevent بسته شده است؟
با اینکه asyncio استاندارد مدرن و آینده پایتون است، اما gevent هنوز یک برگ برنده بزرگ دارد: پروژههای قدیمی (Legacy).
اگر شما یک پروژه بزرگ جنگو (Django) یا فلسک (Flask) دارید که با کدهای معمولی نوشته شده، نمیتوانید یکشبه دهها هزار خط کد را به async/await تبدیل کنید. gevent با تکنیک Monkey Patching به شما اجازه میدهد بدون تغییر دادن حتی یک خط از منطق اصلی برنامهتان، عملکرد I/O سرور را چند برابر کنید.
مثال در سلری:
فرض کنید باید ۱۰۰ ایمیل بفرستید یا از ۱۰۰ سایت دیتا استخراج کنید (کارهای I/O Bound).اگر در Celery از حالت پیشفرض (Prefork/Processes) استفاده کنید و فقط ۲ عدد Worker داشته باشید، در هر لحظه فقط ۲ تسک انجام میشود. بقیه تسکها باید در صف منتظر بمانند تا این دو تمام شوند. این یعنی اتلاف زمان!
اما اگر Worker را با gevent اجرا کنید:
celery -A my_project worker -P gevent -c 100
همان ۲ پروسس حالا میتوانند هر ۱۰۰ تسک را همزمان مدیریت کنند! وقتی تسک اول منتظر جواب سرور ایمیل است، gevent سریعاً سراغ تسک دوم میرود. با کمترین مصرف رم و CPU، سرعت اجرای تسکهای شبکهای شما دهها برابر میشود.
#gevent
@Syntax_fa | 614 |
| 4 | معرفی telegram outreach
تو تلگرام یه سری تبلیغات میبینید که به پیوی شما ارسال میشن.
این پروژه دقیقا همینکارو انجام میده.
اکانت های تلگرامی که دارید رو وارد میکنید و سشنشون ساخته میشه.
بعد میرید تسک میسازید که یوزر های کدوم گروه رو کراول کنه و لیمیت هارو مشخص میکنید مثلا 500 تا از یوزر های گروه سینتکس.
لیست ممبر های گروه رو نمیگیره. بجاش پیام های گروه رو استخراج میکنه و یوزر های فعالشون رو از این طریق پیدا میکنه.
بعدش مشخص میکنید که با کدوم اکانت ها به یوزر های کدوم گروه که تو مرحله قبلی بدست آوردید چه پیام هایی رو ارسال کنه.
پیام ها میتونه تکست باشه یا بصورت ویس باشه.
لینک:
https://github.com/alireza-fa/telegram-outreach
@syntax_fa | 746 |
| 5 | بازنویسی Bun از Zig به Rust؛ کاملاً با هوش مصنوعی
همونطور که احتمالاً میدونید، Bun یک JavaScript Runtime مدرنه که با تمرکز روی سرعت ساخته شده. این پروژه در ابتدا با Zig توسعه پیدا کرد؛ چون Zig به یک تیم کوچک اجازه میداد بدون سربار Garbage Collector و Runtimeهای سنگین، خیلی سریع یک Runtime پرسرعت بسازه. دسترسی مستقیم به حافظه، سادگی زبان و تعامل خوب با C باعث شد معماری و طراحی سطح پایین Bun حول Zig شکل بگیره؛ موضوعی که Jarred Sumner، خالق Bun، هم بارها بهش اشاره کرده.
اما در ماه می امسال، تیم Bun اعلام کرد که قصد داره کل پروژه رو به Rust مهاجرت بده. حالا این بازنویسی انجام شده و کدهای Rust هم وارد شاخه اصلی پروژه شدن. نکتهی عجیب اینجاست که تقریباً تمام این کدها توسط Claude Code تولید شدن و علاوه بر بازنویسی، تعدادی از باگهای قدیمی هم در همین فرآیند برطرف شدن.
آیا مشکل از Zig بود؟
از نگاه تیم Bun، مشکل اصلی خود Zig نبود؛ بلکه مدیریت دستی حافظه در کنار Garbage Collector جاوااسکریپت بود. این ترکیب باعث نشت حافظه، کرش و هزینهی بالای نگهداری کد میشد و با بزرگتر شدن پروژه، اتکا به دقت برنامهنویس دیگر کافی نبود.
با این حال، جرد تأکید میکنه که Zig نقش مهمی در موفقیت اولیه Bun داشته و بخش بزرگی از معماری و عملکرد فعلی پروژه مدیون همون انتخاب اولیه است.
در مقابل، اندرو کلی، خالق Zig، بارها گفته مشکل از زبان Zig نبوده، بلکه از نحوهی استفادهی Bun از اون بوده. حتی جایی گفته بود داخل تیم Zig، از Bun بهعنوان مثالی استفاده میکنیم که «چطور نباید با Zig برنامه نوشت».
چرا Rust؟
بخش بزرگی از باگهای Bun به مدیریت حافظه مربوط میشد. در Rust این دسته از خطاها معمولاً هنگام کامپایل شناسایی میشن و مکانیزم Ownership و Drop هم آزادسازی حافظه رو مدیریت میکنن. در نتیجه، به جای اینکه توسعهدهنده همیشه مراقب همهچیز باشه، کامپایلر جلوی بخش زیادی از اشتباهات رو میگیره.
البته بازنویسی پروژهای با بیش از ۵۳۵ هزار خط کد Zig اصلاً تصمیم سادهای نبود. انجام دستی این کار حداقل یک سال زمان میبرد و عملاً توسعهی Bun رو متوقف میکرد. تیم ابتدا سعی کرد با Smart Pointerهای الهامگرفته از Rust و سختگیرتر کردن قوانین کدنویسی، مشکلات رو داخل Zig حل کنه، اما در نهایت تصمیم گرفت از Claude Code برای بازنویسی کامل پروژه استفاده کنه.
کلاد چطور این بازنویسی را انجام داد؟
جرد میگه ماجرا به سادگی این نبود که به Claude بگه «کل Bun رو به Rust تبدیل کن». قبل از شروع، ساعتها صرف طراحی Workflowها و استراتژی بازنویسی شد.
در نهایت، حدود ۵۰ Workflow مختلف به مدت ۱۱ روز تقریباً بدون توقف اجرا شدن؛ با هزینهای نزدیک به ۱۶۵ هزار دلار.
هر Workflow وظیفهی مشخصی داشت؛ از تبدیل الگوهای Zig به Rust و رفع خطاهای کامپایل گرفته تا اجرای bun test و bun build. پاس کردن تستها و در نهایت Refactor کد.
جرد هم بهجای اصلاح مستقیم خروجیها، Workflowها و Promptها رو بهبود میداد تا هر بار کیفیت خروجی بهتر بشه.
برای اعتماد به بیش از یک میلیون خط کد تولیدشده توسط هوش مصنوعی هم از روشی شبیه Code Review واقعی استفاده شد. یک Claude کد رو مینوشت و چند Claude دیگه، در Contextهای جداگانه، فقط وظیفه داشتن ایرادها و باگها رو پیدا کنن. نویسندهی کد Reviewer نبود و Reviewer هم اجازهی تغییر کد رو نداشت.
بعد از تبدیل همهی فایلها، مرحلهی اصلی یعنی رفع خطاها و پاس کردن تستها شروع شد. این چرخه بارها تکرار شد تا در نهایت تمام تستهای Bun روی همهی پلتفرمها با موفقیت پاس شدن و کد وارد شاخهی اصلی پروژه شد.
آیا این بازنویسی موفق خواهد بود؟
در کوتاهمدت احتمالاً بله. تستها مسیرهای اصلی رو پوشش میدن، نسخههای Canary مشکلات واضح رو پیدا میکنن و Rust هم بخش بزرگی از خطاهای مدیریت حافظه رو حذف میکنه.
اما سؤال اصلی بلندمدته.
اگر چند ماه بعد یک باگ پیچیدهی Concurrency یا یک حالت مرزی عجیب ظاهر بشه، مهندسی که مسئول دیباگ کردنشه با کدی روبهرو میشه که تقریباً هیچ انسانی اون رو بهطور کامل ننوشته یا خطبهخط درکش نکرده.
در نهایت، شرطبندی اصلی این پروژه نه روی Zig و Rust، بلکه روی این سؤاله که آیا یک Codebase عظیم که عمدتاً توسط هوش مصنوعی تولید شده، در بلندمدت هم قابل نگهداری و قابل اعتماد خواهد بود یا نه.
از طرف دیگه، بعضیها هم معتقدن این اتفاق فقط یک بازنویسی فنی نبوده و بخشی از یک کمپین بازاریابی برای Claude محسوب میشه.
پاسخ اینکه این تصمیم در نهایت موفق خواهد بود یا نه، فعلاً مشخص نیست؛ چیزی که فقط با گذر زمان معلوم میشه.
مقاله ای که خود جرد منتشر کرده و در مورد این تغییرات توضیح داده:
https://bun.com/blog/bun-in-rust
#News
@Syntax_fa | 752 |
| 6 | تفاوت مدل های پردازش داده OLTP و OLAP
وقتی یه سیستم بزرگ طراحی میکنید، خیلی زود متوجه میشید که همهی بارهای کاری شبیه هم نیستن. بعضی درخواستها فقط میخوان یه رکورد رو ثبت یا ویرایش کنن، ولی بعضی دیگه باید میلیونها رکورد رو بررسی کنن تا یه گزارش یا تحلیل تولید بشه.
به همین خاطر، پایگاههای داده معمولاً برای یکی از دو مدل OLTP یا OLAP بهینه میشن.
🔹سیستم OLTP (Online Transaction Processing)
سیستمهای OLTP برای انجام تراکنشهای روزمره ساخته شدن. هر درخواست معمولاً کوتاهه، روی تعداد کمی از رکوردها کار میکنه و باید توی کمترین زمان ممکن جواب بده.
تمرکز اصلی OLTP روی سرعت، همزمانی و حفظ یکپارچگی دادههاست. به همین دلیل معمولاً از دیتابیسهای نرمالسازیشده استفاده میکنه تا عملیات ثبت، ویرایش و حذف دادهها سریع و مطمئن انجام بشن.
چند نمونه از بارهای کاری OLTP:
• ثبت سفارش توی فروشگاه آنلاین
• انتقال وجه در سیستم بانکی
• تغییر موجودی کالا
• ورود یا ثبتنام کاربران
🔹 سیستم OLAP (Online Analytical Processing)
برخلاف OLTP، OLAP برای تحلیل دادهها ساخته شده، نه انجام تراکنشهای روزمره.
اینجا معمولاً با کوئریهایی طرف هستیم که حجم زیادی از داده رو میخونن تا به یه نتیجه برسن؛ مثلاً محاسبه فروش یک سال گذشته، تحلیل رفتار کاربران یا ساخت داشبوردهای مدیریتی.
توی OLAP، سرعت انجام یک تراکنش مهم نیست؛ چیزی که اهمیت داره اینه که سیستم بتونه کوئریهای سنگین رو روی حجم زیادی از داده با کارایی مناسب اجرا کنه. به همین خاطر، دادهها معمولاً داخل Data Warehouse نگهداری میشن و ساختارشون برای تحلیل بهینه شده.
چند نمونه از بارهای کاری OLAP:
• گزارش فروش ماهانه یا سالانه
• تحلیل رفتار کاربران
• داشبوردهای مدیریتی
• گزارشهای هوش تجاری (BI)
🔹 تفاوت OLTP و OLAP
با اینکه هر دو با داده سروکار دارن، ولی هدفشون کاملاً متفاوته. OLTP برای اجرای تعداد زیادی تراکنش کوچیک و سریع طراحی شده؛ یعنی هر درخواست فقط چند رکورد رو میخونه یا تغییر میده و تأخیر پایین براش خیلی مهمه.
از اون طرف، OLAP برای اجرای کوئریهای تحلیلی ساخته شده؛ کوئریهایی که ممکنه میلیونها رکورد رو اسکن کنن تا یه گزارش یا تحلیل تولید بشه.
به همین دلیل، توی خیلی از معماریهای مدرن این دو از هم جدا هستن. سیستم عملیاتی (OLTP) فقط مسئول اجرای تراکنشهاست و دادهها بهصورت دورهای به یک Data Warehouse منتقل میشن تا تحلیلها روی اون انجام بشه. این جداسازی باعث میشه هم سیستم عملیاتی سریع باقی بمونه و هم گزارشهای تحلیلی، بدون فشار آوردن به دیتابیس اصلی، اجرا بشن.
#system_design #software_engineering #backend
@Syntax_fa | 632 |
| 7 | 📘 آموزش Network
🧠 هر روز یک دستور شبکه
🔥 هر روز یک نکته
🛡 هر روز یک نکته امنیت شبکه
🧩 هر روز یک سناریوی عیبیابی
https://t.me/ModernLAN | 438 |
| 8 | معرفی ربات controller bot
این ربات برای کسایی که کانال دارن بدرد میخوره
میتونید باهاش پست هایی با دکمه های شیشه ای بذارید
تو پستتون عکس بذارید و این حرفا.
شبیه به این پستمون:
https://t.me/Zervana/98
@Syntax_fa | 754 |
| 9 | مفهوم Idempotent یعنی چیه؟ چرا این مفهوم همه جا دیده میشه؟
اگه یه مدتی برنامهنویسی کرده باشید، احتمالاً اسم Idempotent به گوشتون خورده. ممکنه این اصطلاح رو توی APIها، پایگاه داده، سیستمهای توزیعشده، صفهای پیام یا حتی ابزارهای DevOps دیده باشید. اما واقعاً Idempotent یعنی چی؟
بیاید با یه مثال ساده شروع کنیم.
فرض کنید یه کلید برق داریم که فقط وظیفهش روشن کردن چراغه. اگه چراغ خاموش باشه و کلید رو بزنید، چراغ روشن میشه. حالا اگه دوباره همون کلید رو بزنید چی میشه؟ هیچ اتفاق جدیدی نمیافته؛ چراغ همچنان روشنه.
مهم نیست این کار رو یک بار انجام بدید یا ده بار؛ نتیجهی نهایی همیشه یکیه. دقیقاً به چنین رفتاری میگن Idempotent.
حالا یه مثال برعکس.
فرض کنید دکمهای داریم که هر بار فشار دادنش، ۱۰۰ هزار تومان به موجودی کیف پول اضافه میکنه. بار اول موجودی ۱۰۰ هزار تومان زیاد میشه، بار دوم دوباره ۱۰۰ هزار تومان اضافه میشه و بار سوم هم همین اتفاق تکرار میشه.
اینجا هر بار اجرای عملیات، وضعیت سیستم رو تغییر میده. پس این عملیات Idempotent نیست.
تعریف رسمی Idempotent هم تقریباً همینه؛ اگه یه عملیات رو یک بار اجرا کنیم یا چند بار پشت سر هم، وضعیت نهایی سیستم باید یکسان باشه.
یه نکتهی مهم اینجاست که Idempotent بودن به این معنی نیست که خروجی عملیات همیشه یکی باشه. ممکنه هر بار اطلاعات متفاوتی برگرده، زمان اجرا فرق کنه یا حتی پیام متفاوتی نمایش داده بشه. چیزی که مهمه اینه که اجرای دوبارهی همون عملیات، وضعیت سیستم رو بیشتر از دفعهی اول تغییر نده.
یکی از اشتباههای رایج اینه که Idempotent رو با عملیاتی که هیچ تغییری ایجاد نمیکنه، اشتباه میگیرن. در حالی که یه عملیات Idempotent میتونه وضعیت سیستم رو تغییر بده؛ فقط این تغییر باید فقط بار اول اتفاق بیفته.
مثلاً اگه عملیاتی وضعیت یه کاربر رو از «غیرفعال» به «فعال» تغییر بده، بار اول وضعیت عوض میشه، اما اگه دوباره همون عملیات اجرا بشه، دیگه تغییری ایجاد نمیکنه.
پس این عملیات همچنان Idempotent محسوب میشه.
از اون طرف، عملیاتهایی مثل «افزایش موجودی»، «افزایش تعداد بازدید»، «ارسال ایمیل» یا «ثبت سفارش جدید» معمولاً Idempotent نیستن؛ چون هر بار اجرا شدنشون یه اثر جدید روی سیستم میذاره.
دلیل اهمیت Idempotent فقط سادهتر شدن منطق برنامه نیست.
توی سیستمهای واقعی همیشه ممکنه شبکه قطع بشه، درخواست Timeout بشه، کلاینت دوباره درخواست رو Retry کنه یا یه Job دوباره اجرا بشه.
اگه عملیات شما Idempotent باشه، دیگه مهم نیست همون عملیات چند بار اجرا بشه؛ نتیجهی نهایی تغییری نمیکنه و سیستم توی وضعیت درستی باقی میمونه.
به خاطر همین، این مفهوم تقریباً توی همهی شاخههای مهندسی نرمافزار دیده میشه؛ از طراحی APIها گرفته تا پایگاه داده، Message Queueها، Event-Driven Architecture، Infrastructure و حتی ابزارهای مدیریت سرور.
در نهایت، Idempotent یه تکنولوژی یا قابلیت خاص نیست؛ یه ویژگی برای طراحی عملیاته.
هر وقت بتونید عملیاتی طراحی کنید که اجرای دوبارهی اون، وضعیت نهایی سیستم رو تغییر نده، اون عملیات Idempotent محسوب میشه.
#programming #software_engineering
@Syntax_fa | 1 143 |
| 10 | متد جدید HTTP؛ آشنایی با QUERY
اگر تا حالا با REST یا HTTP کار کرده باشید، قطعا با متدهای GET، POST، PUT، PATCH و DELETE آشنایی دارید. اما بعد از حدود ۱۶ سال، یک متد جدید به پروتکل HTTP اضافه شده که اسمش QUERY هست.
بیاید با یه مثال ببینیم اصلاً چرا چنین متدی به وجود اومده.
فرض کنید یه endpoint به اسم orders داریم که از Pagination، Filter، Sort و موارد مشابه پشتیبانی میکنه. معمولاً برای دریافت اطلاعات از متد GET استفاده میکنیم و پارامترها رو هم به صورت Query String داخل URL میفرستیم.
GET /orders?status=paid&limit=20&offset=0
این روش سالهاست که استفاده میشه و تو اکثر مواقع هم کاملاً منطقیه، اما چند تا محدودیت داره:
• طول URL محدوده (معمولاً حدود ۸۰۰۰ کاراکتر یا حتی کمتر، بسته به سرور و مرورگر)
• پارامترها داخل URL قرار میگیرن و ممکنه توی لاگهای سرور ثبت بشن.
• ساختن کوئریهای پیچیده مثل فیلترهای پیشرفته، SQL، JSONPath و... سخت یا حتی غیرممکنه.
• Encoding کردن پارامترهای پیچیده هم دردسرهای خودش رو داره.
معمولاً وقتی به این محدودیتها میرسیم، خیلیها به جای GET از POST استفاده میکنن و پارامترها رو داخل Body درخواست میذارن.
POST /orders HTTP/1.1
Host: api.example.org
Content-Type: application/x-www-form-urlencoded
select=surname,givenname,email&limit=10&match="email=@example."
این روش مشکل محدودیت URL رو حل میکنه، اما خودش چند تا ایراد مهم داره:
• متد POST ذاتاً Idempotent نیست؛ یعنی اگر وسط ارسال درخواست ارتباط قطع بشه، نمیشه با خیال راحت همون درخواست رو دوباره ارسال کرد، چون ممکنه عملیات دوباره انجام بشه.
• پاسخهای POST به صورت پیشفرض از Cache استاندارد HTTP استفاده نمیکنن.
• Proxyها و CDNها نمیتونن تشخیص بدن که ارسال مجدد این درخواست امن هست یا نه.
• هر فریمورک هم معمولاً راهکار خودش رو برای پیادهسازی چیزی مثل Safe POST داره و استاندارد یکپارچهای وجود نداره.
اینجاست که QUERY وارد میشه.
ایدهی اصلی QUERY اینه که بهترین ویژگیهای GET و POST رو با هم ترکیب کنه. از یه طرف مثل GET فقط برای خوندن اطلاعات استفاده میشه و هیچ تغییری روی وضعیت سرور ایجاد نمیکنه، و از طرف دیگه مثل POST میتونه دادههای پیچیده رو داخل Body درخواست ارسال کنه.
در نتیجه درخواستهامون به این شکل درمیاد:
QUERY /orders HTTP/1.1
Host: api.example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json
select=surname,givenname,email&limit=10&match="email=@example."
به این ترتیب دیگه محدودیت طول URL وجود نداره و میتونید هر نوع فیلتر پیچیده، کوئری، JSONPath یا هر دادهی دیگهای رو داخل Body ارسال کنید.
اما مزیت QUERY فقط این نیست.
یکی از مهمترین ویژگیهای این متد، Idempotent بودنشه. یعنی اگر به هر دلیلی ارتباط شبکه قطع بشه، کلاینت میتونه همون درخواست رو دوباره ارسال کنه و مطمئن باشه نتیجه دقیقاً همون نتیجهی قبلی خواهد بود. برخلاف POST که ارسال مجددش ممکنه باعث ایجاد دادههای تکراری یا اجرای دوبارهی عملیات بشه.
از طرف دیگه، چون QUERY یک متد Safe محسوب میشه و فقط برای دریافت داده استفاده میشه، زیرساختهای HTTP مثل مرورگرها، Proxyها و CDNها میتونن پاسخش رو مثل GET کش کنن. یعنی درخواستهای پیچیدهای که قبلاً مجبور بودیم با POST بفرستیم، حالا میتونن از مزایای Cache استاندارد HTTP هم استفاده کنن.
یکی دیگه از قابلیتهای جالب QUERY اینه که سرور میتونه برای خودِ درخواست یک URI دائمی ایجاد کنه. یعنی به جای اینکه فقط نتیجهی جستجو قابل دسترس باشه، خود Query هم یک آدرس اختصاصی خواهد داشت. هر بار که اون آدرس فراخوانی بشه، همون جستجو دوباره روی دادههای جدید اجرا میشه. این قابلیت برای Share کردن جستجوها، Bookmark کردنشون یا اجرای دورهای یک Query بدون ارسال دوبارهی Body خیلی کاربردیه.
در نهایت، متد QUERY به صورت رسمی استاندارد شده، اما هنوز راه زیادی تا استفادهی گسترده ازش باقی مونده. بعضی از اکوسیستمها مثل Go و Java کار روی پشتیبانی ازش رو شروع کردن و احتمالاً در آینده اسم این متد رو بیشتر خواهیم شنید. البته فعلاً پشتیبانی ازش محدود به چند کتابخونه و سرور خاصه و هنوز اکثر فریمورکها و API Gatewayها ازش پشتیبانی کامل ندارن.
اگر دوست دارید بیشتر درباره این متد بدونید، پیشنهاد میکنم RFC مربوط بهش رو هم بخونید:
https://www.rfc-editor.org/info/rfc10008
#programming
@Syntax_fa | 2 170 |
| 11 | از فوتبال چخبر؟
اینهمه استرس که تو بازی پرتغال داشتم تو جنگ 40 روزه تجربه نکردم | 76 |
| 12 | همیشه برام جالب بود که ما دولوپرها میتونیم پیچیدهترین لاجیکها رو تو کدهامون هندل کنیم، اما وقتی نوبت به باگهای ذهن و تلههای رفتاری خودمون میرسه، هیچ دیباگری نداریم.
این دغدغه باعث شد تو ماههای گذشته، منطق بکاند رو با مفاهیم عمیق روانشناسی تحلیلی و کهنالگوها ترکیب کنم. خروجی این ترکیب شده پروژهی جدیدم: زروانا.
زروانا یه لابراتوارِ مبتنی بر هوش مصنوعیه که دیتای پراکنده ذهن شما (از خوابها و کابوسها گرفته تا تستهای روانسنجی) رو میگیره، پردازش میکنه و بهتون میگه دقیقاً کجای ناخودآگاهتون گیر کردید و کدوم سایه داره تصمیماتون رو کنترل میکنه.
از نظر فنی و اینکه چطور پیاده سازیش کردم تو پست های آینده دربارش صحبت میکنم.
دوست دارم شما بچههای کامیونیتی فنی جزو اولین نفراتی باشید که این سیستم رو تست میکنید. روی دیباگ کردنش حساب کردم.
لینک زروانا:
https://t.me/ZervanaBot | 1 293 |
| 13 | کانکارنسی فقط «همزمان اجرا شدن» نیست.
خیلیها فکر میکنند اگر دو عملیات همزمان اجرا شوند، با مسئلهی Concurrency روبهرو هستیم. اما اگر این دو عملیات هیچ ارتباطی با هم نداشته باشند، در واقع مشکلی وجود ندارد.
برای مثال:
یک سرویس در حال فشردهسازی تصویر است.
سرویس دیگری در حال پردازش ویدئو است.
این دو ممکن است همزمان اجرا شوند، اما چون روی دادهی مشترکی کار نمیکنند، نیازی به هماهنگی خاصی ندارند.
مشکل واقعی زمانی شروع میشود که چند عملیات به یک دادهی مشترک و قابل تغییر (Shared Mutable State دسترسی داشته باشند.
فرض کنید دو تراکنش همزمان روی موجودی یک حساب بانکی کار میکنند:
تراکنش اول: 50 واحد از موجودی کم میکند.
تراکنش دوم: 100 واحد به موجودی اضافه میکند.
در اینجا دیگر فقط «همزمان بودن» مهم نیست؛ بلکه ترتیب اجرا و نحوهی تعامل این دو عملیات میتواند نتیجهی نهایی را تغییر دهد. اگر این تعامل بهدرستی مدیریت نشود، ممکن است دادهها ناسازگار شوند یا حتی تغییرات یکی از تراکنشها از بین برود.
به همین دلیل، Concurrency را میتوان اینگونه تعریف کرد:
کانکارنسی یعنی مدیریت صحیح دسترسی همزمان چند عملیات به یک وضعیت (State) مشترک، بهگونهای که مستقل از ترتیب اجرای آنها، نتیجه همچنان صحیح باقی بماند.
به همین خاطر است که مفاهیمی مانند Isolation ، Locking ، MVCC و Serializability در سیستمهای پایگاه داده به وجود آمدهاند؛ هدف همهی آنها یک چیز است: حفظ صحت دادهها، حتی زمانی که چند عملیات به طور همزمان در حال اجرا هستند.
#programming #system_design
@Syntax_fa | 1 258 |
| 14 | استراتژی Rolling Update؛ بالانس بین سادگی و کارایی
🔹 تعریف و فلسفه وجودی
Rolling Update یک استراتژی استقرار نرمافزار است که در آن نسخه جدید برنامه بهتدریج و مرحلهبهمرحله جایگزین نسخه قدیمی میشود، بدون اینکه هیچگاه سرویس بهطور کامل از کار بیفتد. این روش با هدف حل مشکلات استقرارهای یکباره (Big Bang) متولد شد؛ جایی که یک اشتباه ساده میتوانست کل سیستم را از کار بیندازد و تیم را در ساعت ۳ بامداد بیدار کند. فلسفه اصلی Rolling Update بر شفافیت، کنترل لحظهای و قابلیت بازگشت سریع استوار است، نه افزودن پیچیدگیهای غیرضروری.
🔹مکانیزم عملکرد
فرآیند کار بسیار سرراست است: بهجای اینکه همه نمونههای سرویس یکجا بهروز شوند، فقط تعداد مشخصی (مثلاً ۲۰٪) انتخاب شده، با نسخه جدید جایگزین میشوند، صحت عملکردشان بررسی میگردد و در صورت موفقیت، این چرخه تا جایگزینی کامل ادامه مییابد. این گامهای کوچک امکان نظارت دقیق و بازخورد فوری را فراهم میکنند و تیم عملیاتی در هر لحظه میتواند فرآیند را متوقف یا به نسخه قبلی برگرداند.
🔹مزایای کلیدی در برابر روشهای دیگر
در مقایسه با Blue-Green Deployment: که نیاز به زیرساخت دوبرابر (محیطهای مجزای آبی و سبز) و تغییر ناگهانی ترافیک دارد، Rolling Update بسیار مقرونبهصرفهتر است و با همان منابع موجود اجرا میشود.
در مقایسه با Canary Deployment: که ترافیک کاربران خاص را به نسخه جدید هدایت میکند، در Rolling Update تمرکز بر جایگزینی نمونههای سرویس است که مدیریت آن سادهتر و پیشبینیپذیرتر است.
قابلیت بازگشت آنی: در هر مرحله از استقرار میتوان بدون توقف کل سرویس به نسخه قبل بازگشت، که این امر فشار روانی تیم را به شدت کاهش میدهد.
🔹چالشها و محدودیتها
با وجود محبوبیت، Rolling Update بینقص نیست. از جمله چالشهای آن میتوان به مدیریت وضعیت دادهها در حین بهروزرسانی (بهویژه اگر نسخه جدید با ساختار دیتابیس قبلی سازگار نباشد)، هماهنگی بین سرویسهای وابسته، و زمانبر بودن فرآیند در مقیاسهای بسیار بزرگ اشاره کرد. همچنین برای تغییرات اساسی در دیتابیس یا معماری، این روش اصلاً توصیه نمیشود.
🔹زمان استفاده و ابزارهای مورد نیاز
Rolling Update برای سیستمهای با در دسترسبودن بالا (High Availability)، معماری توزیعشده و تیمهایی که تازه میخواهند فرآیند استقرار خود را بهبود بخشند، ایدهآل است. خوشبختانه ابزارهای مدرنی مثل Kubernetes (با قابلیت RollingUpdate)، AWS CodeDeploy، Ansible و ArgoCD پیادهسازی آن را به سادگی چند خط کد کاهش دادهاند.
🔹جمعبندی نهایی
Rolling Update تلاش نمیکند همه مشکلات را با اختراع دوباره چرخ حل کند، بلکه با تکیه بر سادگی، قابلیت اطمینان و هزینهی پایین، یکی از جدیترین گزینهها برای استقرار در محیط تولید باقی مانده است. اگرچه هیچ روش واحدی برای همه شرایط مناسب نیست، اما برای اکثر تیمهای DevOps که به دنبال بالانس بین امنیت، سرعت و کنترل هستند، Rolling Update همچنان یک انتخاب طلایی محسوب میشود. شاید روشهای جدیدتر جذابیت بیشتری داشته باشند، اما کمتر کسی میتواند انکار کند که این استراتژی قدیمی اما کارآمد، بارها عملیاتهای روزمره را از بحران نجات داده است.
#DevOps
@Syntax_fa | 1 417 |
| 15 | این چنل آرشیو کتابهای برنامه نویسی، برگه تقلب، پادکست و وبینار برای دولپرهاست، که بدردتون میخوره.
t.me/ArchiveDevs
دوست داشتید جوین بشید.❤️✌🏽 | 676 |
| 16 | الان استفاده از فریمورکی مثل جنگو منطقیه؟
یکی از دلایل استفاده از جنگو همیشه سرعت توسعه و پنل ادمینش بوده.
دلیل بعدی اون قابلیتهایی که از قبل داره مثل مدیریت دسترسیها و پکیجهای بیشماری که برای جنگو میتونید پیدا کنید.
و دلیل بعدی بنظرم تعداد کسانی که جنگو و پایتون بلدن خیلی زیاده و هیچوقت لنگ نیرو نمیمونید.
ولی الان دیگه استفاده ازش منطقیه؟
تو پایتون وبفریمورک خفن و مدرنی مثل FastAPI رو داریم.
زبانی مثل گولنگ رو داریم که واقعا تو بکاند شاهکاره.
هوش مصنوعی رو داریم کافیه معماری و ساختار رو مشخص کنیم، پنل ادمین و کدهای تکراری رو برامون بدون مشکل میزنه و نیاز به ابزارهای آماده رو کمتر میکنه.
از اونطرف با اینکه جنگو پشتیبانی از async رو اضافه کرده، ولی چون ذات و معماری پایهاش همگام هست، تو هندل کردن I/O تو مقیاس بالا میتونه واقعا گلوگاه بشه.
یکم فکر کنید میبینید با همون منابع تو گولنگ میشد چند برابر ریکوئست رو هندل کرد، و به لطف گوروتینها اصلا نیازی نیست درگیر پیچیدگیهای نوشتن کدهای Asynchronous برای هندل کردن I/O بشید.
سوالم اینه:
فرض کنید میخواید پروژهای رو از صفر شروع کنید.
بنظرتون جنگو همچنان یک مزیت رقابتی به حساب میاد یا تبدیل شده به گلوگاه توسعه، نگهداری و مدیریت مصرف منابع؟
@Syntax_fa | 1 362 |
| 17 | با این میتونید خیلی راحت برای وبسایتتون favicon هارو بسازید:
https://realfavicongenerator.net/
کافیه عکسو اپلود کنید و تنظیماتشو مشخص کنید.
@Syntax_fa | 1 288 |
| 18 | 💡 چرا SQL اینقدر با بقیه زبانها متفاوت است؟ (روایتی از کتاب DDIA)
مدتی پیش در حال بازخوانی چپتر دوم کتاب معروف Designing Data-Intensive Applications اثر مارتین کلپمن بودم. کلپمن در این بخش، دست روی مقایسهای میگذارد که شاید بارها شنیده باشیم، اما زاویه دید او به این ماجرا در بستر «زبانهای کوئری دیتابیس»، دیدگاه من را نسبت به SQL کاملاً تغییر داد: پارادایم Imperative (امری) در برابر Declarative (توصیفی).
اگر برای شما هم سؤال است که چرا ساختار SQL اینقدر با زبانهای سنتی برنامهنویسی فرق دارد، این خلاصه و شهود کلیدی را از دست ندهید:
🔹 تفاوت اصلی در یک نگاه
زبانهای Imperative: به کامپیوتر دستور میدهند که یک عملیات را چگونه (How) و با چه ترتیبی در حافظه اجرا کند (مانند حلقهها و تغییر گامبهگام متغیرها).
زبانهای Declarative: صرفاً مشخص میکنند که نتیجه نهایی باید چه چیزی (What) باشد و قوانین حاکم بر داده چیست. جزئیاتِ چگونگی اجرا کاملاً پنهان است.
📜 ریشه تاریخی: از فاجعه تا انقلاب SQL
در دهه ۱۹۷۰ و پیش از ظهور SQL، در مدلهای دیتابیس قدیمیتر (مثل IMS و CODASYL)، برنامهنویسان مجبور بودند با کدهای Imperative و حلقههای متوالی، یک اشارهگر (Pointer) را به صورت دستی میان رکوردها حرکت دهند تا دادهای را پیدا کنند.
بزرگترین فاجعه چه بود؟ اگر ساختار فیزیکی دیتابیس روی دیسک تغییر میکرد (مثلاً یک ستون جابهجا میشد یا نحوه ذخیرهسازی عوض میشد)، تمام کدهای پروژه خراب میشدند و باید از اول بازنویسی میشدند!
اما SQL این مشکل را حل کرد. شما فقط میگویید چه دادهای میخواهید:
SELECT * FROM users WHERE age > 18;
با این کار، وظیفه نحوه اجرا به Query Optimizer (بهینهساز کوئری دیتابیس) واگذار شد. دیتابیس خودش تصمیم میگیرد که از کدام ایندکس یا الگوریتم (مثلاً Hash Join یا Merge Join) برای استخراج داده استفاده کند و برنامهنویس درگیر جزئیات سختافزار نمیشود.
📐 ربط زبانهای Declarative به جبر رابطهای (Relational Algebra)
زبان SQL بر پایهی یک نظریه ریاضی به نام «جبر رابطهای» بنا شده است. در ریاضیات دوران مدرسه، قوانینی وجود دارد که اجازه میدهد فرمولها را ساده کنیم بدون اینکه نتیجه تغییر کند؛ مثلاً:
(x+y)⋅z=x⋅z+y⋅z
ما در ریاضی فقط فرمول را مینویسیم و نگران نیستیم که پردازنده چطور ضرب را انجام میدهد. این قوانین جبری به Query Optimizer دیتابیس اجازه میدهد تا یک عبارت پیچیده و سنگین را پشت صحنه به یک عبارت ریاضی سادهتر و بهینهتر تبدیل کند.
🌐 یک مثال شهودی: دنیای بدون CSS را تصور کنید!
فرض کنید CSS وجود نداشت و میخواستید در یک لیست، پسزمینه آیتمهای انتخابشده (selected.) قرمز شود. در رویکرد امری (با JavaScript) باید یک حلقه بنویسید، تکتک المانها را چک کنید و رنگ بزنید. این کد شکننده است؛ اگر المان جدیدی بعداً به صفحه اضافه شود، قرمز نمیشود و باید حلقه را دوباره دستوری اجرا کنید. مرورگر هم نمیتواند این حلقه دستی را موازیسازی کند.
اما در دنیای Declarative (با CSS) مینویسید:
.selected { background-color: red; }
شما فقط وضعیت ایدهآل را توصیف میکنید. حالا اگر مرورگر آپدیت شود یا شتابدهنده گرافیکی (GPU) جدیدی بیاید، مرورگر خودش پشت صحنه نحوه اعمال این رنگ را بهینهسازی میکند، بدون اینکه نیاز باشد شما کدتان را دست بزنید.
🎯 ۳ مزیت کلیدی زبانهای توصیفی (Declarative) از زبان کلپمن:
1️⃣ استقلال داده (Data Independence): کد توصیفی به ساختار فیزیکی ذخیرهسازی داده وابسته نیست. میتوانید ایندکسها را تغییر دهید یا دیتابیس را بهینهسازی کنید، بدون اینکه کدهای برنامه شما آسیب ببینند.
2️⃣ پتانسیل بالای بهینهسازی: موتورهای زیرین (مثل دیتابیس یا انجین مرورگر) کنترل کاملی روی نحوه اجرا دارند، بنابراین میتوانند کد شما را به شدت بهینهتر از یک حلقه امریِ دستی اجرا کنند.
3️⃣ قابلیت موازیسازی (Parallelization): کدهای توصیفی به دلیل عدم تغییر مستقیم وضعیت (State)، به راحتی روی چندین هسته پردازنده یا چندین سرور پخش و موازی میشوند؛ اتفاقی که در کدهای امریِ دارای حلقه، فوقالعاده سخت و پر از Bug است.
📌 شما در پروژههای خودتون چقدر سعی میکنید منطق برنامهنویسی رو به سمت Declarative ببرین؟ تجربهای از چالشهای کدهای Imperative در دیتابیسهای قدیمی دارید؟ خوشحال میشم نظراتتون رو برام بنویسید.
📖 منبع: کتاب Designing Data-Intensive Applications (Chapter 2) - Martin Kleppmann
#software_engineering #database #sql #ddia #backend #system_design #programming
@Syntax_fa | 1 581 |
| 19 | مینی اپ تلگرامی
تو کلاینت لینوکس تلگرام من یه مشکلی دارم.
حتی اکسپایر init data رو روی یه هفته گذاشتم بازم به اکسپایر میرسه و برخلاف موبایل و بقیه کلایت ها انگار کش میشه و آپدیت نمیشه.
کسی تجربه ای داره در این خصوص؟
در خصوص احراز هویت کاربر ها تو مینی اپ تلگرامی چه نکاتی رو باید رعایت کنیم؟ | 10 |
| 20 | هیچکی میرا رو دوست نداره
متاسفانه بن میشه
آخرش حرفتو بزن تو کامنتا میرا جان | 38 |
