Gopher Academy
3.33K subscribers
915 photos
40 videos
279 files
1.96K links
🕸 Gopher Academy

🔷interview golang
https://github.com/mrbardia72/Go-Interview-Questions-And-Answers

حمایت مالی:
https://www.coffeete.ir/mrbardia72

ادمین:
@mrbardia72
Download Telegram
Forwarded from Software Engineer Labdon
🐧 ویرایشگر کد Zed :
امکان غیرفعال‌سازی هوش مصنوعی 

🔹اZed چیست؟
اZed یک ویرایشگر کد مدرن و متن‌باز است که ویژگی‌های منحصر‌به‌فردی ارائه می‌دهد: 
سبک و سریع (حتی روی سیستم‌های ضعیف) 
پشتیبانی از چندین زبان برنامه‌نویسی 
امکانات پیشرفته مانند دیباگر داخلی و Git Integration 

🔹 ویژگی جدید:
غیرفعال‌سازی هوش مصنوعی در آخرین آپدیت + امکان خاموش کردن کامل قابلیت‌های هوش مصنوعی اضافه شده است. 

🔸 مزایای این قابلیت:
- حفظ حریم خصوصی
(عدم ارسال کدها به سرورهای خارجی) 
- کاهش مصرف منابع سیستم 
- تمرکز بیشتر روی کدنویسی بدون مزاحمت پیشنهادات AI 
- امکان استفاده از مدل‌های محلی به جای سرویس ابری 

🔹 نحوه غیرفعال‌سازی:
- باز کردن تنظیمات (Ctrl+, یا Cmd+,) 
- جستجوی "AI" 
- غیرفعال کردن گزینه‌های مربوطه 

🔹 مقایسه با سایر ویرایشگرها:
- سرعت: Zed > VS Code > JetBrains 
- هوش مصنوعی: Zed (انعطاف‌پذیر) - VS Code (وابسته به افزونه) - JetBrains (پولی) 
- متن‌باز بودن: Zed و VS Code متن‌باز هستند 

🔹 دانلود:
🌐 وبسایت رسمی: zed.dev 
📥 برای ویندوز، مک و لینوکس در دسترس است.

👤 نویسنده: امیرحسین قاسم‌زاده
📚 منبع: zed.dev

https://t.me/addlist/QtXiQlynEJwzODBk
2
استفاده از هوش مصنوعی در مصاحبه‌های شغلی متا آزاد شد!

▪️متا به‌زودی به برنامه‌نویس‌های تازه‌وارد اجازه می‌ده حین تست کدنویسی از ابزارهای هوش مصنوعی استفاده کنن!

▪️چرا؟! چون اینطوری :

1. بهتر به واقعیت محیط کاری نزدیک می‌شن
2. جلوی تقلب‌های پنهانی با AI گرفته می‌شه ، چون دیگه خود استفاده از AI بخشی از تست حساب می‌شه!

🧠 متا می‌گه آینده‌ی کدنویسی با هوش مصنوعیه، پس مصاحبه‌ها هم باید با این واقعیت همسو بشن.
👍8🍾1
پردازش ۱.۲ میلیون پیام در ثانیه با Kafka و Go — معماری سبک اما حرفه‌ای

وقتی نرخ ورود داده به میلیون‌ها پیام در ثانیه می‌رسد، عامل تعیین‌کننده در یک معماری بهینه و سریع و موثر، نه ارتقای پرهزینه‌ی سخت‌افزار است و نه تکیه بر زیرساخت‌های سنگین ابری، بلکه یک طراحی دقیق، ساده و هوشمندانه است که می‌تواند تفاوت واقعی را رقم بزند.
اخیراً با مقاله‌ای مواجه شدم که دقیقاً همین رویکرد را نشان می‌داد: تیمی که با استفاده از مفاهیم سبک‌وزن مانند goroutine در Go و چند تصمیم مهندسی‌شده، توانسته بودند تنها با یک سخت‌افزار معمولی، بیش از ۱ میلیون پیام در ثانیه را به‌صورت پایدار پردازش کنند.
در این پست، به مرور نکات کلیدی این معماری ساده اما تأثیرگذار می‌پردازیم — روایتی کاربردی از دنیای مهندسی داده و سیستم‌های توزیع‌شده.

مقاله اصلی:
Kafka at 1M Messages/Second with Go – Our Exact Pipeline Setup

چالش‌ها:
- هجوم سنگین داده‌ها از دستگاه‌های IoT و کاربران
- نیاز به پردازش بلادرنگ و ارسال همزمان به چند سرویس
- تضمین پایداری، مانیتورینگ دقیق و ریکاوری خودکار در خطا

مکانیزم‌هایی که این معماری را ممکن کردند:
- کامیت دستی offsetها:
تأیید دریافت فقط زمانی انجام می‌شود که پیام کاملاً و با موفقیت پردازش شده باشد — جلوگیری از گم‌شدن یا پردازش تکراری داده‌ها.
- مکانیزم Worker Pool کنترل‌شده با goroutine:
به‌جای ایجاد goroutine برای هر پیام، یک استخر ثابت از goroutineها (به ازای هر پارتیشن کافکا) با طول کانال مشخص و محدود، تعریف شده است که پیام‌ها را موازی اما کنترل‌شده پردازش می‌کنند.
- یک Worker Pool به ازای هر پارتیشن Kafka:
مثلاً با ۱۰ پارتیشن و ۵ goroutine برای هر پارتیشن، در مجموع ۵۰ goroutine داریم — بدون هم‌پوشانی، بدون رقابت اضافه.
- الگوی Dispatcher برای جداسازی دریافت از پردازش:
- بخش اول: فقط دریافت پیام و ارسال به کانال داخلی (یک کانسیومر به ازای هر پارتیشن)
- بخش دوم: پردازش پیام از صف به کمک Worker Pool
- مکانیزم Batching در ارسال خروجی:
پیام‌های پردازش‌شده به‌صورت گروهی ارسال می‌شوند، مثلاً به دیتابیس یا تاپیک‌های دیگر Kafka. این کار فشار ارتباطی را کاهش داده و throughput را بالا برده است.
- اعمال Backpressure هوشمند:
با محدود کردن ظرفیت صف‌ها، اگر سیستم تحت فشار شدید قرار گیرد، مصرف از Kafka موقتاً کند یا متوقف می‌شود تا منابع آزاد شوند. این مکانیزم، از overload جلوگیری کرده و سیستم را در حالت پایدار نگه می‌دارد.
- مانیتورینگ دقیق با Prometheus و Grafana:
شاخص‌هایی مثل تأخیر پردازش، consumer lag و مصرف CPU به‌صورت لحظه‌ای مانیتور می‌شوند — برای تنظیم سریع و واکنش فوری.

نتایج:
- نرخ پردازش: ۱.۲M msg/sec
- تأخیر کل مسیر: <۳ms
- مصرف CPU: ۹۰٪ (پایدار و قابل پیش‌بینی)

نکات مهم برای مهندسان داده و سیستم‌های توزیع‌شده:
- طراحی درست مهم‌تر از افزایش منابع
- انجام commit دقیق، batching و backpressure = ستون‌های یک سیستم مقاوم
- تفکیک دریافت/پردازش + تقسیم کار بین پارتیشن‌ها = مقیاس‌پذیری مؤثر
- مانیتورینگ لحظه‌ای = پاسخ سریع به فشارها و خطاها

| <Mojtaba Banaie/>
👍32🍾2
ما وقتی برنامه Go مون رو می‌بندیم، فقط یه Ctrl+C می‌زنیم و می‌گیم:
“خب، shutdown شد!”
و تمام!
ولی واقعیت اینه که خاموش شدن یه سرویس واقعی، اونم توی Production،
خیلی بیشتر از یه سیگنال ساده‌ست.


اگه درست پیاده‌سازی نشه:
- ممکنه وسط ارسال درخواست، ارتباط قطع شه
- جاب‌ها در حال پردازش نصفه‌کاره بمونن
- کانکشن‌ها به دیتابیس یا Redis نشت کنن
- و حتی برنامه قبل از تموم شدن goroutineها، کلاً بسته شه


تو این مقاله، به‌صورت خلاصه نوشتم:
- چطور با signal.NotifyContext درست shutdown رو هندل کنیم
- چطور http.Server رو با Shutdown(ctx) ببندیم
- چطور workerها رو با context و sync.WaitGroup تمیز ببندیم
- و تو Kubernetes چطور از terminationGracePeriodSeconds درست استفاده کنیم

https://medium.com/@a.mousavi/graceful-shutdown-in-go-part-1-build-production-ready-services-without-dropping-requests-b55934c217c1
7👍5🍾2
Forwarded from AI Labdon
عرفی هیولای جدید گوگل ؛ آیا با خطرناک‌ترین هوش مصنوعی دنیا روبه‌رو هستیم؟

▪️گوگل به‌تازگی از مدل پیشرفته‌ی خودش به‌نام Gemini 2.5 Deep Think رونمایی کرده؛ مدلی که در آزمایش‌ها حتی موفق به کسب مدال طلا در المپیاد جهانی ریاضی شده!

▪️این مدل فقط برای کاربران پلن Ultra با قیمت ماهانه 250 دلار در دسترسه و استفاده ازش با هشدارها و محدودیت‌های خاصی همراهه.

▪️در تست‌های داخلی تابستون 2024، گوگل رسماً اعلام کرده Deep Think در حال نزدیک شدن به مرزهایی‌ست که ممکنه اون رو به ابزاری غیرقابل کنترل در دستان افراد نادرست تبدیل کنه
8
مقاله «Writing Go Code like a Pro!» در Go Chronicles، همراه با نکات مهم و مثال‌های کوچک برای درک بهتر:

---

🧠 نکات کلیدی برای نوشتن کد حرفه‌ای در Go

1. نام‌گذاری متغیرها و توابع

* از camelCase استفاده کنید و از snake\_case پرهیز شود.
مثال: myVariable بجای my_variable ☑️
* نام‌ها را کوتاه ولی واضح نگه دارید؛ بسته به scope، اسم کوتاه‌تر مناسب‌تر است.
* برای شاخص‌ حلقه‌ها از حروف تک مثل i استفاده کنید، نه index.

> بیشترین زمان را برای خواندن کد دیگران می‌گذارید، پس کدی بنویسید که دیگران بدون دردسر بفهمند.

---

2. نام‌گذاری پکیج‌ها

* نام پکیج‌ها باید کوتاه، پایین‌نویس (lowercase) و معمولاً مفرد باشند (مثلاً service بجای services, utils توصیه نمی‌شود).

---

3. طراحی ساختار پروژه

* پروژه‌های کوچک: تمام فایل‌ها در ریشه، مثل main.go.
* برای پروژه‌های با چند executable: ساختار پیشنهادی:


cmd/
app1/
app2/
internal/
go.mod
README.md

* فقط وقتی نیاز واقعی به جداکردن logic دارید، پکیج مجزا در internal/ بسازید.

---

4. رعایت اصول Domain-Driven Structure

* پکیج‌ها را براساس سرویس‌ها و موجودیت‌های دامنه تعریف کنید (مثلاً پکیج‌هایی مثل account, inventory).
* اجتناب از ساختار تقلیدی MVC یا مدل‌هایی که ممکن است منجر به circular dependency شود.

---

5. شروع ساده و افزایش تدریجی ساختار

* اگر ایده‌ای ندارید، فقط با go.mod و main.go شروع کنید؛ بعد با رشد پروژه، نیاز به طبقه‌بندی دقیق‌تر را تشخیص دهید. شروع مینیمال، کد قابل نگهداری را تسهیل می‌کند.

---

6. فایل‌های مرتبط را کنار هم نگه دارید

* توابع مرتبط، typeها و handlerهای یک واحد منطقی را در فایل‌های نزدیک یا مشابه قرار دهید؛ این کار خوانایی را بالا می‌برد.

---

7. اندازه فایل مهم نیست... مگر نگهداری را دشوار کند

* فایل‌های بزرگ ایرادی ندارند، تا وقتی که نگهداری آن‌ها راحت باشد. لازم نیست برای چند فایل ساده، پکیج ایجاد کنید.

---

8. وقتی لازم نیست پکیج جدا نسازید

* از ایجاد پکیج‌های کم‌اهمیت یا بسیار جزئی خودداری کنید؛ مگر قصد reuse مجزا یا جداسازی واضح logic را داشته باشید.)

---

9. به علائم هشدار ساختار دقت کنید

اگر موارد زیر را دیدید، زمان بازبینی ساختار فرارسیده:

* مشکل در یافتن نقاط کد،
* تغییرات گسترده در بخش‌های متفاوت،
* سخت شدن debug،
* وابستگی حلقوی یا پیچیدگی error handling.

---

💡 جمع‌بندی نهایی

* تأکید روی خوانایی، نگهداری‌پذیری و ساختار معقول.
* شروع از ساده‌ترین حالت، حفظ نام‌گذاری استاندارد Go و اجتناب از ساختارهای پیچیده غیر idiomatic Go.
* اجازه دهید پروژه در طول زمان ساختار مناسب خودش را بیابد، نه طراحی اولیه‌ی کاملاً دقیق.
4👍2
📝 نکات کاربردی درباره strings.Builder

1. چهار روش نوشتن مختلف

strings.Builder از چهار روش برای افزودن محتوا پشتیبانی می‌کند:

* Write([]byte), WriteByte(byte), WriteRune(rune), WriteString(string)
بسته به نوع داده‌ای که در اختیار دارید، می‌توانید روش مناسب را استفاده کنید

2. نحوه ذخیره‌سازی داخلی

این نوع از یک slice داخلی استفاده می‌کند که نوشتن‌ها به صورت append در آن انجام می‌شوند. بنابراین عملکرد آن مشابه append روی slice است

3. استفاده‌ی بهینه با Grow(n)

قبل از نوشتن با حجم بالا، بهتر است با Grow(n) ظرفیت را از پیش افزایش دهید تا از realloc جلوگیری شود:

* اگر ظرفیت فعلی کافی باشد، گسترش اتفاق نمی‌افتد.
* اگر ظرفیت کافی نباشد، با فرمول current_capacity*2 + n افزایش پیدا می‌کند

4. عملکرد String()

متد String() بدون تخصیص حافظه اضافی، یک رشته جدید از buffer داخلی ایجاد می‌کند—با استفاده از `unsafe`، فقط اشاره‌گر را باز می‌گرداند

### 5. هرگز یک Builder غیرصفر را کپی نکنید

کپی کردن یک `strings.Builder` که قبلاً نوشته شده باشد منجر به panic می‌شود:

var b1 strings.Builder
b1.WriteString("ABC")
b2 := b1
b2.WriteString("DEF") // panic!


فقط اشیاء صفر مقدار (بدون نوشتن) قابل کپی هستند

6. عدم پشتیبانی هم‌زمانی (Concurrency)

strings.Builder ایمن برای استفاده هم‌زمان از چند goroutine نیست؛ خواندن یا نوشتن هم‌زمان می‌تواند منجر به نتایج غیرمنتظره شود

7. پیاده‌سازی io.Writer

رابط Write(p []byte) (int, error) پیاده‌سازی شده است، بنابراین می‌توانید از strings.Builder به عنوان یک io.Writer استفاده کنید—مثلاً log‌سازی، fmt.Fprintf و …

---

⚡️ مثال استفاده

package main

import (
"fmt"
"strings"
)

func main() {
var sb strings.Builder
sb.Grow(100)

sb.WriteString("Hello")
sb.WriteByte(' ')
sb.WriteRune('世')
sb.WriteString("界")

fmt.Println(sb.String()) // خروجی: "Hello 世界"
fmt.Printf("Len=%d, Cap=%d\n", sb.Len(), sb.Cap())
}


در این مثال:

* از Grow(100) برای کاهش realloc استفاده کردیم.
* با ترکیب WriteString, WriteByte, و WriteRune یک رشته UTF‑8 ساختیم.
* قابلیت گرفتن طول و ظرفیت نیز وجود دارد.
|
5👍2
چی هست fuzz testing؟

* در Go 1.18، fuzz testing به‌صورت داخلی وارد stdlib شد**؛ ابزاری که به‌طور خودکار ورودی‌های تصادفی تولید کرده و تابع مورد نظر را تست می‌کند تا **Bugها و edge caseها را بیابد
* برخلاف تست‌های واحد که ورودی‌های مشخص دارند، fuzz با تکیه بر یک seed corpus (مثلاً تعدادی ورودی اولیه) شروع گرفته و بر اساس راهنمای پوشش کد تست را گسترش می‌دهد، مسیرهای جدید کد را کشف می‌کند و موارد جالبی تولید می‌کند که تست‌های سنتی ممکن است پوشش ندهند

---

2. نحوه نوشتن fuzz test در Go

func FuzzReverse(f *testing.F) {
f.Add("abc") // seed اولیه
f.Add("bb")
f.Fuzz(func(t *testing.T, str string) {
rev1 := Reverse(str)
rev2 := Reverse(rev1)
if str != rev2 {
t.Errorf("fuzz test failed: %q became %q", str, rev1)
}
if utf8.ValidString(str) && !utf8.ValidString(rev1) {
t.Errorf("invalid utf-8 after reverse: %q", rev1)
}
})
}


* تابع FuzzXXX در فایل تست نوشته می‌شود؛
* f.Add(...) ورودی‌های اولیه را مشخص می‌کند (seed corpus)؛
* f.Fuzz(...) تابع تست را با signature مشخص اجرا می‌کند و Go وظیفه دارد ورودی‌های جدید را تولید و اجرا کند

---

3. مزایا و معایب

مزایا:

* افزایش پوشش تست و کشف خطاهای نادیده‌گرفته‌شده: به‌ویژه برای parserها، handlers با JSON یا ورودی پیچیده
* سهولت استفاده: تست زیاد بدون نیاز به نوشتن دستی هزاران ورودی.
* هر بار موارد جالب کشف‌شده ذخیره‌شده و قابل اجرای مجدد هستند

معایب یا چالش‌ها:

* نیاز به طراحی درست تابع تحت تست (مثلاً برگشت error برای ورودی نامعتبر مانند invalid UTF-8)
* زمان‌بر بودن تست: اجرای fuzz برای هزاران ورودی ممکن است زمان زیادی ببرد
* در مولفه‌های پیچیده‌تر (مثلاً structهایی با فیلد private) ممکن است نیاز به ساخت custom generator باشد.

---

4. تجربه افراد و ابزارهای مکمل

* سیستم‌هایی مثل go-fuzz (پیش از نسخه رسمی Go) برای fuzz کردن بسته‌های Go استفاده می‌شد و بسیار موثر بود
* کتابخانه‌های property-based مانند pgregory.net/rapid گزینه‌ی جایگزینی هستند که قابلیت‌های پیشرفته توليد داده، مینیمال‌سازی خطاها و persistence را ارائه می‌دهند
* جامعه توسعه‌دهنده‌ها تجربه‌های بسیار مثبتی داشته‌اند:
4
Forwarded from Software Engineer Labdon
🌟 ۵ استراتژی کلیدی برای دسترسی بالا (High Availability)

۱. 🍎 Load Balancing

توزیع هوشمند درخواست‌ها به سرورهای مختلف با در نظر گرفتن معیارهایی مثل مصرف CPU، حافظه و زمان پاسخ‌گویی. این کار از بارگذاری بیش‌ازحد یک سرور جلوگیری کرده و تضمین دسترسی مناسب را فراهم می‌کند

۲. 🔁 Data Redundancy with Isolation

ایجاد نسخه‌های متعدد از داده‌ها در دیتاسنترها یا مناطق مختلف (AZ/Region) برای جلوگیری از توقف سرویس در صورت خرابی یک محل. تکنیک‌هایی مثل replication و توزیع داده استفاده می‌شود

۳. 🛠 Failover

راه‌اندازی خودکار سرویس‌های پشتیبان (standby) که در صورت خرابی سرور اصلی، بدون وقفه بارکاری را ادامه دهند. این امکان از طریق load balancer، دیتابیس یا سرویس‌های کاربردی قابل اجراست

۴. 📈 Auto Scaling

تنظیم خودکار مقیاس منابع در مواجهه با افزایش یا کاهش بار. منابع مانند VM، کانتینر یا فانکشن سرورلس به کلود یا سیستم مدیریت اختصاصی اضافه و حذف می‌شوند

۵. 🚦 Rate Limiting

اعمال محدودیت در تعداد درخواست‌های دریافتی (مثلاً تعداد مشخص در هر ثانیه یا دقیقه) در لایه‌های مختلف مثل load balancer یا خود سرور. جلوگیری از overload سیستم و تضمین تجربه کاربری پایدار را ممکن می‌کند

---

🧭 چرا این روش‌ها مهم‌اند؟

* با ترکیب این استراتژی‌ها می‌تونی سیستم‌ت رو به‌گونه‌ای طراحی کنی که حتی در صورت خرابی یا حمله ناگهانی، ادامه به‌کار دهد.
* هر مورد از این استراتژی‌ها یک جنبه‌ی خاص از پایداری مثل توزیع بار، حفاظت داده‌ها یا کنترل درخواست را پوشش می‌دهد.
* این اصول نمایانگر مفاهیمی مثل حذف Single Point of Failure، failover خودکار، کشش دینامیک و کنترل ترافیک هستند.

---

🧩 سایر رویکردها که ممکنه مفید باشن:

* Redundancy + Fault Tolerance: استفاده از سرورهای active-active یا active-passive در داده‌سنترهای مختلف به‌همراه clustering و heartbeat برای مانیتورینگ خودکار .
* Distributed Storage & Replication: برای پایداری داده و تحمل خرابی در نودهای جغرافیایی متعدد
* Monitoring, Health Checks, Graceful Degradation: پیاده‌سازی مانیتورینگ لحظه‌ای، بررسی سلامت سرویس و ارائه fallback مناسب در شرایط بحرانی برای حفظ تجربه کاربری

---

جمع‌بندی سریع

این پنج استراتژی (Load Balancing، Data Redundancy، Failover، Auto Scaling، Rate Limiting) پایه‌ای‌ترین اصول برای طراحی سیستم‌های با High Availability هستند. با اجرای مناسب آن‌ها می‌تونی سطح دسترسی بالا، مقاومت در برابر خطا و تجربه‌ی بدون وقفه‌ای برای کاربران فراهم کنی.



https://t.me/addlist/QtXiQlynEJwzODBk
👍21
🏗 مراحل کامپایل در زبان Go

کامپایلر Go شامل مراحل زیر هست:

Source Code → Tokenizing → Parsing → AST → Type Checking → IR → SSA → Machine Code



1. Tokenizing (Lexical Analysis)

کد به اجزای کوچکتر مثل if, for, x, +, 123 تجزیه می‌شه.
این کار توسط lexer انجام می‌شه.

2. Parsing (Syntax Analysis)

از توکن‌ها یک درخت نحوی یا AST (Abstract Syntax Tree) ساخته می‌شه.
مثلاً a + b به شکل درختی با + به عنوان ریشه و a و b به عنوان فرزندها تحلیل می‌شه.

3. Type Checking

بررسی می‌کنه که همه چیز از نظر نوع (type) درسته یا نه:

آیا a + b مجازه؟ (آیا a و b عدد هستن؟)

آیا تابعی با امضای درست فراخوانی شده؟

4. Intermediate Representation (IR)

کد به فرم میانی ترجمه می‌شه که خواندن و بهینه‌سازی روش راحت‌تره.
Go از فرم SSA (Static Single Assignment) استفاده می‌کنه (در مرحله بعد توضیح داده می‌شه).

5. SSA (Static Single Assignment)

در این مدل، هر متغیر فقط یک‌بار مقداردهی می‌شه.
این به کامپایلر کمک می‌کنه که راحت‌تر بهینه‌سازی انجام بده، مثلاً:

حذف کدهای مرده

inline کردن توابع

بهینه‌سازی حلقه‌ها

6. Code Generation

در نهایت، از SSA کد ماشین تولید می‌شه (برای لینوکس/ویندوز/مک، معماری x86/ARM و…).
3👍2
Gopher Academy
🏗 مراحل کامپایل در زبان Go کامپایلر Go شامل مراحل زیر هست: Source Code → Tokenizing → Parsing → AST → Type Checking → IR → SSA → Machine Code 1. Tokenizing (Lexical Analysis) کد به اجزای کوچکتر مثل if, for, x, +, 123 تجزیه می‌شه. این کار توسط lexer انجام…
🌀 چرا Go سریع کامپایل می‌کنه؟

* کامپایلر Go فایل‌ها رو به صورت مستقل کامپایل می‌کنه (no header files مثل C/C++)
* importها فقط به شکل explicit مجاز هستن (هیچ چیزی مخفیانه load نمی‌شه)
* فرم SSA بسیار بهینه و کم‌حجم هست
* استفاده از حافظه‌ی کم در زمان build

---

🧪 مثال عملی (build داخلی Go)
اگر این کد رو ذخیره کنی:

package main

import "fmt"

func main() {
fmt.Println("Hello, Go!")
}


و بعد دستور زیر رو بزنی:

go build -x main.go


می‌بینی که این مراحل اتفاق می‌افته:

WORK=/tmp/go-build123456
mkdir -p $WORK/b001/
compile -> main.a
link -> main binary


---

🧰 ابزار مفید: go tool compile و go tool objdump

اگه بخوای دقیق‌تر رفتار کامپایلر رو ببینی:

1. فقط کامپایل کن بدون لینک:

go tool compile -S main.go


این دستور خروجی اسمبلی (Assembly) کد رو نشون می‌ده.

2. آنالیز باینری نهایی:

go tool objdump ./main


https://t.me/addlist/QtXiQlynEJwzODBk
👍2🔥1🍾1
در طراحی کامپایلرها، Static Single Assignment (SSA) یک فرم نمایش میانی (Intermediate Representation یا IR) است که در آن هر متغیر تنها یک‌بار تعریف می‌شود. این روش برای بهینه‌سازی کد و ساده‌سازی تحلیل‌هایی مثل زنجیره‌های استفاده-تعریف (use-define chains) استفاده می‌شود. کامپایلر گولنگ (مانند gc یا ابزارهای مرتبط با LLVM) ممکن است در مراحل بهینه‌سازی داخلی خود از مفاهیم مشابه SSA استفاده کند،

مثال ساده:
فرض کنید کدی مثل این دارید
func main() {
x := 1
x = x + 2
fmt.Println(x)
}

در فرم SSA، متغیر x به نسخه‌های مختلفی (مثل x1 و x2) تقسیم می‌شود تا هر تخصیص یکتا باشد:

x1 := 1
x2 := x1 + 2
fmt.Println(x2)


این نمایش به ابزارهای تحلیل کمک می‌کنه تا بتونن دقیق‌تر بررسی کنن که مقادیر متغیرها از کجا میان و کجا استفاده می‌شن.

🔴 این کار باعث می‌شه ردیابی جریان داده‌ها (مثل اینکه یک متغیر کجا تعریف و کجا استفاده شده) ساده‌تر بشه. این روش به‌خصوص برای ابزارهایی مثل بررسی باگ‌ها، بهینه‌سازی کد، یا تحلیل وابستگی‌ها خیلی مفیده.
2👍2
🎯 تفاوت بین Heap و Stack به زبان ساده:

Stack:
- چیست؟
حافظه‌ای با دسترسی سریع و مدیریت خودکار که برای ذخیره متغیرهای محلی و موقت (مثل متغیرهای داخل تابع) استفاده می‌شه.
- ویژگی‌ها:
- تخصیص و آزادسازی حافظه به صورت LIFO (Last In, First Out) انجام می‌شه.
- اندازه‌اش معمولاً محدود و ثابت است.
- سریع‌تره چون مدیریتش ساده‌ست.
- متغیرهای محلی (مثل int x = 5) و ارجاعات تابع در Stack ذخیره می‌شن.

Heap:
- چیست؟
حافظه‌ای پویا برای ذخیره داده‌هایی که عمر طولانی‌تری دارن یا اندازه‌شون در زمان اجرا مشخص می‌شه (مثل اشیاء یا آرایه‌های پویا).
- ویژگی‌ها:
- تخصیص و آزادسازی حافظه به صورت دستی یا توسط Garbage Collector (در گولنگ به صورت خودکار).
- کندتر از Stack چون مدیریتش پیچیده‌ست.
- برای داده‌های بزرگ یا اشتراک‌گذاری بین توابع استفاده می‌شه.

تفاوت کلیدی:
- سرعت: Stack سریع‌تره چون مدیریتش ساده‌ست.
- مدیریت: Stack خودکار مدیریت می‌شه، اما Heap نیاز به Garbage Collector داره (در گولنگ).
- عمر داده: Stack برای داده‌های موقت (محدوده تابع)، Heap برای داده‌های با عمر طولانی‌تر.
- اندازه: Stack محدودتره، Heap بزرگ‌تر و پویاست.

در گولنگ:
گولنگ با Escape Analysis تصمیم می‌گیره که یک متغیر در Stack یا Heap ذخیره بشه. مثلاً اگر متغیر از تابع خارج بشه (مثل برگرداندن اشاره‌گر)، به Heap می‌ره.
1👍1💯1🦄1
Forwarded from Gopher Job
😂😂👍🏻💯💯
👌1111👍1
🛠 ابزارها در حوزه Linters و تحلیل کد Go

1. Actionlint

* وظیفه: بررسی استاتیک فایل‌های workflow در GitHub Actions (.yml/.yaml در مسیر .github/workflows/)
* ویژگی‌ها:

* بررسی نحوی و semantic expressions (${{ }})
* اعتبارسنجی فراخوانی Actionها، ورودی/خروجی، نوع runners و امنیت اسکریپت‌ها
* استفاده از ShellCheck و Pyflakes برای lint کردن inline scripts
* CLI + کتابخانه Go برای استفاده در ابزارهای CI/CD ([megalinter.io][1])

---

2. Hadolint

* وظیفه: lint کردن Dockerfile
* ویژگی‌ها:

* نوشته شده با Haskell**؛ استفاده از AST برای تحلیل دستورات Docker
* ادغام با **ShellCheck
برای بررسی اسکریپت‌های bash داخل RUN
* امکان ignore قوانین، سفارشی‌سازی severity، trusted registries و خروجی‌های متنوع (json, sarif, checkstyle)
* قابلیت اجرا به صورت binary، container تصویر Docker و ادغام در CI یا IDE ([megalinter.io][2])

---

3. deadcode

* وظیفه: شناسایی کدهای بلا‌استفاده (dead code) در برنامه‌های Go
* ویژگی‌ها:

* استفاده از تحلیل Rapid Type Analysis (RTA) برای ساخت call graph از تابع‌های reachable از main
* شناسایی توابع و متدهایی که در جریان اجرا هرگز فراخوانی نمی‌شوند، حتی در ورودی‌های تست
* گزینه‌های -test, -filter, -generated برای کنترل نوع تحلیل و محدودسازی نتایج
* نصب از طریق go install ...@latest ([Google Groups][3], [Go][4], [Go Packages][5])

---

4. fieldalignment

* وظیفه: آنالیز alignment فیلدهای struct
* ویژگی‌ها:

* بررسی شکل ساختار struct برای بهبود چینش فیلدها و کاهش حافظه مصرف‌شده
* موجود در پکیج go/analysis و قابل اجرا به‌صورت standalone یا در قالب Pass در تحلیل‌های سفارشی
* نصب با go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest

---

5. Protolint

* وظیفه: lint (و در برخی موارد fix) فایل‌های .proto مطابق با استاندارد Google Protobuf
* ویژگی‌ها:

* اجرا بدون نیاز به compiler اصلی (protoc) و سبک اجرا
* تولید گزارش برای قوانین style مانند نام‌گذاری، indentation، order imports، documentation، comment برای RPC و پیام‌ها
* توانایی غیرفعال‌سازی قوانین در سطح فایل، استفاده از پلاگین برای قوانین سفارشی، و خروجی‌های متنوع (json, junit, sarif)


کدومش برای پروژه شما کاربردیه؟

* CI پروژه با workflows عالیه → Actionlint
* ساختن Docker image استاندارد/امن → Hadolint
* حذف کدهای غیرضروری پس refactor → deadcode
* بهینه‌سازی حافظه باینری در structها → fieldalignment
* بررسی فایل‌های protobuf و استانداردسازی API → Protolint
3👍1
Forwarded from Gopher Academy
🏆31👨‍💻1
🔐 مفهوم Mutex در Go

اsync.Mutex یک اصل اساسی برای کنترل دسترسی امن به منابع مشترک بین goroutineها است. این نوع قفل تضمین می‌کند که در هر لحظه تنها یک goroutine به بخش حیاتی از کد (critical section) دسترسی دارد

---

🧠 وضعیت‌های مختلف Mutex

می‌توان عملکرد آن را با وضعیت‌های زیر توضیح داد:
ا
ا* Unlocked (حالت اولیه): Mutex آزاد است و هر goroutine می‌تواند با فراخوانی Lock() آن را بگیرد.
ا* Locked: وقتی یک goroutine Lock() می‌زند، دیگران باید منتظر بمانند.
ا* Waiting: در صورت تلاش هم‌زمان چند goroutine برای گرفتن قفل، بقیه به صف انتظار اضافه می‌شوند.
ا* Starvation Mode: اگر یک goroutine بیش از \~۱ms نتواند قفل را بگیرد، سیستم وارد حالت گرسنگی (fair mode) شده و به ترتیب به goroutineهای قدیمی‌تر اجازه دسترسی می‌دهد ([CSDN Blog][3], [Zhihu Zhiwan][4]).

---

⚙️ عملکرد درونی Mutex

* از عملیات غیرقابل قطع (CAS) برای کنترل فیلد state استفاده می‌شود.
* در شرایط کم‌رقابت ابتدا به‌صورت spinning تلاش می‌کند تا حد ممکن بدون خوابیدن lock را بگیرد.
* در سطوح بالای رقابت، goroutineها به صف انتظار اضافه می‌شوند و بیدار می‌شوند وقتی قفل آزاد شد.
* حالت starvation زمانی فعال می‌شود که یک goroutine مدت طولانی در انتظار است تا از حالت FIFO استفاده شود

---

نکات کاربردی و بهترین شیوه‌ها

1. هیچ گاه Mutex را کپی نکنید؛ حتی تصادفاً**—مستقیماً باید از pointers استفاده شود
2. هیچ‌گاه موضعی در struct آن را جاسازی (embed) نکنید، چون باعث در دسترس‌پذیری ناخواسته متدهای Lock/Unlock می‌شود
3. از
defer m.Unlock() برای اطمینان از آزادسازی قفل حتی در صورت panic یا return زودهنگام استفاده کنید
4. بخش قفل‌شده باید حداقل زمان ممکن طول بکشد؛ انجام عملیات بلندمدت در آن ممکن است باعث کاهش concurrency و تأخیر جدی شود.

---

⚠️ مشکلات رایج و اشتباهات متداول

* **کپی ناخواسته Mutex: حذف ایمنی synchronization و موجب رفتار نامشخص.
ا* embedding Mutex: باعث انتشار متدهای داخلی قفل به بیرون struct می‌شود — روش اشتباهی است
ا* Double Unlock یا Unlock بدون Lock قبلی → panic.
* عدم رعایت defer → ممکن است در صورت خطا یا exit، قفل آزاد نشود و deadlock رخ دهد.
ا* Deadlock ناشی از تداخل دو یا چند goroutine با mutexهای متفاوت و انتظار متقابل بر مبنای نظم اشتباهی بین Lock()ها.
6👍1
مقاله‌ی «Top 6 Golang Logging Best Practices» در HackerNoon توسط Lane Wagner در سال ۲۰۲۲ منتشر شده و به بررسی نکاتی اساسی ولی کاربردی درباره‌ی لاگ‌نویسی در زبان Go پرداخته است. در ادامه، خلاصه‌ای مختصر

---

## نکات کلیدی مقاله

1. استفاده از `error` بجای رشته‌ها (strings)
از نوع استاندارد error برای نشان دادن خطاها استفاده کن تا از رفتارهای نادرست مانند نادیده‌گرفتن خطا یا پراکندگی سازوکار خطا جلوگیری شود.

2. Wrap کردن خطاها
بجای لاگ فقط پیام خطا، آن را wrap کن تا محل دقیق رخداد خطا (stack trace یا خط کد) حفظ شود و دیباگ آسان‌تر شود.

3. استفاده از `fmt.Errorf()` برای قالب‌بندی
fmt.Errorf() با قابلیت %w به تو اجازه می‌دهد خطاها را قالب‌بندی و wrap کنی:

   return fmt.Errorf("failed to open file: %w", err)


4. قالب‌دهی structها (Format Structs)
وقتی structها در لاگ‌ها استفاده می‌شن، آن‌ها را قالب‌مند کن تا خواناتر و مفیدتر باشند؛ مثلاً با فرمت:

   fmt.Printf("%+v", myStruct)


5. استفاده از نسخه variadic توابع مانند `fmt.Println()`
ورژن variadic بهت اجازه می‌دهد مولفه‌های مختلف را بدون تلاش برای concatenation دستی به هم بچسبونی. خوانا و منعطف‌تره.

6. استفاده از بسته‌ی استاندارد `log`
برای شروع خوبه، خصوصاً برای پروژه‌های ساده یا کوچک. log پایدار و سبک هست و کافی برای کاربردهای ابتدایی است.

---

جمع‌بندی سریع

اینها اصولی هستند که در بسیاری از آموزش‌ها و بحث‌های Go توصیه می‌شن: استفاده از سیستم خطای داخلی، پیروی از استانداردها در wrap خطا، قالب‌دهی مناسب، و استفاده از امکانات داخلی زبان قبل از رفتن به راه‌حل‌های پیچیده‌تر.

---

توصیه‌های عملی

* لاگ‌نویسی رو با استفاده از خطاهای داخلی Go شروع کن.
* ورودی‌ها رو wrap کن؛ structها رو مرتب قالب بده.
* برای لاگ‌های پیشرفته‌تر، از structured logging استفاده کن (مثل Zap یا Zerolog).
* همیشه context مهم رو مثل request ID در لاگ‌ها نگه‌دار.
* حجم لاگ رو کنترل کن: نه خیلی زیاد باشه که کارایی رو پایین بیاره، نه خیلی کم که مفید نباشه.
🤝4👍1