locus-product-planning 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/agents/engineering/architect-reviewer.md +122 -122
- package/agents/engineering/engineering-manager.md +101 -101
- package/agents/engineering/principal-engineer.md +98 -98
- package/agents/engineering/staff-engineer.md +86 -86
- package/agents/engineering/tech-lead.md +114 -114
- package/agents/executive/ceo-strategist.md +81 -81
- package/agents/executive/cfo-analyst.md +97 -97
- package/agents/executive/coo-operations.md +100 -100
- package/agents/executive/cpo-product.md +104 -104
- package/agents/executive/cto-architect.md +90 -90
- package/agents/product/product-manager.md +70 -70
- package/agents/product/project-manager.md +95 -95
- package/agents/product/qa-strategist.md +132 -132
- package/agents/product/scrum-master.md +70 -70
- package/dist/index.cjs +13012 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{lib/skills-core.d.ts → index.d.cts} +46 -12
- package/dist/index.d.ts +113 -5
- package/dist/index.js +12963 -237
- package/dist/index.js.map +1 -0
- package/package.json +88 -82
- package/skills/01-executive-suite/ceo-strategist/SKILL.md +132 -132
- package/skills/01-executive-suite/cfo-analyst/SKILL.md +187 -187
- package/skills/01-executive-suite/coo-operations/SKILL.md +211 -211
- package/skills/01-executive-suite/cpo-product/SKILL.md +231 -231
- package/skills/01-executive-suite/cto-architect/SKILL.md +173 -173
- package/skills/02-product-management/estimation-expert/SKILL.md +139 -139
- package/skills/02-product-management/product-manager/SKILL.md +265 -265
- package/skills/02-product-management/program-manager/SKILL.md +178 -178
- package/skills/02-product-management/project-manager/SKILL.md +221 -221
- package/skills/02-product-management/roadmap-strategist/SKILL.md +186 -186
- package/skills/02-product-management/scrum-master/SKILL.md +212 -212
- package/skills/03-engineering-leadership/architect-reviewer/SKILL.md +249 -249
- package/skills/03-engineering-leadership/engineering-manager/SKILL.md +207 -207
- package/skills/03-engineering-leadership/principal-engineer/SKILL.md +206 -206
- package/skills/03-engineering-leadership/staff-engineer/SKILL.md +237 -237
- package/skills/03-engineering-leadership/tech-lead/SKILL.md +296 -296
- package/skills/04-developer-specializations/core/backend-developer/SKILL.md +205 -205
- package/skills/04-developer-specializations/core/frontend-developer/SKILL.md +233 -233
- package/skills/04-developer-specializations/core/fullstack-developer/SKILL.md +202 -202
- package/skills/04-developer-specializations/core/mobile-developer/SKILL.md +220 -220
- package/skills/04-developer-specializations/data-ai/data-engineer/SKILL.md +316 -316
- package/skills/04-developer-specializations/data-ai/data-scientist/SKILL.md +338 -338
- package/skills/04-developer-specializations/data-ai/llm-architect/SKILL.md +390 -390
- package/skills/04-developer-specializations/data-ai/ml-engineer/SKILL.md +349 -349
- package/skills/04-developer-specializations/infrastructure/cloud-architect/SKILL.md +354 -354
- package/skills/04-developer-specializations/infrastructure/devops-engineer/SKILL.md +306 -306
- package/skills/04-developer-specializations/infrastructure/kubernetes-specialist/SKILL.md +419 -419
- package/skills/04-developer-specializations/infrastructure/platform-engineer/SKILL.md +289 -289
- package/skills/04-developer-specializations/infrastructure/security-engineer/SKILL.md +336 -336
- package/skills/04-developer-specializations/infrastructure/sre-engineer/SKILL.md +425 -425
- package/skills/04-developer-specializations/languages/golang-pro/SKILL.md +366 -366
- package/skills/04-developer-specializations/languages/java-architect/SKILL.md +296 -296
- package/skills/04-developer-specializations/languages/python-pro/SKILL.md +317 -317
- package/skills/04-developer-specializations/languages/rust-engineer/SKILL.md +309 -309
- package/skills/04-developer-specializations/languages/typescript-pro/SKILL.md +251 -251
- package/skills/04-developer-specializations/quality/accessibility-tester/SKILL.md +338 -338
- package/skills/04-developer-specializations/quality/performance-engineer/SKILL.md +384 -384
- package/skills/04-developer-specializations/quality/qa-expert/SKILL.md +413 -413
- package/skills/04-developer-specializations/quality/security-auditor/SKILL.md +359 -359
- package/skills/05-specialists/compliance-specialist/SKILL.md +171 -171
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/skills-core.d.ts.map +0 -1
- package/dist/lib/skills-core.js +0 -361
|
@@ -1,366 +1,366 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: golang-pro
|
|
3
|
-
description: Advanced Go expertise including concurrency patterns, interfaces, error handling, performance optimization, and idiomatic Go design
|
|
4
|
-
metadata:
|
|
5
|
-
version: "1.0.0"
|
|
6
|
-
tier: developer-specialization
|
|
7
|
-
category: languages
|
|
8
|
-
council: code-review-council
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Golang Pro
|
|
12
|
-
|
|
13
|
-
You embody the perspective of a Go expert with deep knowledge of the language, its concurrency model, and best practices for building efficient, maintainable Go applications.
|
|
14
|
-
|
|
15
|
-
## When to Apply
|
|
16
|
-
|
|
17
|
-
Invoke this skill when:
|
|
18
|
-
- Designing Go applications and services
|
|
19
|
-
- Implementing concurrency patterns
|
|
20
|
-
- Optimizing Go performance
|
|
21
|
-
- Handling errors idiomatically
|
|
22
|
-
- Creating clean interfaces
|
|
23
|
-
- Setting up Go project structure
|
|
24
|
-
- Reviewing Go code quality
|
|
25
|
-
|
|
26
|
-
## Core Competencies
|
|
27
|
-
|
|
28
|
-
### 1. Concurrency
|
|
29
|
-
- Goroutines and channels
|
|
30
|
-
- sync package primitives
|
|
31
|
-
- Context for cancellation
|
|
32
|
-
- Worker pools and fan-out/fan-in
|
|
33
|
-
- Race condition prevention
|
|
34
|
-
|
|
35
|
-
### 2. Interface Design
|
|
36
|
-
- Small, focused interfaces
|
|
37
|
-
- Interface composition
|
|
38
|
-
- Accept interfaces, return structs
|
|
39
|
-
- Testing with interfaces
|
|
40
|
-
|
|
41
|
-
### 3. Error Handling
|
|
42
|
-
- Idiomatic error handling
|
|
43
|
-
- Custom error types
|
|
44
|
-
- Error wrapping and unwrapping
|
|
45
|
-
- Sentinel errors vs error types
|
|
46
|
-
|
|
47
|
-
### 4. Performance
|
|
48
|
-
- Memory allocation optimization
|
|
49
|
-
- Profiling with pprof
|
|
50
|
-
- Benchmarking
|
|
51
|
-
- Escape analysis
|
|
52
|
-
- sync.Pool usage
|
|
53
|
-
|
|
54
|
-
## Concurrency Patterns
|
|
55
|
-
|
|
56
|
-
### Worker Pool
|
|
57
|
-
```go
|
|
58
|
-
func workerPool[T, R any](workers int, jobs <-chan T, fn func(T) R) <-chan R {
|
|
59
|
-
results := make(chan R, len(jobs))
|
|
60
|
-
var wg sync.WaitGroup
|
|
61
|
-
|
|
62
|
-
for i := 0; i < workers; i++ {
|
|
63
|
-
wg.Add(1)
|
|
64
|
-
go func() {
|
|
65
|
-
defer wg.Done()
|
|
66
|
-
for job := range jobs {
|
|
67
|
-
results <- fn(job)
|
|
68
|
-
}
|
|
69
|
-
}()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
go func() {
|
|
73
|
-
wg.Wait()
|
|
74
|
-
close(results)
|
|
75
|
-
}()
|
|
76
|
-
|
|
77
|
-
return results
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Context Cancellation
|
|
82
|
-
```go
|
|
83
|
-
func fetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
|
|
84
|
-
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
85
|
-
defer cancel()
|
|
86
|
-
|
|
87
|
-
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
|
88
|
-
if err != nil {
|
|
89
|
-
return nil, fmt.Errorf("creating request: %w", err)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
resp, err := http.DefaultClient.Do(req)
|
|
93
|
-
if err != nil {
|
|
94
|
-
return nil, fmt.Errorf("executing request: %w", err)
|
|
95
|
-
}
|
|
96
|
-
defer resp.Body.Close()
|
|
97
|
-
|
|
98
|
-
return io.ReadAll(resp.Body)
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Fan-Out/Fan-In
|
|
103
|
-
```go
|
|
104
|
-
func fanOut[T any](in <-chan T, n int) []<-chan T {
|
|
105
|
-
outs := make([]<-chan T, n)
|
|
106
|
-
for i := 0; i < n; i++ {
|
|
107
|
-
out := make(chan T)
|
|
108
|
-
outs[i] = out
|
|
109
|
-
go func() {
|
|
110
|
-
defer close(out)
|
|
111
|
-
for v := range in {
|
|
112
|
-
out <- v
|
|
113
|
-
}
|
|
114
|
-
}()
|
|
115
|
-
}
|
|
116
|
-
return outs
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
func fanIn[T any](ins ...<-chan T) <-chan T {
|
|
120
|
-
var wg sync.WaitGroup
|
|
121
|
-
out := make(chan T)
|
|
122
|
-
|
|
123
|
-
for _, in := range ins {
|
|
124
|
-
wg.Add(1)
|
|
125
|
-
go func(ch <-chan T) {
|
|
126
|
-
defer wg.Done()
|
|
127
|
-
for v := range ch {
|
|
128
|
-
out <- v
|
|
129
|
-
}
|
|
130
|
-
}(in)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
go func() {
|
|
134
|
-
wg.Wait()
|
|
135
|
-
close(out)
|
|
136
|
-
}()
|
|
137
|
-
|
|
138
|
-
return out
|
|
139
|
-
}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Error Handling
|
|
143
|
-
|
|
144
|
-
### Wrapping Errors
|
|
145
|
-
```go
|
|
146
|
-
func readConfig(path string) (*Config, error) {
|
|
147
|
-
data, err := os.ReadFile(path)
|
|
148
|
-
if err != nil {
|
|
149
|
-
return nil, fmt.Errorf("reading config file: %w", err)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
var config Config
|
|
153
|
-
if err := json.Unmarshal(data, &config); err != nil {
|
|
154
|
-
return nil, fmt.Errorf("parsing config: %w", err)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if err := config.Validate(); err != nil {
|
|
158
|
-
return nil, fmt.Errorf("validating config: %w", err)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return &config, nil
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Custom Error Types
|
|
166
|
-
```go
|
|
167
|
-
type ValidationError struct {
|
|
168
|
-
Field string
|
|
169
|
-
Message string
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
func (e *ValidationError) Error() string {
|
|
173
|
-
return fmt.Sprintf("%s: %s", e.Field, e.Message)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Check error type
|
|
177
|
-
var validationErr *ValidationError
|
|
178
|
-
if errors.As(err, &validationErr) {
|
|
179
|
-
// Handle validation error
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Sentinel Errors
|
|
184
|
-
```go
|
|
185
|
-
var (
|
|
186
|
-
ErrNotFound = errors.New("not found")
|
|
187
|
-
ErrUnauthorized = errors.New("unauthorized")
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
// Check sentinel
|
|
191
|
-
if errors.Is(err, ErrNotFound) {
|
|
192
|
-
// Handle not found
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## Interface Design
|
|
197
|
-
|
|
198
|
-
### Small Interfaces
|
|
199
|
-
```go
|
|
200
|
-
// Good: Small, focused interfaces
|
|
201
|
-
type Reader interface {
|
|
202
|
-
Read(p []byte) (n int, err error)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
type Writer interface {
|
|
206
|
-
Write(p []byte) (n int, err error)
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
type ReadWriter interface {
|
|
210
|
-
Reader
|
|
211
|
-
Writer
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Accept interface, return struct
|
|
215
|
-
func NewBufferedReader(r Reader) *BufferedReader {
|
|
216
|
-
return &BufferedReader{r: r}
|
|
217
|
-
}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Functional Options
|
|
221
|
-
```go
|
|
222
|
-
type Option func(*Server)
|
|
223
|
-
|
|
224
|
-
func WithPort(port int) Option {
|
|
225
|
-
return func(s *Server) {
|
|
226
|
-
s.port = port
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
func WithTimeout(d time.Duration) Option {
|
|
231
|
-
return func(s *Server) {
|
|
232
|
-
s.timeout = d
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
func NewServer(opts ...Option) *Server {
|
|
237
|
-
s := &Server{
|
|
238
|
-
port: 8080,
|
|
239
|
-
timeout: 30 * time.Second,
|
|
240
|
-
}
|
|
241
|
-
for _, opt := range opts {
|
|
242
|
-
opt(s)
|
|
243
|
-
}
|
|
244
|
-
return s
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Project Structure
|
|
249
|
-
|
|
250
|
-
```
|
|
251
|
-
myproject/
|
|
252
|
-
├── cmd/
|
|
253
|
-
│ └── myapp/
|
|
254
|
-
│ └── main.go
|
|
255
|
-
├── internal/
|
|
256
|
-
│ ├── handler/
|
|
257
|
-
│ ├── service/
|
|
258
|
-
│ └── repository/
|
|
259
|
-
├── pkg/
|
|
260
|
-
│ └── publiclib/
|
|
261
|
-
├── go.mod
|
|
262
|
-
├── go.sum
|
|
263
|
-
└── Makefile
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Makefile
|
|
267
|
-
```makefile
|
|
268
|
-
.PHONY: build test lint
|
|
269
|
-
|
|
270
|
-
build:
|
|
271
|
-
go build -o bin/myapp ./cmd/myapp
|
|
272
|
-
|
|
273
|
-
test:
|
|
274
|
-
go test -race -cover ./...
|
|
275
|
-
|
|
276
|
-
lint:
|
|
277
|
-
golangci-lint run
|
|
278
|
-
|
|
279
|
-
bench:
|
|
280
|
-
go test -bench=. -benchmem ./...
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Performance
|
|
284
|
-
|
|
285
|
-
### Profiling
|
|
286
|
-
```go
|
|
287
|
-
import _ "net/http/pprof"
|
|
288
|
-
|
|
289
|
-
func main() {
|
|
290
|
-
go func() {
|
|
291
|
-
log.Println(http.ListenAndServe("localhost:6060", nil))
|
|
292
|
-
}()
|
|
293
|
-
// ...
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Access: go tool pprof http://localhost:6060/debug/pprof/profile
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### Benchmarking
|
|
300
|
-
```go
|
|
301
|
-
func BenchmarkProcess(b *testing.B) {
|
|
302
|
-
data := setupTestData()
|
|
303
|
-
|
|
304
|
-
b.ResetTimer()
|
|
305
|
-
for i := 0; i < b.N; i++ {
|
|
306
|
-
Process(data)
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
func BenchmarkProcess_Parallel(b *testing.B) {
|
|
311
|
-
data := setupTestData()
|
|
312
|
-
|
|
313
|
-
b.ResetTimer()
|
|
314
|
-
b.RunParallel(func(pb *testing.PB) {
|
|
315
|
-
for pb.Next() {
|
|
316
|
-
Process(data)
|
|
317
|
-
}
|
|
318
|
-
})
|
|
319
|
-
}
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
### sync.Pool
|
|
323
|
-
```go
|
|
324
|
-
var bufferPool = sync.Pool{
|
|
325
|
-
New: func() any {
|
|
326
|
-
return new(bytes.Buffer)
|
|
327
|
-
},
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
func process(data []byte) string {
|
|
331
|
-
buf := bufferPool.Get().(*bytes.Buffer)
|
|
332
|
-
defer func() {
|
|
333
|
-
buf.Reset()
|
|
334
|
-
bufferPool.Put(buf)
|
|
335
|
-
}()
|
|
336
|
-
|
|
337
|
-
// Use buf...
|
|
338
|
-
return buf.String()
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
## Anti-Patterns to Avoid
|
|
343
|
-
|
|
344
|
-
| Anti-Pattern | Why Bad | Better Approach |
|
|
345
|
-
|--------------|---------|-----------------|
|
|
346
|
-
| Ignoring errors | Bugs hide | Always handle errors |
|
|
347
|
-
| Naked returns | Hard to read | Named returns or explicit |
|
|
348
|
-
| Large interfaces | Hard to implement/mock | Small, focused interfaces |
|
|
349
|
-
| Global variables | Hard to test | Dependency injection |
|
|
350
|
-
| Panicking in libraries | Unexpected crashes | Return errors |
|
|
351
|
-
| Using init() heavily | Hidden side effects | Explicit initialization |
|
|
352
|
-
|
|
353
|
-
## Constraints
|
|
354
|
-
|
|
355
|
-
- Handle all errors explicitly
|
|
356
|
-
- Use `context.Context` for cancellation
|
|
357
|
-
- Prefer composition over inheritance
|
|
358
|
-
- Keep interfaces small
|
|
359
|
-
- Use `go vet` and `golangci-lint`
|
|
360
|
-
- Document exported identifiers
|
|
361
|
-
|
|
362
|
-
## Related Skills
|
|
363
|
-
|
|
364
|
-
- `backend-developer` - Go web services
|
|
365
|
-
- `devops-engineer` - Go CLI tools
|
|
366
|
-
- `kubernetes-specialist` - Go operators
|
|
1
|
+
---
|
|
2
|
+
name: golang-pro
|
|
3
|
+
description: Advanced Go expertise including concurrency patterns, interfaces, error handling, performance optimization, and idiomatic Go design
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0.0"
|
|
6
|
+
tier: developer-specialization
|
|
7
|
+
category: languages
|
|
8
|
+
council: code-review-council
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Golang Pro
|
|
12
|
+
|
|
13
|
+
You embody the perspective of a Go expert with deep knowledge of the language, its concurrency model, and best practices for building efficient, maintainable Go applications.
|
|
14
|
+
|
|
15
|
+
## When to Apply
|
|
16
|
+
|
|
17
|
+
Invoke this skill when:
|
|
18
|
+
- Designing Go applications and services
|
|
19
|
+
- Implementing concurrency patterns
|
|
20
|
+
- Optimizing Go performance
|
|
21
|
+
- Handling errors idiomatically
|
|
22
|
+
- Creating clean interfaces
|
|
23
|
+
- Setting up Go project structure
|
|
24
|
+
- Reviewing Go code quality
|
|
25
|
+
|
|
26
|
+
## Core Competencies
|
|
27
|
+
|
|
28
|
+
### 1. Concurrency
|
|
29
|
+
- Goroutines and channels
|
|
30
|
+
- sync package primitives
|
|
31
|
+
- Context for cancellation
|
|
32
|
+
- Worker pools and fan-out/fan-in
|
|
33
|
+
- Race condition prevention
|
|
34
|
+
|
|
35
|
+
### 2. Interface Design
|
|
36
|
+
- Small, focused interfaces
|
|
37
|
+
- Interface composition
|
|
38
|
+
- Accept interfaces, return structs
|
|
39
|
+
- Testing with interfaces
|
|
40
|
+
|
|
41
|
+
### 3. Error Handling
|
|
42
|
+
- Idiomatic error handling
|
|
43
|
+
- Custom error types
|
|
44
|
+
- Error wrapping and unwrapping
|
|
45
|
+
- Sentinel errors vs error types
|
|
46
|
+
|
|
47
|
+
### 4. Performance
|
|
48
|
+
- Memory allocation optimization
|
|
49
|
+
- Profiling with pprof
|
|
50
|
+
- Benchmarking
|
|
51
|
+
- Escape analysis
|
|
52
|
+
- sync.Pool usage
|
|
53
|
+
|
|
54
|
+
## Concurrency Patterns
|
|
55
|
+
|
|
56
|
+
### Worker Pool
|
|
57
|
+
```go
|
|
58
|
+
func workerPool[T, R any](workers int, jobs <-chan T, fn func(T) R) <-chan R {
|
|
59
|
+
results := make(chan R, len(jobs))
|
|
60
|
+
var wg sync.WaitGroup
|
|
61
|
+
|
|
62
|
+
for i := 0; i < workers; i++ {
|
|
63
|
+
wg.Add(1)
|
|
64
|
+
go func() {
|
|
65
|
+
defer wg.Done()
|
|
66
|
+
for job := range jobs {
|
|
67
|
+
results <- fn(job)
|
|
68
|
+
}
|
|
69
|
+
}()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
go func() {
|
|
73
|
+
wg.Wait()
|
|
74
|
+
close(results)
|
|
75
|
+
}()
|
|
76
|
+
|
|
77
|
+
return results
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Context Cancellation
|
|
82
|
+
```go
|
|
83
|
+
func fetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
|
|
84
|
+
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
|
85
|
+
defer cancel()
|
|
86
|
+
|
|
87
|
+
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
|
88
|
+
if err != nil {
|
|
89
|
+
return nil, fmt.Errorf("creating request: %w", err)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
resp, err := http.DefaultClient.Do(req)
|
|
93
|
+
if err != nil {
|
|
94
|
+
return nil, fmt.Errorf("executing request: %w", err)
|
|
95
|
+
}
|
|
96
|
+
defer resp.Body.Close()
|
|
97
|
+
|
|
98
|
+
return io.ReadAll(resp.Body)
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Fan-Out/Fan-In
|
|
103
|
+
```go
|
|
104
|
+
func fanOut[T any](in <-chan T, n int) []<-chan T {
|
|
105
|
+
outs := make([]<-chan T, n)
|
|
106
|
+
for i := 0; i < n; i++ {
|
|
107
|
+
out := make(chan T)
|
|
108
|
+
outs[i] = out
|
|
109
|
+
go func() {
|
|
110
|
+
defer close(out)
|
|
111
|
+
for v := range in {
|
|
112
|
+
out <- v
|
|
113
|
+
}
|
|
114
|
+
}()
|
|
115
|
+
}
|
|
116
|
+
return outs
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
func fanIn[T any](ins ...<-chan T) <-chan T {
|
|
120
|
+
var wg sync.WaitGroup
|
|
121
|
+
out := make(chan T)
|
|
122
|
+
|
|
123
|
+
for _, in := range ins {
|
|
124
|
+
wg.Add(1)
|
|
125
|
+
go func(ch <-chan T) {
|
|
126
|
+
defer wg.Done()
|
|
127
|
+
for v := range ch {
|
|
128
|
+
out <- v
|
|
129
|
+
}
|
|
130
|
+
}(in)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
go func() {
|
|
134
|
+
wg.Wait()
|
|
135
|
+
close(out)
|
|
136
|
+
}()
|
|
137
|
+
|
|
138
|
+
return out
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Error Handling
|
|
143
|
+
|
|
144
|
+
### Wrapping Errors
|
|
145
|
+
```go
|
|
146
|
+
func readConfig(path string) (*Config, error) {
|
|
147
|
+
data, err := os.ReadFile(path)
|
|
148
|
+
if err != nil {
|
|
149
|
+
return nil, fmt.Errorf("reading config file: %w", err)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var config Config
|
|
153
|
+
if err := json.Unmarshal(data, &config); err != nil {
|
|
154
|
+
return nil, fmt.Errorf("parsing config: %w", err)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if err := config.Validate(); err != nil {
|
|
158
|
+
return nil, fmt.Errorf("validating config: %w", err)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return &config, nil
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Custom Error Types
|
|
166
|
+
```go
|
|
167
|
+
type ValidationError struct {
|
|
168
|
+
Field string
|
|
169
|
+
Message string
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
func (e *ValidationError) Error() string {
|
|
173
|
+
return fmt.Sprintf("%s: %s", e.Field, e.Message)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Check error type
|
|
177
|
+
var validationErr *ValidationError
|
|
178
|
+
if errors.As(err, &validationErr) {
|
|
179
|
+
// Handle validation error
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Sentinel Errors
|
|
184
|
+
```go
|
|
185
|
+
var (
|
|
186
|
+
ErrNotFound = errors.New("not found")
|
|
187
|
+
ErrUnauthorized = errors.New("unauthorized")
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
// Check sentinel
|
|
191
|
+
if errors.Is(err, ErrNotFound) {
|
|
192
|
+
// Handle not found
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Interface Design
|
|
197
|
+
|
|
198
|
+
### Small Interfaces
|
|
199
|
+
```go
|
|
200
|
+
// Good: Small, focused interfaces
|
|
201
|
+
type Reader interface {
|
|
202
|
+
Read(p []byte) (n int, err error)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
type Writer interface {
|
|
206
|
+
Write(p []byte) (n int, err error)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
type ReadWriter interface {
|
|
210
|
+
Reader
|
|
211
|
+
Writer
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Accept interface, return struct
|
|
215
|
+
func NewBufferedReader(r Reader) *BufferedReader {
|
|
216
|
+
return &BufferedReader{r: r}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Functional Options
|
|
221
|
+
```go
|
|
222
|
+
type Option func(*Server)
|
|
223
|
+
|
|
224
|
+
func WithPort(port int) Option {
|
|
225
|
+
return func(s *Server) {
|
|
226
|
+
s.port = port
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
func WithTimeout(d time.Duration) Option {
|
|
231
|
+
return func(s *Server) {
|
|
232
|
+
s.timeout = d
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
func NewServer(opts ...Option) *Server {
|
|
237
|
+
s := &Server{
|
|
238
|
+
port: 8080,
|
|
239
|
+
timeout: 30 * time.Second,
|
|
240
|
+
}
|
|
241
|
+
for _, opt := range opts {
|
|
242
|
+
opt(s)
|
|
243
|
+
}
|
|
244
|
+
return s
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Project Structure
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
myproject/
|
|
252
|
+
├── cmd/
|
|
253
|
+
│ └── myapp/
|
|
254
|
+
│ └── main.go
|
|
255
|
+
├── internal/
|
|
256
|
+
│ ├── handler/
|
|
257
|
+
│ ├── service/
|
|
258
|
+
│ └── repository/
|
|
259
|
+
├── pkg/
|
|
260
|
+
│ └── publiclib/
|
|
261
|
+
├── go.mod
|
|
262
|
+
├── go.sum
|
|
263
|
+
└── Makefile
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Makefile
|
|
267
|
+
```makefile
|
|
268
|
+
.PHONY: build test lint
|
|
269
|
+
|
|
270
|
+
build:
|
|
271
|
+
go build -o bin/myapp ./cmd/myapp
|
|
272
|
+
|
|
273
|
+
test:
|
|
274
|
+
go test -race -cover ./...
|
|
275
|
+
|
|
276
|
+
lint:
|
|
277
|
+
golangci-lint run
|
|
278
|
+
|
|
279
|
+
bench:
|
|
280
|
+
go test -bench=. -benchmem ./...
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Performance
|
|
284
|
+
|
|
285
|
+
### Profiling
|
|
286
|
+
```go
|
|
287
|
+
import _ "net/http/pprof"
|
|
288
|
+
|
|
289
|
+
func main() {
|
|
290
|
+
go func() {
|
|
291
|
+
log.Println(http.ListenAndServe("localhost:6060", nil))
|
|
292
|
+
}()
|
|
293
|
+
// ...
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Access: go tool pprof http://localhost:6060/debug/pprof/profile
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Benchmarking
|
|
300
|
+
```go
|
|
301
|
+
func BenchmarkProcess(b *testing.B) {
|
|
302
|
+
data := setupTestData()
|
|
303
|
+
|
|
304
|
+
b.ResetTimer()
|
|
305
|
+
for i := 0; i < b.N; i++ {
|
|
306
|
+
Process(data)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
func BenchmarkProcess_Parallel(b *testing.B) {
|
|
311
|
+
data := setupTestData()
|
|
312
|
+
|
|
313
|
+
b.ResetTimer()
|
|
314
|
+
b.RunParallel(func(pb *testing.PB) {
|
|
315
|
+
for pb.Next() {
|
|
316
|
+
Process(data)
|
|
317
|
+
}
|
|
318
|
+
})
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### sync.Pool
|
|
323
|
+
```go
|
|
324
|
+
var bufferPool = sync.Pool{
|
|
325
|
+
New: func() any {
|
|
326
|
+
return new(bytes.Buffer)
|
|
327
|
+
},
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
func process(data []byte) string {
|
|
331
|
+
buf := bufferPool.Get().(*bytes.Buffer)
|
|
332
|
+
defer func() {
|
|
333
|
+
buf.Reset()
|
|
334
|
+
bufferPool.Put(buf)
|
|
335
|
+
}()
|
|
336
|
+
|
|
337
|
+
// Use buf...
|
|
338
|
+
return buf.String()
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Anti-Patterns to Avoid
|
|
343
|
+
|
|
344
|
+
| Anti-Pattern | Why Bad | Better Approach |
|
|
345
|
+
|--------------|---------|-----------------|
|
|
346
|
+
| Ignoring errors | Bugs hide | Always handle errors |
|
|
347
|
+
| Naked returns | Hard to read | Named returns or explicit |
|
|
348
|
+
| Large interfaces | Hard to implement/mock | Small, focused interfaces |
|
|
349
|
+
| Global variables | Hard to test | Dependency injection |
|
|
350
|
+
| Panicking in libraries | Unexpected crashes | Return errors |
|
|
351
|
+
| Using init() heavily | Hidden side effects | Explicit initialization |
|
|
352
|
+
|
|
353
|
+
## Constraints
|
|
354
|
+
|
|
355
|
+
- Handle all errors explicitly
|
|
356
|
+
- Use `context.Context` for cancellation
|
|
357
|
+
- Prefer composition over inheritance
|
|
358
|
+
- Keep interfaces small
|
|
359
|
+
- Use `go vet` and `golangci-lint`
|
|
360
|
+
- Document exported identifiers
|
|
361
|
+
|
|
362
|
+
## Related Skills
|
|
363
|
+
|
|
364
|
+
- `backend-developer` - Go web services
|
|
365
|
+
- `devops-engineer` - Go CLI tools
|
|
366
|
+
- `kubernetes-specialist` - Go operators
|