fa
Feedback
Amin'sTechLab

Amin'sTechLab

رفتن به کانال در Telegram

🔬 Embedded Systems | AI | FPGA | PCB Design 🚀 Exploring tech at the edge of innovation 🧠 Founder of AminTechLab 📍Engineering the future – one bit at a time

نمایش بیشتر
1 962
مشترکین
+224 ساعت
+87 روز
+630 روز
جذب مشترکین
ژوئیه '26
ژوئیه '260
در 0 کانال‌ها
ژوئن '26
+27
در 0 کانال‌ها
Get PRO
مه '26
+10
در 0 کانال‌ها
Get PRO
آوریل '26
+7
در 0 کانال‌ها
Get PRO
مارس '26
+1
در 0 کانال‌ها
Get PRO
فوریه '26
+12
در 0 کانال‌ها
Get PRO
ژانویه '26
+4
در 0 کانال‌ها
Get PRO
دسامبر '25
+28
در 1 کانال‌ها
Get PRO
نوامبر '25
+36
در 1 کانال‌ها
Get PRO
اکتبر '25
+41
در 1 کانال‌ها
Get PRO
سپتامبر '25
+56
در 1 کانال‌ها
Get PRO
اوت '25
+44
در 0 کانال‌ها
Get PRO
ژوئیه '25
+20
در 0 کانال‌ها
Get PRO
ژوئن '25
+15
در 0 کانال‌ها
Get PRO
مه '25
+25
در 1 کانال‌ها
Get PRO
آوریل '25
+18
در 0 کانال‌ها
Get PRO
مارس '25
+30
در 0 کانال‌ها
Get PRO
فوریه '25
+19
در 0 کانال‌ها
Get PRO
ژانویه '25
+42
در 0 کانال‌ها
Get PRO
دسامبر '24
+34
در 0 کانال‌ها
Get PRO
نوامبر '24
+36
در 0 کانال‌ها
Get PRO
اکتبر '24
+27
در 0 کانال‌ها
Get PRO
سپتامبر '24
+17
در 0 کانال‌ها
Get PRO
اوت '24
+23
در 0 کانال‌ها
Get PRO
ژوئیه '24
+48
در 0 کانال‌ها
Get PRO
ژوئن '24
+39
در 0 کانال‌ها
Get PRO
مه '24
+44
در 0 کانال‌ها
Get PRO
آوریل '24
+32
در 0 کانال‌ها
Get PRO
مارس '24
+60
در 0 کانال‌ها
Get PRO
فوریه '24
+82
در 1 کانال‌ها
Get PRO
ژانویه '24
+48
در 2 کانال‌ها
Get PRO
دسامبر '23
+30
در 0 کانال‌ها
Get PRO
نوامبر '23
+7
در 0 کانال‌ها
Get PRO
اکتبر '23
+10
در 0 کانال‌ها
Get PRO
سپتامبر '23
+7
در 0 کانال‌ها
Get PRO
اوت '23
+5
در 0 کانال‌ها
Get PRO
ژوئیه '23
+10
در 0 کانال‌ها
Get PRO
ژوئن '23
+7
در 0 کانال‌ها
Get PRO
مه '23
+1 042
در 0 کانال‌ها
Get PRO
آوریل '23
+5
در 0 کانال‌ها
Get PRO
مارس '23
+9
در 0 کانال‌ها
Get PRO
فوریه '23
+15
در 0 کانال‌ها
Get PRO
ژانویه '23
+14
در 0 کانال‌ها
Get PRO
دسامبر '22
+1
در 0 کانال‌ها
Get PRO
نوامبر '22
+8
در 0 کانال‌ها
Get PRO
اکتبر '22
+11
در 0 کانال‌ها
Get PRO
سپتامبر '22
+7
در 0 کانال‌ها
Get PRO
اوت '22
+13
در 0 کانال‌ها
Get PRO
ژوئیه '22
+14
در 0 کانال‌ها
Get PRO
ژوئن '22
+11
در 0 کانال‌ها
Get PRO
مه '22
+18
در 0 کانال‌ها
Get PRO
آوریل '22
+14
در 0 کانال‌ها
Get PRO
مارس '22
+8
در 0 کانال‌ها
Get PRO
فوریه '22
+12
در 0 کانال‌ها
Get PRO
ژانویه '22
+12
در 0 کانال‌ها
Get PRO
دسامبر '21
+12
در 0 کانال‌ها
Get PRO
نوامبر '21
+38
در 0 کانال‌ها
Get PRO
اکتبر '21
+5
در 0 کانال‌ها
Get PRO
سپتامبر '21
+25
در 0 کانال‌ها
Get PRO
اوت '21
+27
در 0 کانال‌ها
Get PRO
ژوئیه '21
+554
در 0 کانال‌ها
Get PRO
ژوئن '21
+14
در 0 کانال‌ها
Get PRO
مه '21
+39
در 0 کانال‌ها
Get PRO
آوریل '21
+58
در 0 کانال‌ها
Get PRO
مارس '21
+88
در 0 کانال‌ها
Get PRO
فوریه '21
+112
در 0 کانال‌ها
Get PRO
ژانویه '21
+692
در 0 کانال‌ها
Get PRO
دسامبر '20
+2 352
در 0 کانال‌ها
تاریخ
رشد مشترکین
اشارات
کانال‌ها
01 ژوئیه0
پست‌های کانال
💻 یکی از قوانین کمتر شناخته‌شده اما بسیار مهم در زبان C: Strict Aliasing Rule یکی از رایج‌ترین اشتباهاتی که حتی برنامه‌نویس‌های باتجربه C مرتکب می‌شوند، تبدیل مستقیم یک اشاره‌گر به نوعی دیگر و دسترسی به داده از طریق آن است. برای مثال:
#include <stdio.h>

int main() {
    float f = 3.14f;

    int *p = (int *)&f;

    printf("%x\n", *p);

    return 0;
}
در نگاه اول شاید تصور کنیم فقط داریم بیت‌های متغیر float را به صورت یک عدد صحیح مشاهده می‌کنیم. اما مشکل اینجاست که طبق استاندارد زبان C، یک شیء باید معمولاً فقط از طریق اشاره‌گری از همان نوع خودش (یا چند استثنای مشخص) خوانده یا نوشته شود. به این قانون می‌گویند: Strict Aliasing Rule کامپایلرها هنگام فعال بودن Optimization فرض می‌کنند که اشاره‌گرهای با نوع‌های متفاوت، هرگز به یک محل از حافظه اشاره نمی‌کنند. به همین دلیل ممکن است کامپایلر کدی تولید کند که اصلاً انتظارش را ندارید. مثلاً این کد را ببینید:
int foo(float *f, int *i)
{
    *f = 0.0f;
    *i = 42;

    return *f == 0.0f;
}
اگر f و i در واقع به یک آدرس اشاره کنند (با Cast کردن)، ممکن است انتظار داشته باشید نتیجه تابع تغییر کند. اما کامپایلر مجاز است فرض کند این دو اشاره‌گر هرگز به یک داده اشاره نمی‌کنند و بر همین اساس کد را بهینه کند. در نتیجه، خروجی برنامه می‌تواند کاملاً با انتظار شما متفاوت باشد. نکته جالب اینجاست که ممکن است برنامه:
gcc main.c
کاملاً درست کار کند. اما فقط با فعال کردن Optimization:
gcc main.c -O2
رفتار برنامه تغییر کند. دلیلش این نیست که Optimization خراب است؛ بلکه برنامه از ابتدا قوانین استاندارد C را نقض کرده است. اگر هدفتان مشاهده بیت‌های یک متغیر است، روش صحیح استفاده از memcpy است:
#include <string.h>

float f = 3.14f;
int bits;

memcpy(&bits, &f, sizeof(bits));
یا در صورت نیاز، از unsigned char * برای دسترسی سطح بایت استفاده کنید؛ زیرا استاندارد C این مورد را مجاز می‌داند. چرا این قانون وجود دارد؟ کامپایلر با دانستن اینکه انواع مختلف روی یک حافظه قرار ندارند، می‌تواند: داده‌ها را داخل Register نگه دارد. دسترسی‌های غیرضروری به حافظه را حذف کند. کد بسیار سریع‌تری تولید کند. به همین دلیل است که نقض این قانون معمولاً فقط هنگام Optimization خودش را نشان می‌دهد. در زبان C، هر Castی مجاز نیست؛ گاهی یک Cast ساده می‌تواند باعث شود کامپایلر فرض‌هایی انجام دهد که نتیجه برنامه را کاملاً تغییر دهد. پس اگر برنامه‌ای بدون Optimization درست کار می‌کند اما با -O2 رفتار عجیبی پیدا می‌کند، یکی از اولین چیزهایی که باید بررسی کنید، نقض Strict Aliasing Rule است. ⚠️ @Amin_TechLab

2
🔥 قسمت ۳: فعال‌سازی حالت Performance برای CPU در لینوکس بعد از نصب cpupower، می‌توانید با یک دستور ساده CPU را روی حالت حداکثر عملکرد قرار دهید: sudo cpupower frequency-set -g performance با اجرای این دستور، Governor پردازنده روی حالت performance تنظیم می‌شود. در این حالت، سیستم تلاش می‌کند پردازنده را در سطح بالاتری از توان پردازشی نگه دارد تا برنامه‌ها سریع‌تر پاسخ دهند و پردازش‌های سنگین با تأخیر کمتری انجام شوند. این حالت برای موقعیت‌هایی مثل موارد زیر مناسب است: کامپایل پروژه‌های سنگین رندر گرفتن اجرای ماشین مجازی پردازش داده اجرای بازی تست و بنچمارک سیستم اجرای سرویس‌های حساس به تأخیر اما حالت performance همیشه بهترین انتخاب نیست. اگر از لپ‌تاپ استفاده می‌کنید، فعال بودن دائمی این حالت می‌تواند باعث افزایش مصرف باتری، بالا رفتن دمای CPU و بیشتر شدن صدای فن شود. برای برگشت به حالت کم‌مصرف‌تر می‌توانید از دستور زیر استفاده کنید: sudo cpupower frequency-set -g powersave اگر سیستم شما از schedutil پشتیبانی می‌کند، این حالت معمولاً انتخاب متعادلی بین عملکرد و مصرف انرژی است: sudo cpupower frequency-set -g schedutil جمع‌بندی ساده: performance یعنی قدرت بیشتر، مصرف بیشتر و دمای بالاتر. powersave یعنی مصرف کمتر، عملکرد محدودتر و شارژدهی بهتر. schedutil یا ondemand یعنی تعادل بین سرعت و مصرف انرژی. پس اگر به حداکثر توان CPU نیاز دارید، performance گزینه مناسبی است؛ اما برای استفاده روزمره، حالت‌های متعادل معمولاً انتخاب بهتری هستند. @Amin_TechLab
124
3
⚙️ قسمت ۲: نصب و بررسی وضعیت CPU با cpupower برای استفاده از ابزار cpupower ابتدا باید بسته مربوط به آن را نصب کنید. نام بسته در توزیع‌های مختلف لینوکس ممکن است متفاوت باشد. 📦 در اوبونتو، دبیان و توزیع‌های مبتنی بر آن‌ها: sudo apt update sudo apt install linux-tools-common در بعضی نسخه‌های اوبونتو ممکن است لازم باشد ابزار مخصوص کرنل فعلی را هم نصب کنید: sudo apt install linux-tools-$(uname -r) 📦 در فدورا: sudo dnf install kernel-tools 📦 در Red Hat / RHEL / CentOS: sudo yum install kernel-tools یا در نسخه‌های جدیدتر: sudo dnf install kernel-tools 📦 در آرچ لینوکس و توزیع‌های مبتنی بر آن: sudo pacman -S cpupower بعد از نصب، بهتر است قبل از تغییر تنظیمات، وضعیت فعلی پردازنده را بررسی کنید: cpupower frequency-info این دستور اطلاعات مهمی درباره CPU نمایش می‌دهد؛ از جمله: حداقل و حداکثر فرکانس پردازنده Governor فعال فعلی درایور مدیریت فرکانس CPU حالت‌های قابل استفاده برای مدیریت مصرف انرژی محدوده فرکانسی قابل پشتیبانی توسط پردازنده در خروجی این دستور معمولاً بخشی با عنوان available cpufreq governors وجود دارد. این بخش نشان می‌دهد سیستم شما از چه حالت‌هایی مثل performance، powersave، ondemand یا schedutil پشتیبانی می‌کند. بررسی این اطلاعات قبل از اعمال تغییرات مهم است، چون همه سیستم‌ها دقیقاً گزینه‌های یکسانی ندارند. ادامه دارد... @Amin_TechLab
167
4
تا امروز خیلی از ما از ابزارهای AI مثل Claude Code، Cursor یا Codex بیشتر شبیه یک چت‌بات استفاده می‌کردیم. یک Prompt می‌نوشتی
تا امروز خیلی از ما از ابزارهای AI مثل Claude Code، Cursor یا Codex بیشتر شبیه یک چت‌بات استفاده می‌کردیم. یک Prompt می‌نوشتیم، خروجی می‌گرفتیم، ایرادها را اصلاح می‌کردیم و دوباره Prompt جدید می‌دادیم. اما به‌نظر می‌رسد قدم بعدی برای برنامه‌نویس‌ها، چیزی فراتر از Prompt Engineering باشد: 🔥 Loop Engineering در این رویکرد، تمرکز فقط روی نوشتن Prompt بهتر نیست؛ بلکه روی طراحی یک چرخه کاری هوشمند است. یعنی به‌جای اینکه همیشه انسان مرحله‌به‌مرحله به AI بگوید چه کاری انجام دهد، یک سیستم طراحی می‌شود که Agentها بتوانند داخل آن کار را جلو ببرند. مثلاً Agent می‌تواند: 🔹 تسک‌ها را بررسی کند 🔹 کد را تغییر دهد 🔹 تست‌ها را اجرا کند 🔹 خطاها را پیدا و اصلاح کند 🔹 Pull Requestها را بررسی کند 🔹 Issueها را مدیریت کند 🔹 Changelog بسازد 🔹 و فقط وقتی تصمیم انسانی لازم بود، کار را به انسان ارجاع دهد به زبان ساده، مسیر در حال تغییر است: از این مدل: «من Prompt می‌نویسم، AI جواب می‌دهد» به این مدل: «من سیستم را طراحی می‌کنم، Agentها داخل آن سیستم کار را جلو می‌برند.» این تغییر برای تیم‌های نرم‌افزاری خیلی مهم اس
177
5
🚀 قسمت ۱: افزایش عملکرد CPU در لینوکس با cpupower اگر از لینوکس استفاده می‌کنید و می‌خواهید در کارهای سنگین، عملکرد پردازنده را افزایش دهید، یکی از ابزارهای کاربردی برای این کار cpupower است. این ابزار به شما اجازه می‌دهد حالت کاری CPU را تغییر دهید و مشخص کنید پردازنده بیشتر روی مصرف انرژی تمرکز کند یا روی حداکثر عملکرد. در لینوکس، CPU همیشه با یک فرکانس ثابت کار نمی‌کند. سیستم‌عامل با توجه به میزان فشار کاری، دما، مصرف برق و تنظیمات مدیریت انرژی، فرکانس پردازنده را کم یا زیاد می‌کند. این رفتار توسط چیزی به نام CPU Governor کنترل می‌شود. Governor در واقع سیاست کاری پردازنده را مشخص می‌کند. برای مثال: powersave مصرف انرژی را کاهش می‌دهد و معمولاً CPU را در فرکانس پایین‌تری نگه می‌دارد. ondemand فرکانس پردازنده را با توجه به نیاز سیستم کم و زیاد می‌کند. schedutil در سیستم‌های جدیدتر رایج است و تلاش می‌کند بین مصرف انرژی و عملکرد تعادل ایجاد کند. performance پردازنده را در حالت حداکثر عملکرد قرار می‌دهد. اگر در حال کامپایل پروژه‌های بزرگ، اجرای ماشین مجازی، بازی، رندر، پردازش داده یا بنچمارک هستید، حالت performance می‌تواند باعث افزایش سرعت پاسخ‌دهی سیستم شود. اما باید توجه داشت که این حالت معمولاً مصرف انرژی و دمای CPU را هم افزایش می‌دهد. پس اگر از لپ‌تاپ استفاده می‌کنید، بهتر است فقط زمانی که واقعاً به قدرت پردازشی بالا نیاز دارید، این حالت را فعال کنید. ادامه دارد... @Amin_TechLab
180
6
🐍 سه نقطه ... در پایتون فقط برای زیبایی نیست! شاید در بعضی از کدهای پایتون چیزی شبیه این دیده باشید: def process_data(): ... در نگاه اول ممکن است فکر کنیم این سه نقطه فقط برای خالی گذاشتن بدنه تابع استفاده شده یا چیزی شبیه pass است؛ اما در پایتون، ... یک مفهوم واقعی دارد. در واقع ... همان آبجکتی به نام Ellipsis است. >>> ... Ellipsis >>> type(...) <class 'ellipsis'> یعنی سه نقطه در پایتون نه کامنت است، نه صرفاً یک علامت نمایشی، بلکه یک آبجکت واقعی از نوع ellipsis محسوب می‌شود. اما سؤال اصلی اینجاست: آیا ... همان pass است؟ نه دقیقاً. pass یک statement خالی است. یعنی وقتی پایتون به آن می‌رسد، هیچ کاری انجام نمی‌دهد و فقط اجازه می‌دهد ساختار کد از نظر نحوی معتبر باقی بماند. مثلاً: def process_data(): pass اینجا pass فقط می‌گوید: «فعلاً این بخش خالی است، ولی از نظر syntax مشکلی ندارد.» اما ... یک expression است، یعنی خودش یک مقدار واقعی تولید می‌کند: x = ... print(x) خروجی: Ellipsis پس تفاوت مهم اینجاست: pass هیچ مقداری تولید نمی‌کند. ولی: ... یک آبجکت واقعی به نام Ellipsis است. یکی از کاربردهای رایج ... این است که در زمان طراحی اولیه کد، جای بخش‌هایی را که هنوز پیاده‌سازی نشده‌اند نگه داریم: class UserService: def create_user(self): ... def delete_user(self): ... این روش به‌خصوص در نوشتن اسکلت اولیه کلاس‌ها، توابع، اینترفیس‌ها یا کدهایی که قرار است بعداً تکمیل شوند، کاربرد دارد. البته از نظر خوانایی، اگر فقط می‌خواهید بگویید «اینجا هنوز کاری انجام نمی‌شود»، استفاده از pass همچنان رایج‌تر و واضح‌تر است. اما Ellipsis فقط برای خالی گذاشتن تابع نیست. در بعضی کتابخانه‌ها، مخصوصاً در حوزه‌هایی مثل NumPy، از ... برای indexing و slicing پیشرفته استفاده می‌شود. مثلاً: array[..., 0] در اینجا ... معنای خاصی دارد و به کتابخانه کمک می‌کند با ابعاد مختلف آرایه‌ها راحت‌تر کار کند. همچنین در type hinting و stub fileها هم زیاد دیده می‌شود؛ مخصوصاً در فایل‌هایی که فقط ساختار تابع یا کلاس را مشخص می‌کنند، اما پیاده‌سازی واقعی ندارند. مثلاً: def connect(host: str, port: int) -> bool: ... در این حالت، ... یعنی امضای تابع مشخص شده، اما بدنه آن در جای دیگری تعریف می‌شود یا فعلاً اهمیتی ندارد. پس دفعه بعد که در کد پایتون با ... روبه‌رو شدید، بدانید که این سه نقطه فقط یک جای‌خالی ساده نیست. ... در پایتون همان Ellipsis است؛ یک آبجکت واقعی، با کاربردهایی فراتر از چیزی که در نگاه اول به نظر می‌رسد. @Amin_TechLab
218
7
💻 یکی از خطرناک‌ترین مفاهیم در زبان C: Undefined Behavior در زبان C، همیشه این‌طور نیست که هر کدی که کامپایل می‌شود، الزاماً رفتار مشخص و قابل اعتمادی داشته باشد. گاهی برنامه از نظر ظاهری درست به نظر می‌رسد، کامپایلر هم هیچ خطایی نمی‌دهد، اما نتیجه اجرای برنامه می‌تواند کاملاً غیرقابل پیش‌بینی باشد. به این حالت در زبان C می‌گوییم: Undefined Behavior یا به اختصار: UB یعنی استاندارد زبان C هیچ تضمینی نمی‌دهد که برنامه دقیقاً چه رفتاری داشته باشد. برای مثال به این کد دقت کنید: #include <stdio.h> int main() { int x = 5; int y = x++ + ++x; printf("%d\n", y); return 0; } شاید در نگاه اول فکر کنیم مقدار y قابل محاسبه است. اما مشکل اینجاست که در این عبارت، متغیر x بیش از یک بار بین دو نقطه‌ی مشخص از اجرای برنامه تغییر کرده است و ترتیب دقیق این تغییرات تضمین‌شده نیست. نتیجه؟ ممکن است در یک کامپایلر عددی چاپ شود، در کامپایلر دیگر عددی متفاوت، و حتی با تغییر سطح optimization نتیجه عوض شود. مثلاً اجرای برنامه با: gcc main.c ممکن است یک خروجی بدهد، اما با: gcc main.c -O2 خروجی متفاوتی ببینیم. این یعنی برنامه وارد محدوده‌ی Undefined Behavior شده است. یک نمونه معروف‌تر: int arr[3] = {1, 2, 3}; printf("%d\n", arr[5]); اینجا ما در حال دسترسی به خانه‌ای خارج از محدوده‌ی آرایه هستیم. زبان C جلوی ما را نمی‌گیرد، اما این به معنی درست بودن کد نیست. ممکن است برنامه اجرا شود، ممکن است مقدار بی‌معنی چاپ کند، ممکن است crash کند، یا حتی ظاهراً بدون مشکل کار کند. و همین «ظاهراً بدون مشکل کار کردن» خطرناک‌ترین بخش ماجراست. در زبان‌هایی مثل Python یا Java معمولاً چنین خطاهایی سریع‌تر و واضح‌تر مشخص می‌شوند، اما در C مسئولیت زیادی روی دوش برنامه‌نویس است. برای جلوگیری از Undefined Behavior بهتر است: int x = 5; x++; int y = x; x++; y += x; به‌جای نوشتن عبارت‌های پیچیده، تغییرات را مرحله‌به‌مرحله و خوانا بنویسیم. زبان C بسیار سریع، قدرتمند و نزدیک به سخت‌افزار است؛ اما همین قدرت باعث می‌شود کوچک‌ترین بی‌دقتی، رفتار برنامه را غیرقابل پیش‌بینی کند. پس در C فقط کامپایل شدن کد کافی نیست؛ باید مطمئن باشیم کد از نظر استاندارد زبان هم رفتار مشخصی دارد. ⚠️ @Amin_TechLab
193
8
💻 آشنایی با چند اپراتور کمتر شناخته‌شده در زبان C در زبان C، مقادیری که روی آن‌ها عملیات انجام می‌شود را Operand و نماد انجام‌دهنده عملیات را Operator می‌نامیم. برای مثال در کد زیر: if (x > y) { ... } متغیرهای x و y نقش Operand را دارند و علامت > یک Operator است. اما در میان اپراتورهای زبان C، چند مورد وجود دارد که شاید کمتر به آن‌ها توجه کرده باشید. یکی از آن‌ها Comma Operator یا همان اپراتور ویرگول است. در زبان C، ویرگول همیشه فقط برای جدا کردن آرگومان‌ها یا متغیرها نیست؛ گاهی خودش یک اپراتور واقعی است. این اپراتور چند عبارت را از چپ به راست اجرا می‌کند، اما مقدار نهایی آن برابر با مقدار آخرین عبارت است. مثلاً: int x; x = (printf("Hello\n"), 10); در این کد، ابتدا دستور printf اجرا می‌شود و سپس مقدار 10 داخل متغیر x قرار می‌گیرد. یعنی بعد از اجرای کد بالا، مقدار x برابر با 10 خواهد بود. یک نمونه کاربردی‌تر: int i = 0; int j = 0; while (i < 5) j += i, i++; در اینجا ابتدا مقدار i به j اضافه می‌شود و سپس i یک واحد افزایش پیدا می‌کند. البته باید حواسمان باشد که استفاده زیاد از این اپراتور می‌تواند خوانایی کد را پایین بیاورد؛ برای همین معمولاً بهتر است فقط در جاهایی استفاده شود که واقعاً کد را تمیزتر می‌کند. حالا سراغ یک مورد عجیب‌تر برویم؛ چیزی که خیلی از برنامه‌نویس‌های C حتی اسمش را هم کمتر شنیده‌اند: Digraphs. در زبان C، برای بعضی از نمادها، شکل‌های جایگزین وجود دارد. مثلاً به جای { و } می‌توان از <% و %> استفاده کرد. یعنی این کد: int main() { return 0; } می‌تواند به شکل زیر هم نوشته شود: int main() <% return 0; %> یا مثلاً به جای [ و ] می‌توان از <: و :> استفاده کرد: int arr<:3:> = <%1, 2, 3%>; که معادل این کد است: int arr[3] = {1, 2, 3}; این قابلیت در گذشته برای سیستم‌هایی کاربرد داشت که بعضی کاراکترهای خاص مثل { یا [ روی کیبورد یا سیستم‌عاملشان به‌راحتی در دسترس نبود. امروزه Digraphها تقریباً کاربرد عملی خاصی ندارند و بیشتر به‌عنوان یک ویژگی تاریخی و عجیب در زبان C شناخته می‌شوند. 😄 @Amin_TechLab
176
9
❌ پیام آخرین Commit رو اشتباه نوشتید؟ لازم نیست برای اصلاحش یک Commit جدید بسازید. اگر می‌خواهید پیام آخرین Commit را تغییر دهید، می‌توانید از Interactive Rebase استفاده کنید: git rebase -i HEAD~1 سپس در فایل بازشده، این خط را: pick abc123 Fix logni page به این شکل تغییر دهید: reword abc123 Fix logni page بعد از ذخیره و خروج، Git از شما می‌خواهد پیام جدید Commit را وارد کنید: Fix login page 📌 دستورات مهم در Interactive Rebase: pick → استفاده از Commit بدون تغییر reword → تغییر پیام Commit edit → ویرایش Commit squash → ادغام با Commit قبلی fixup → ادغام بدون نگه داشتن پیام Commit drop → حذف Commit 💡 البته اگر فقط قصد دارید پیام آخرین Commit را تغییر دهید، معمولاً این دستور سریع‌تر و ساده‌تر است: git commit --amend -m "NEW MESSAGE" @Amin_TechLab
239
10
❌ پیام آخرین Commit رو اشتباه نوشتید؟ لازم نیست برای اصلاحش یک Commit جدید بسازید. اگر می‌خواهید پیام آخرین Commit را تغییر دهید، می‌توانید از Interactive Rebase استفاده کنید: git rebase -i HEAD~1 سپس در فایل بازشده، این خط را: pick abc123 Fix logni page به این شکل تغییر دهید: reword abc123 Fix logni page بعد از ذخیره و خروج، Git از شما می‌خواهد پیام جدید Commit را وارد کنید: Fix login page 📌 دستورات مهم در Interactive Rebase: pick → استفاده از Commit بدون تغییر reword → تغییر پیام Commit edit → ویرایش Commit squash → ادغام با Commit قبلی fixup → ادغام بدون نگه داشتن پیام Commit drop → حذف Commit 💡 البته اگر فقط قصد دارید پیام آخرین Commit را تغییر دهید، معمولاً این دستور سریع‌تر و ساده‌تر است: git commit --amend -m "NEW MESSAGE" @Amin_TechLab
1
11
🐍 چرا Generic Typing در پایتون اهمیت دارد؟ بسیاری از توسعه‌دهندگان هنگام استفاده از Type Hinting فقط سراغ انواع مشخصی مثل str، int یا list[str] می‌روند. اما وقتی یک تابع یا کلاس قرار است با چند نوع داده مختلف کار کند، Generic Typing به شما کمک می‌کند بدون از دست دادن Type Safety، کدی منعطف‌تر و قابل‌استفاده‌تر بنویسید. به جای اینکه برای هر نوع داده یک تابع جداگانه تعریف کنید، می‌توانید یک Type Variable بسازید و نوع ورودی و خروجی را به آن وابسته کنید. در این حالت ابزارهایی مانند MyPy و Pyright نیز می‌توانند ناسازگاری‌های نوعی را قبل از اجرای برنامه تشخیص دهند. from typing import TypeVar T = TypeVar("T") def first(items: list[T]) -> T: return items[0] در مثال بالا، تابع first می‌تواند لیستی از هر نوع داده‌ای را دریافت کند؛ اما نوع خروجی همیشه دقیقاً با نوع عناصر لیست یکسان خواهد بود. برای درک بهتر قدرت Genericها، به مثال زیر توجه کنید: def select[T](items: list[T]) -> T: ... این تابع بسته به نوع داده‌ای که دریافت می‌کند، مقدار T را به‌صورت خودکار تعیین می‌کند: select([1, 2, 3, 4, 5]) # T = int select(["a", "b", "c"]) # T = str select([1.2, 1.3, 1.4]) # T = float حتی برای انواع تعریف‌شده توسط خودتان نیز همین اتفاق می‌افتد: users = [User("Abby"), User("Chris"), User("Nick")] select(users) # T = User همان‌طور که می‌بینید، نوع T ثابت نیست و بر اساس نوع داده‌ای که به تابع ارسال می‌شود تعیین خواهد شد. این دقیقاً جوهره Generic Typing است. ❓ چرا معمولاً از حرف T استفاده می‌شود؟ در واقع هیچ اجباری برای استفاده از T وجود ندارد. این فقط یک قرارداد رایج بین برنامه‌نویسان است؛ درست مثل بسیاری از Conventionهای دیگر در دنیای توسعه نرم‌افزار. بنابراین کد زیر کاملاً معتبر است: def duplicate[B](item: B) -> tuple[B, B, B]: return (item, item, item) همچنین می‌توانید از چند Generic Type به‌طور هم‌زمان استفاده کنید: def pair[A, B](first: A, second: B) -> tuple[A, B]: return (first, second) در این مثال، نوع A و B مستقل از یکدیگر هستند و می‌توانند هر نوع داده‌ای را نمایش دهند. Generic Typing یکی از ابزارهای مهم برای نوشتن کدهای reusable، type-safe و قابل نگهداری در پروژه‌های بزرگ پایتونی است. 📚 منبع: https://blog.imsadra.dev/generic-typing-in-python @Amin_TechLab
346
12
🐍 آشنایی با چند اپراتور کمتر شناخته‌شده در پایتون در پایتون، مقادیری که روی آن‌ها عملیات انجام می‌شود را Operand و نماد انجام‌دهنده عملیات را Operator می‌نامیم. برای مثال در کد زیر: if x > y: ... متغیرهای x و y نقش Operand را دارند و علامت > یک Operator است. اما در میان اپراتورهای پایتون، موردی وجود دارد که خیلی از برنامه‌نویس‌ها کمتر با آن آشنا هستند: Walrus Operator (:=). این اپراتور علاوه بر انجام مقایسه یا ارزیابی یک عبارت، همزمان مقدار آن را در یک متغیر نیز ذخیره می‌کند. مثلاً معمولاً کدی شبیه این می‌نویسیم: length = len("test1234") if length < 8: print(f"Your password is {length} chars long.") اما با استفاده از Walrus Operator می‌توان همان کار را به شکل خلاصه‌تر انجام داد: if (length := len("test1234")) < 8: print(f"Your password is {length} chars long.") نکته جالب اینجاست که فارغ از نتیجه شرط، متغیر length پس از اجرای این دستور همچنان در دسترس خواهد بود. حالا سراغ یک اپراتور عجیب‌تر برویم؛ چیزی که احتمالاً هرگز در کدهای واقعی ندیده‌اید! در نسخه‌های قدیمی پایتون، برای عملگر «نامساوی» به‌جای != از <> استفاده می‌شد. این سینتکس سال‌هاست منسوخ شده، اما هنوز به‌عنوان یک ایستر اگ (Easter Egg) در پایتون وجود دارد. from __future__ import barry_as_FLUFL بعد از اجرای این دستور، پایتون شما را مجبور می‌کند به جای != از <> استفاده کنید: >>> 2 != 3 SyntaxError: with Barry as BDFL, use '<>' instead of '!=' >>> 2 <> 3 True نام این قابلیت از Barry Warsaw، یکی از توسعه‌دهندگان قدیمی پایتون، گرفته شده است. البته کاربرد عملی خاصی ندارد و بیشتر یک شوخی تاریخی در دل زبان پایتون محسوب می‌شود. 😄 📚 منبع: https://blog.imsadra.dev/10-python-easter-eggs @Amin_TechLab
292
13
🔍 Unlimited-OCR by Baidu A powerful OCR model from Baidu that takes things a step beyond DeepSeek-OCR. It features long-hori
🔍 Unlimited-OCR by Baidu A powerful OCR model from Baidu that takes things a step beyond DeepSeek-OCR. It features long-horizon parsing, enabling one-shot processing of lengthy documents—including single images, multi-page documents, and entire PDFs. The model supports Transformers and SGLang, and delivers high-quality structured outputs for document understanding and information extraction. 🔗 github.com/baidu/Unlimited-OCR @Amin_TechLab
271
14
❗️پیام موقت ❗️ درود دوستان یکی از دوستان عزیز و همکاران بنده که از لحاظ فنی و اخلاقی به صورت کامل مورد تایید بنده هستن . جویای کار تخصصی در الکترونیک و امبدد سیستم هستن در شهر تهران . به طور خلاصه بیش از ۳ سال تجربه کار طراحی دارند مسلط به آلتیوم و طراحی مدار و ساخت برد . تسلط کار با میکروکنترلر های avr,stm32,esp . مسلط به زبان پایتون و سی . لطفا دوستان هر شخص موقعیت شغلی داشتن لطفا به بنده پیام اعلام کنن تا رزومه و نمونه کار های ایشون رو ارسال کنم . با تشکر از تمام عزیزان . ای دی جهت ارسال پیام :
46
15
رفقا براتون یک سری رفرنس خوب برای آشنایی عمیق از لینوکس فرستادم . اینکه چی میخونید برق یا کامپیوتر مهم نیست ، صفت بچسبید لینوکس یادبگیرید . اگر لینوکس بلد بودید به نظرم میدونی کامپیوتر که حلوت هست چه جوری میتونی به بهترین و بهینه ترین شکل ممکن ازش استفاده کنید . اینو من راجب تمام سیستم عامل های unix بیس میکنم ولی اگر بلد نبودی به نظرم با اون حساب دار یا انبار داری که اکسل رو باز میکنه تو ویندوزش هیچ فرق نداریم . اگر لینوکس بدونی ، یعنی سخت افزار رو درک کردی ، اگر لینوکس بدونی یعنی میفهمی زبان برنامه سطح پایین چیه اگر لینوکس بدونی یعنی سی بلدی اگر لینوکس بدونی یعنی مدیریت تسک رو درک کردی اگر لینوکس بدونی یعنی مهندسی رو فهمیدی .... ارادمند تمام عزیزان 🫡🌹 @Amin_TechLab
580
16
Understanding the Linux Kernel Daniel P. Bovet Marco Cesati Publisher: O'Reilly @Amin_TechLab
523
17
Understanding the Linux Kernel Daniel P. Bovet Marco Cesati Publisher: O'Reilly @Amin_TechLab 👇👇👇👇👇👇👇
Understanding the Linux Kernel Daniel P. Bovet Marco Cesati Publisher: O'Reilly @Amin_TechLab 👇👇👇👇👇👇👇
499
18
The Linux Programming inTerface A Linux and UNIX® System Programming Handbook Michael KerrisK @Amin_TechLab
436
19
The Linux Programming inTerface A Linux and UNIX® System Programming Handbook Michael KerrisK @Amin_TechLab 👇👇👇👇👇👇👇
The Linux Programming inTerface A Linux and UNIX® System Programming Handbook Michael KerrisK @Amin_TechLab 👇👇👇👇👇👇👇
401
20
Linux Kernel Development Third Edition Robert Love @AminTechLab
341