Gopher Academy
3.85K subscribers
933 photos
42 videos
280 files
2.2K links
🕸 Gopher Academy

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

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

ادمین:
@mrbardia72
Download Telegram
🔵 عنوان مقاله
Revisiting Interface Segregation in Go

🟢 خلاصه مقاله:
این مطلب «Interface Segregation Principle (ISP)» را از منظر Go مرور می‌کند: مشتری نباید به متدهایی وابسته شود که از آن‌ها استفاده نمی‌کند. در Go، راهکارهای رایج شامل ساختن رابط‌های کوچک و رفتاری، تعریف رابط‌ها در محل استفاده، «پذیرفتن interface و برگرداندن نوع‌های concrete»، و الهام گرفتن از نمونه‌های استاندارد مثل io.Reader و io.Writer است.

مشکل وقتی پیش می‌آید که یک پکیج، رابط‌های چاق و همه‌چیزدار صادر می‌کند؛ این کار تغییرات را سخت و پیاده‌سازی‌ها را پر از متدهای بی‌مصرف می‌کند. بهتر است رابط‌های کوچک را ترکیب یا embed کنیم، فقط وقتی واقعاً لازم است سراغ رابط‌های بزرگ برویم، و از میان‌افزارها/adapterها برای سازگاری در مسیر ریفکتور کمک بگیریم.

راهبرد عملی: ابتدا پیاده‌سازی‌های concrete بسازید، بعد بر اساس نیاز واقعی رابط استخراج کنید؛ مجموعه‌متدها را کوچک نگه دارید، برای تست از فیک/ماک بهره ببرید، و APIها را تدریجی تکامل دهید. با وجود generics هم باید از تعمیم بی‌جا پرهیز کرد و رابط‌های runtime را بر رفتار متمرکز نگه داشت. نتیجه پایبندی به ISP در Go، کدی ساده‌تر برای تست، نگهداشت و توسعه است؛ نکاتی که در تازه‌ترین مطلب معرفی‌شده توسط Golang Weekly نیز برجسته شده‌اند.

#Go #Golang #InterfaceSegregation #ISP #GoInterfaces #SoftwareDesign #Refactoring #GolangWeekly

🟣لینک مقاله:
https://golangweekly.com/link/176622/web


👑 @gopher_academy
👍2
💋چی کار می‌کنه sync.Once

تضمین می‌کنه یک تابع دقیقاً یک‌بار اجرا بشه حتی اگر چندین goroutine هم‌زمان تلاش کنن اون رو اجرا کنن. متد اصلیش Do(f func()) هست: اولین فراخوانی Do تابع f را اجرا می‌کنه و فراخوانی‌های بعدی هیچ کاری نمی‌کنن (بلوک نمی‌شن؛ فقط بازمی‌گردن).

💋موارد متداول استفاده

* پیاده‌سازی Singleton (یک‌بار ساختن نمونهٔ مشترک).
* بارگذاری تنبل (lazy load) کانفیگ یا منابع سنگین فقط وقتی لازم شدن.
* عمل‌هایی که باید فقط یک‌بار انجام بشن (مثلاً ثبت یک handler، close ای که نباید دوباره انجام بشه، و غیره).

مثال ساده (Singleton)

var instance *MyType
var once sync.Once

func GetInstance() *MyType {
once.Do(func() {
instance = &MyType{ /* init */ }
})
return instance
}


مثال: امن کردن close یک channel`

var once sync.Once
var ch = make(chan struct{})

func safeClose() {
once.Do(func() { close(ch) })
}


💋 نکات و خطرات (خیلی مهم)

1. اگر تابعِ داخل `Do` پانیک کند: در نسخهٔ فعلیِ استاندارد، Do آن فراخوانی را «تمام‌شده» در نظر می‌گیرد — یعنی بعد از پانیک، فراخوانی‌های بعدی Do دیگر f را اجرا نخواهند کرد. (در عمل پانیک به caller برمی‌گردد ولی Once وضعیتِ «انجام‌شده» را علامت می‌زند). پس اگر f ممکن است پانیک کند یا نیاز به retry دارید، sync.Once ممکن است مناسبِ کامل نباشد.

> (نکته: در Go 1.21 به‌علاوه توابعی مثل OnceFunc / OnceValue اضافه شدند که رفتار پانیک/بازگردانی را متفاوت ارائه می‌دهند؛ خوب است اگر از این ورژن‌ها استفاده می‌کنید نگاهی به مستندات بیندازید).

2.ا `Once` را بعد از استفاده کپی نکنید — کپی کردن یک Once بعد از اولین استفاده خطا/رفتار غیرمنتظره ایجاد می‌کند.
3. تابعِ داخل `Do` نباید خودش `Do` را صدا بزند (یا باعث قفل/deadlock شود). اگر f در همان Once دوباره Do را فراخوانی کند، قفل/deadlock یا رفتار نامناسب ممکن است رخ دهد. (به‌صورت کلی از بلوک‌های طولانی یا عملیات که ممکن است بلوکه شوند داخل f خودداری کنید).

4. ا`Do` مقدار/خطا برنمی‌گرداند — اگر تابع شما ممکن است خطا داشته باشد و بخواهید آن را به callerها برگردانید، معمولاً از pattern زیر استفاده می‌کنند:

var once sync.Once
var cfg Config
var cfgErr error

func LoadConfig() error {
once.Do(func() {
cfg, cfgErr = loadFromDisk()
})
return cfgErr
}


اما دقت کنید: اگر loadFromDisk پانیک کند یا با خطاهای خاصی مواجه شود و شما نیاز به retry داشته باشید، این الگو کافی نیست چون Do بعد از اولین اجرا (حتی اگر پانیک شد) اجازهٔ تکرار نمی‌دهد.

💋 پیشنهاد وقتی می‌خواهید retry یا مقدار/خطای دقیق داشته باشید

اگر نیاز دارید تابع مقدار برگردونه و رفتارِ retry داشته باشید، باید از الگوهای دیگری استفاده کنید (مثلاً mutex + state machine، یا کانال‌ها، یا بسته‌های ثالث که این الگو رو پیاده‌سازی می‌کنن). در Go 1.21 توابعی مثل OnceValue هم اضافه شدند که کمک می‌کنند مقدار بازگردونده و رفتار پانیک مشخص‌تر بشه
21
Gopher Academy
💋چی کار می‌کنه sync.Once تضمین می‌کنه یک تابع دقیقاً یک‌بار اجرا بشه حتی اگر چندین goroutine هم‌زمان تلاش کنن اون رو اجرا کنن. متد اصلیش Do(f func()) هست: اولین فراخوانی Do تابع f را اجرا می‌کنه و فراخوانی‌های بعدی هیچ کاری نمی‌کنن (بلوک نمی‌شن؛ فقط بازمی‌گردن).…
بیایید هر دو حالت را ببینیم:
۱️⃣ نمونهٔ Retry‌دار (برای مواقعی که تابع ممکن است خطا بدهد)
۲️⃣ نمونهٔ واقعی‌تر (مثلاً بارگذاری فایل کانفیگ فقط یک‌بار)

---
🧩 مثال ۱: sync.Once با قابلیت Retry

sync.Once به‌صورت پیش‌فرض فقط یک‌بار اجرا می‌شود — حتی اگر اون اجرا شکست بخوره.
اما گاهی می‌خواهیم تابع فقط *در صورت موفقیت* «once» باشد، وگرنه دفعهٔ بعدی دوباره تلاش کند.
برای این کار، باید رفتار خودمان را روی Once شبیه‌سازی کنیم:

package main

import (
"errors"
"fmt"
"sync"
)

type OnceRetry struct {
mu sync.Mutex
done bool
}

func (o *OnceRetry) Do(f func() error) error {
o.mu.Lock()
defer o.mu.Unlock()

if o.done {
return nil
}

err := f()
if err != nil {
return err
}

o.done = true
return nil
}

func main() {
var once OnceRetry
counter := 0

task := func() error {
counter++
if counter < 3 {
fmt.Println(" Failed attempt", counter)
return errors.New("temporary error")
}
fmt.Println(" Success on attempt", counter)
return nil
}

for i := 0; i < 5; i++ {
err := once.Do(task)
if err != nil {
fmt.Println("Error:", err)
}
}

fmt.Println("Final counter =", counter)
}


🟢 نتیجه خروجی:

 Failed attempt 1
Error: temporary error
Failed attempt 2
Error: temporary error
Success on attempt 3
Final counter = 3


یعنی تابع تا زمانی که موفق نشده، باز هم قابل اجراست — اما بعد از موفقیت فقط یک‌بار انجام می‌شود

🧱 مثال ۲: بارگذاری فایل کانفیگ فقط یک‌بار (Real-world)

package main

import (
"encoding/json"
"fmt"
"os"
"sync"
)

type Config struct {
Port int `json:"port"`
Mode string `json:"mode"`
}

var (
cfg Config
cfgErr error
cfgOnce sync.Once
)

func LoadConfig() (Config, error) {
cfgOnce.Do(func() {
fmt.Println("📁 Reading config.json only once...")
data, err := os.ReadFile("config.json")
if err != nil {
cfgErr = err
return
}
cfgErr = json.Unmarshal(data, &cfg)
})
return cfg, cfgErr
}

func main() {
for i := 0; i < 3; i++ {
c, err := LoadConfig()
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Loaded config:", c)
}
}
}


🔹 حتی اگر LoadConfig() چندبار فراخوانی شود، فایل فقط یک‌بار خوانده می‌شود.
🔹 در برنامه‌های بزرگ (microserviceها، سرورها، یا SDKها) این pattern خیلی رایج است.
2🔥1
🔵 عنوان مقاله
Chans: Building Blocks for Idiomatic Go Pipelines

🟢 خلاصه مقاله:
** آنتون در مقاله «Chans: Building Blocks for Idiomatic Go Pipelines» بسته‌ی chans را معرفی می‌کند؛ مجموعه‌ای از عملگرهای عمومی و نوع‌امن روی channelها در زبان Go—مثل filter، map، partition و takeWhile—برای ساختpipelineهای همزمان به‌شکل idiomatic. این بسته با کاهش کد تکراری و افزایش ترکیب‌پذیری، نوشتن جریان‌های پردازش داده را ساده‌تر، خواناتر و قابل نگه‌داری‌تر می‌کند و برای پردازش جریان‌ها، رویدادها و کارهای IO-محور بسیار کاربردی است.

#Go #Concurrency #Channels #Pipelines #Generics #FunctionalProgramming #SoftwareEngineering

🟣لینک مقاله:
https://golangweekly.com/link/176627/web


👑 @gopher_academy
👍3
Gopher Academy
🔵 عنوان مقاله Chans: Building Blocks for Idiomatic Go Pipelines 🟢 خلاصه مقاله: ** آنتون در مقاله «Chans: Building Blocks for Idiomatic Go Pipelines» بسته‌ی chans را معرفی می‌کند؛ مجموعه‌ای از عملگرهای عمومی و نوع‌امن روی channelها در زبان Go—مثل filter،…
Here's a toy example:
// Given a channel of documents.
docs := make(chan []string, 10)
docs <- []string{"go", "is", "awesome"}
docs <- []string{"cats", "are", "cute"}
close(docs)

// Extract all words from the documents.
words := make(chan string, 10)
chans.Flatten(ctx, words, docs)
close(words)

// Calculate the total byte count of all words.
step := func(acc int, word string) int { return acc + len(word) }
count := chans.Reduce(ctx, words, 0, step)
fmt.Println("byte count =", count)

byte count = 22
👍2
Gopher Academy
📌 Memory Allocation in Go این پست اپدیت می‌شود 🔹 در این پست به بررسی جزئیات مدیریت حافظه در زبان Go می‌پردازیم. درک درست از ساختار حافظه به شما کمک می‌کند عملکرد برنامه‌هایتان را بهتر بهینه کنید و رفتار Garbage Collector را بهتر بفهمید. 🔵 Introduction…
این تصویر نمونه‌ای از مفهوم Summary برای یک bitmap در حافظه‌ی Go رو نشون می‌ده

🧩 این Bitmap Summary در مدیریت صفحات Go

در این شکل، هر بیت از bitmap نشان‌دهنده‌ی وضعیت یک صفحه‌ی حافظه است:

* 0 → صفحه آزاد (free)
* 1 → صفحه در حال استفاده (allocated)

برای بهینه‌سازی جستجوی صفحات آزاد، Go برای هر bitmap سه مقدار خلاصه‌شده (summary) نگه می‌داره:

* start = 3 → یعنی در ابتدای bitmap، ۳ صفحه‌ی متوالی آزاد داریم
* end = 7 → یعنی در انتهای bitmap، ۷ صفحه‌ی متوالی آزاد داریم
* max = 10 → طولانی‌ترین دنباله‌ی صفحات آزاد در کل bitmap برابر با ۱۰ صفحه است

🔹 فلش در تصویر جهت افزایش آدرس حافظه (از پایین به بالا) رو نشون می‌ده.
در نتیجه، ۳ صفحه‌ی آزاد در بخش پایین‌تر حافظه (low address) و ۷ صفحه‌ی آزاد در بالاترین بخش (high address) قرار دارن.

این ساختار باعث می‌شه Go خیلی سریع‌تر بتونه محدوده‌های بزرگ از صفحات آزاد رو پیدا کنه بدون این‌که کل bitmap رو اسکن کنه — فقط با نگاه کردن به summaryها!

👑 @gopher_academy
👍1🔥1
🔵 عنوان مقاله
progjpeg: image/jpeg But With Progressive Encoding Support

🟢 خلاصه مقاله:
progjpeg نسخه‌ای از بسته image/jpeg در زبان Go است که امکان Progressive Encoding را به آن اضافه می‌کند؛ قابلیتی که تصویر را ابتدا به‌صورت کم‌جزئیات نشان می‌دهد و در چند گذر با دریافت داده‌های بیشتر شفاف‌تر می‌شود. این ویژگی می‌تواند در شبکه‌های کند تجربه کاربری را بهبود دهد و توسط بیشتر مرورگرها و دیکدرهای تصویر پشتیبانی می‌شود. چون درخواست افزودن این قابلیت در مخزن رسمی Go «متوقف/فریز» شده بود، progjpeg این خلأ را برای توسعه‌دهندگان پر می‌کند. هرچند کاربرد آن تخصصی است، اما برای سرویس‌های وب و سامانه‌های سنگینِ تصویر می‌تواند تجربه بارگذاری روان‌تری فراهم کند، با درنظرگرفتن ملاحظاتی مثل پیچیدگی کدنویسی و تفاوت احتمالی در اندازه فایل.

#Go #Golang #JPEG #ProgressiveJPEG #ImageProcessing #WebPerformance #OpenSource

🟣لینک مقاله:
https://golangweekly.com/link/176639/web


👑 @gopher_academy
Clients should not be forced to depend on methods they do not use.


— Robert C. Martin (SOLID, interface segregation principle)
👍2
🔵 عنوان مقاله
docxgo: A Library for Manipulating Microsoft Word Documents

🟢 خلاصه مقاله:
docxgo یک کتابخانه برای کار برنامه‌نویسی با اسناد Microsoft Word با فرمت .docx است که امکان ساخت، خواندن و ویرایش خودکار اسناد را فراهم می‌کند. نمونه‌کدهای همراه، مراحل پایه مانند بازکردن سند، پیمایش ساختار، افزودن یا ویرایش پاراگراف‌ها و سبک‌ها و ذخیره‌سازی خروجی را نشان می‌دهند. این پروژه تکامل‌یافته‌ی کتابخانه Docx است و با بهبود سازگاری با Microsoft Word، گسترش پوشش قابلیت‌ها (مانند جداول، تصاویر، سرصفحه/پاصفحه و بخش‌بندی) و بهبود کارایی و مدیریت خطا، تجربه توسعه یکپارچه‌تری ارائه می‌دهد. از تولید گزارش‌ها و قراردادهای مبتنی بر قالب تا ادغام در سرویس‌های پشتیبان و ابزارهای خط فرمان، docxgo برای خودکارسازی فرآیندهای اسنادی و استانداردسازی قالب‌بندی گزینه‌ای مناسب است.

#docxgo #MicrosoftWord #DOCX #DocumentAutomation #DeveloperTools #WordProcessing #APIs

🟣لینک مقاله:
https://golangweekly.com/link/176636/web


👑 @gopher_academy
👍1
🔵 عنوان مقاله
"I'm Independently Verifying Go's Reproducible Builds"

🟢 خلاصه مقاله:
** از نسخه Go 1.21، ابزارهای اصلی Go به‌صورت Reproducible Builds عرضه می‌شوند؛ یعنی اگر همان سورس را دوباره بسازید، برای هر هدف مشخص، خروجی دقیقا همسانِ بایت‌به‌بایت تولید می‌شود و به محیط میزبان وابسته نیست. این مقاله گزارشی از یک راستی‌آزمایی مستقل است: دریافت سورس از ریلیزهای رسمی، ساخت در محیط‌های ایزوله روی میزبان‌های متفاوت، تولید ابزارها برای تارگت‌های یکسان و مقایسه هش‌ها با یکدیگر و با چک‌سام‌های رسمی. نتیجه نشان می‌دهد که از Go 1.21 به بعد، Go toolchain طبق وعده قابل بازتولید است. این کار، در کنار انتشار رسمی، اعتماد را افزایش می‌دهد، ریسک دست‌کاری در زنجیره تامین نرم‌افزار را کاهش می‌دهد و به کاربران امکان می‌دهد خروجی‌های منتشرشده را خودشان مستقلانه راستی‌آزمایی کنند.

#ReproducibleBuilds #Go #Golang #SupplyChainSecurity #DeterministicBuilds #OpenSource #DevSecOps

🟣لینک مقاله:
https://golangweekly.com/link/176621/web


👑 @gopher_academy
1
Forwarded from DevOps Labdon
🔵 عنوان مقاله
Cost-optimized ml on production: autoscaling GPU nodes on Kubernetes to zero using keda

🟢 خلاصه مقاله:
این آموزش نشان می‌دهد چگونه با استفاده از Kubernetes و KEDA ظرفیت GPU را بر اساس طول صف پیام‌ها به‌صورت خودکار تا صفر کاهش دهیم و هزینه اجرای ML در محیط تولید را کم کنیم. معماری مبتنی بر یک message queue (مثل Kafka، RabbitMQ یا AWS SQS) است و KEDA با ScaledObject تعداد پادهای مصرف‌کننده GPU را نسبت به backlog تنظیم می‌کند (minReplicaCount=0). با فعال‌بودن Cluster Autoscaler و یک GPU node pool با حداقل اندازه صفر، نودهای GPU فقط هنگام نیاز ایجاد و سپس آزاد می‌شوند. نکات کلیدی شامل تنظیم nodeSelector/tolerations، درخواست nvidia.com/gpu، کنترل pollingInterval/cooldownPeriod، کاهش cold start با pre-pull و پایش با Prometheus/Grafana است. نتیجه: پرداخت هزینه GPU فقط هنگام وجود کار، همراه با حفظ قابلیت اطمینان و کنترل تأخیر.

#Kubernetes #KEDA #GPU #MLOps #Autoscaling #CostOptimization #MessageQueue #ProductionML

🟣لینک مقاله:
https://ku.bz/Zhb9q3BZx


👑 @DevOps_Labdon
2