Skip to content

Commit

Permalink
Merge pull request #50 from fabianoflorentino/5-terminar-o-curso
Browse files Browse the repository at this point in the history
5 terminar o curso
  • Loading branch information
fabianoflorentino authored Dec 8, 2024
2 parents e97df49 + 0202b4f commit d4c5b50
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 41 deletions.
74 changes: 73 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ Capítulos do Curso
--cap=11 --topics Exercícios Ninja: Nível 5
--cap=12 --topics Funções
--cap=13 --topics Exercícios Ninja: Nível 6
--cap=14 --topics Ponteiros
--cap=15 --topics Exercícios Ninja: Nível 7
--cap=16 --topics Aplicações
--cap=17 --topics Exercícios Ninja: Nível 8
--cap=18 --topics Concorrência
--cap=19 --topics Seu Ambiente de Desenvolvimento
--cap=20 --topics Exercícios Ninja: Nível 9
--cap=21 --topics Canais
```

### Ajuda
Expand Down Expand Up @@ -115,6 +123,8 @@ Capítulos do Curso
--cap=17 --topics Exercícios Ninja: Nível 8
--cap=18 --topics Concorrência
--cap=19 --topics Seu Ambiente de Desenvolvimento
--cap=20 --topics Exercícios Ninja: Nível 9
--cap=21 --topics Canais

Outline do Curso por Capítulo

Expand All @@ -130,6 +140,15 @@ Outline do Curso por Capítulo
--cap=10 --overview Structs
--cap=11 --overview Exercícios Ninja Nível 5
--cap=12 --overview Funções
--cap=13 --overview Exercícios Ninja Nível 6
--cap=14 --overview Ponteiros
--cap=15 --overview Exercícios Ninja Nível 7
--cap=16 --overview Aplicações
--cap=17 --overview Exercícios Ninja Nível 8
--cap=18 --overview Concorrência
--cap=19 --overview Seu Ambiente de Desenvolvimento
--cap=20 --overview Exercícios Ninja Nível 9
--cap=21 --overview Canais

Capítulo 1: Visão Geral do Curso

Expand Down Expand Up @@ -386,6 +405,35 @@ Capítulo 19: Seu Ambiente de Desenvolvimento
--explorando-o-github Exibe informações sobre explorando o github.
--compilacao-cruzada Exibe informações sobre compilação cruzada.
--pacotes Exibe informações sobre pacotes.

Capítulo 20: Exercícios Ninja Nível 9

--na-pratica-exercicio-1 --nivel-9 Exibe o Exercício 1 do capítulo 20
--na-pratica-exercicio-1 --nivel-9 --resolucao Exibe a resolução do Exercício 1 do capítulo 20
--na-pratica-exercicio-2 --nivel-9 Exibe o Exercício 2 do capítulo 20
--na-pratica-exercicio-2 --nivel-9 --resolucao Exibe a resolução do Exercício 2 do capítulo 20
--na-pratica-exercicio-3 --nivel-9 Exibe o Exercício 3 do capítulo 20
--na-pratica-exercicio-3 --nivel-9 --resolucao Exibe a resolução do Exercício 3 do capítulo 20
--na-pratica-exercicio-4 --nivel-9 Exibe o Exercício 4 do capítulo 20
--na-pratica-exercicio-4 --nivel-9 --resolucao Exibe a resolução do Exercício 4 do capítulo 20
--na-pratica-exercicio-5 --nivel-9 Exibe o Exercício 5 do capítulo 20
--na-pratica-exercicio-5 --nivel-9 --resolucao Exibe a resolução do Exercício 5 do capítulo 20
--na-pratica-exercicio-6 --nivel-9 Exibe o Exercício 6 do capítulo 20
--na-pratica-exercicio-6 --nivel-9 --resolucao Exibe a resolução do Exercício 6 do capítulo 20
--na-pratica-exercicio-7 --nivel-9 Exibe o Exercício 7 do capítulo 20
--na-pratica-exercicio-7 --nivel-9 --resolucao Exibe a resolução do Exercício 7 do capítulo 20

Capítulo 21: Canais

--entendendo-canais Entendendo Canais
--canais-direcionais-utilizando-canais Canais direcionais & utilizando canais
--range-e-close Range e Close
--select Select
--a-expressao-comma-ok A expressão comma ok
--convergencia Convergência
--divergencia Divergência
--context Context

```
## Estrutura do Projeto
Expand All @@ -403,12 +451,25 @@ Capítulo 19: Seu Ambiente de Desenvolvimento
├── configs
│   └── _env
├── docker-compose.yml
├── docs
│   └── questionarie.md
├── go.mod
├── go.sum
├── help.out
├── internal
│   ├── agrupamento_de_dados
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── aplicacoes
│   │   ├── examples.go
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── canais
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── concorrencia
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── exercicios_ninja_nivel_1
│   │   ├── overview.yml
│   │   ├── resolution_exercises.go
Expand Down Expand Up @@ -437,6 +498,14 @@ Capítulo 19: Seu Ambiente de Desenvolvimento
│   │   ├── overview.yml
│   │   ├── resolution_exercises.go
│   │   └── topics.go
│   ├── exercicios_ninja_nivel_8
│   │   ├── overview.yml
│   │   ├── resolution_exercises.go
│   │   └── topics.go
│   ├── exercicios_ninja_nivel_9
│   │   ├── overview.yml
│   │   ├── resolution_exercise.go
│   │   └── topics.go
│   ├── fluxo_de_controle
│   │   ├── overview.yml
│   │   └── topics.go
Expand All @@ -456,6 +525,9 @@ Capítulo 19: Seu Ambiente de Desenvolvimento
│   ├── ponteiros
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── seu_ambiente_de_desenvolvimento
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── structs
│   │   ├── overview.yml
│   │   └── topics.go
Expand All @@ -481,7 +553,7 @@ Capítulo 19: Seu Ambiente de Desenvolvimento
│   └── overview.go
└── tree.log

27 directories, 62 files
34 directories, 79 files
```
## Documentação Técnica
Expand Down
154 changes: 154 additions & 0 deletions internal/canais/overview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
description:
name: "Capítulo 21: Canais"
sections:
- title: Entendendo Canais
text: |
- Canais são o Jeito Certo® de fazer sincronização e código concorrente.
- Eles nos permitem trasmitir valores entre goroutines.
- Servem pra coordenar, sincronizar, orquestrar, e buffering.
- Na prática:
- make(chan type, b)
- <- 42
- <-c
- Canais bloqueiam:
- Eles são como corredores em uma corrida de revezamento
- Eles tem que "passar o bastão" de maneira sincronizada
- Se um corredor tentar passar o bastão pro próximo, mas o próximo corredor não estiver lá...
- Ou se um corredor ficar esperando receber o bastão, mas ninguem entregar...
- ...não dá certo.
- Exemplos:
- Poe um valor num canal e faz um print. Block.
- Código acima com goroutine.
- Ou com buffer. Via de regra: má idéia; é legal em certas situações, mas em geral é melhor sempre passar o bastão de maneira sincronizada.
- Interessante: ref/spec → types
- Código:
- Block: https://play.golang.org/p/dClS7vQlYE (não roda!)
- Go routine: https://play.golang.org/p/ZbNCwUuiPi
- Buffer: https://play.golang.org/p/32vYvCR7qn
- Buffer block: https://play.golang.org/p/smeW6vigAT
- Mais buffer: https://play.golang.org/p/Pe2pcboGiA
- title: Canais direcionais & utilizando canais
text: |
- Canais podem ser direcionais.
- E isso serve pra...?
- Um send channel e um receive channel são tipos diferentes. Isso permite que os type-checking mechanisms do compilador façam com que não seja possível, por exemplo, escrever num canal de leitura.
- Aos aventureitos: https://stackoverflow.com/questions/13596186/whats-the-point-of-one-way-channels-in-go
- Canais bidirecionals (send & receive)
- send chan<-
- error: "invalid operation: <-cs (receive from send-only type chan<- int)"
- receive <-chan
- error: "invalid operation: cr <- 42 (send to receive-only type <-chan int)"
- Exemplo: https://play.golang.org/p/TlcSm8bHkW
- A seta sempre aponta para a esquerda.
- Assignment/conversion:
- de geral para específico
- de específico para geral não
- Exemplos:
- geral pra específico: https://play.golang.org/p/H1uk4YGMBB
- específico pra específico: https://play.golang.org/p/8JkOnEi7-a
- específico pra geral: https://play.golang.org/p/4sOKuQRHq7
- atribuição tipos !=: https://play.golang.org/p/bG7H6l03VQ
- Em funcs podemos especificar:
- receive channel
- Parâmetro receive channel: (c <-chan int)
- No scope dessa função, esse canal só recebe
- Não podemos fechar um receive channel
- send channel
- Parâmetro send channel: (c chan<- int)
- No scope dessa função, esse canal só envia
- Podemos fechar um send channel
- Exemplo: passando informação de uma função para outra.
- Código: https://play.golang.org/p/TlcSm8bHkW (replay)
- title: Range e Close
text: |
- Range:
- gofunc com for loop com send e close(chan)
- recebe com range chan
- Código: https://play.golang.org/p/_g5IEjSkh1
- title: Select
text: |
- Select é como switch, só que pra canais, e não é sequencial.
- "A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready." — https://tour.golang.org/concurrency/5
- Na prática:
- Exemplo 1:
- Duas go funcs enviando X/2 numeros cada uma pra um canal
- For loop X valores, select case <-x
- Exemplo 2:
- Func 1 recebe X valores de canal, depois manda qualquer coisa pra chan quit
- Func 2 for infinito, select: case envia pra canal, case recebe de quit
- Exemplo 3:
- Chans par, ímpar, quit
- Func send manda números pares pra um canal, ímpares pra outro, e fecha/quit
- Func receive é um select entre os três canais, encerra no quit
- Problema!
- Go Playground:
- 1. https://play.golang.org/p/xC3e1wBxgv
- 2. https://play.golang.org/p/_NZqhBXN-v
- 3. https://play.golang.org/p/rK8QwsBo0H
- title: A expressão comma ok
text: |
- v, ok := <-chan
- Se receber valor: v, true
- Canal fechado, nada, etc.: zero v, false
- Agora vamos resolver o problema do exercício anterior usando comma ok.
- Código: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/21_canais/06_exerc%C3%ADcio_anterior/main.go
- title: Convergência
text: |
- Observamos convergência quando informação de vários canais é enviada a um número menor de canais.
- Interessante: <- <-
- Na prática, exemplos:
- 1. Todd:
- Canais par, ímpar, e converge.
- Func send manda pares pra um, ímpares pro outro, depois fecha.
- Func receive cria duas go funcs, cada uma com um for range, enviando dados dos canais par e ímpar pro canal converge. Não esquecer de WGs!
- Por fim um range retira todas as informações do canal converge.
- 2. Rob Pike (palestra Go Concurrency Patterns):
- Func trabalho cria um canal, cria uma go func que manda dados pra esse canal, e retorna o canal. Interessante: time.Duration(rand.Intn(1e3))
- Func converge toma dois canais, cria um canal novo, e cria duas go funcs com for infinito que passa tudo para o canal novo. Retorna o canal novo.
- Por fim chamamos canal := converge(trabalho(nome1), trabalho(nome2)) e usamos um for para receber dados do canal var.
- Código: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/21_canais/07
- title: Divergência
text: |
- Divergência é o contrário de convergência :)
- Na prática, exemplos:
- 1. Um stream vira centenas de go funcs que depois convergem.
- Dois canais.
- Uma func manda X números ao primeiro canal.
- Outra func faz um range deste canal, e para cada ítem lança uma go func que poe o retorno de trabalho() no canal dois.
- Trabalho() é um timer aleatório pra simular workload.
- Por fim, range canal dois demonstra os valores.
- 2. Com throttling! Ou seja, com um número máximo de go funcs.
- Ídem acima, mas a func que lança go funcs é assim:
- Cria X go funcs, cada uma com um range no primeiro canal que, para cada item, poe o retorno de trabalho() no canal dois.
- Código: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/21_canais/08
- title: Context
text: |
- Só pra ter uma idéia geral:
- Se a gente lança 500 goroutines pra fazer uma tarefa, e cancelamos a tarefa no meio do caminho, como fazemos pra matar as goroutines?
- Documentação: https://golang.org/pkg/context/
- Aos aventureiros: https://blog.golang.org/context
- Destaques:
- ctx := context.Background
- ctx, cancel = context.WithCancel(context.Background)
- goroutine: select case <-ctx.Done(): return; default: continua trabalhando.
- check ctx.Err();
- Tambem tem WithDeadline/Timeout
- Exemplos (Todd):
- Analisando:
- Background: https://play.golang.org/p/cByXyrxXUf
- WithCancel: https://play.golang.org/p/XOknf0aSpx
- Função Cancel: https://play.golang.org/p/UzQxxhn_fm
- Exemplos práticos:
- func WithCancel: https://play.golang.org/p/Lmbyn7bO7e
- func WithCancel: https://play.golang.org/p/wvGmvMzIMW
- func WithDeadline: https://play.golang.org/p/Q6mVdQqYTt
- func WithTimeout: https://play.golang.org/p/OuES9sP_yX
- func WithValue: https://play.golang.org/p/8JDCGk1K4P
90 changes: 90 additions & 0 deletions internal/canais/topics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Package canais provides functions to demonstrate and execute various concepts related to channels in Go.
// It includes sections on understanding channels, directional channels, range and close, select statement,
// comma ok idiom, convergence, divergence, and context. The package also provides menu options and help
// descriptions for each section.
package canais

import (
"fmt"

"github.com/fabianoflorentino/aprendago/pkg/format"
)

// rootDir is a constant that holds the relative path to the "canais" directory
// within the "internal" directory. This path is used as a base directory for
// various operations related to the "canais" module in the project.
const (
rootDir = "internal/canais"
)

// Canais is a function that prints the title of Chapter 21: Channels
// and executes several sections related to the topic of channels in Go.
// The sections covered are:
// - Understanding Channels
// - Directional Channels & Using Channels
// - Range and Close
// - Select
// - The comma ok idiom
// - Convergence
// - Divergence
// - Context
func Canais() {
fmt.Printf("\n\nCapítulo 21: Canais\n")

executeSection("Entendendo Canais")
executeSection("Canais direcionais & utilizando canais")
executeSection("Range e Close")
executeSection("Select")
executeSection("A expressão comma ok")
executeSection("Convergência")
executeSection("Divergência")
executeSection("Context")
}

// MenuCanais returns a slice of format.MenuOptions, each representing a menu option
// for different topics related to Go channels. Each menu option includes a string
// that represents the option and a function to execute when the option is selected.
// The topics covered include understanding channels, directional channels, range and close,
// select statement, the comma ok expression, convergence, divergence, and context.
func MenuCanais([]string) []format.MenuOptions {
return []format.MenuOptions{
{Options: "--entendendo-canais", ExecFunc: func() { executeSection("Entendendo Canais") }},
{Options: "--canais-direcionais-utilizando-canais", ExecFunc: func() { executeSection("Canais direcionais & utilizando canais") }},
{Options: "--range-e-close", ExecFunc: func() { executeSection("Range e Close") }},
{Options: "--select", ExecFunc: func() { executeSection("Select") }},
{Options: "--a-expressao-comma-ok", ExecFunc: func() { executeSection("A expressão comma ok") }},
{Options: "--convergencia", ExecFunc: func() { executeSection("Convergência") }},
{Options: "--divergencia", ExecFunc: func() { executeSection("Divergência") }},
{Options: "--context", ExecFunc: func() { executeSection("Context") }},
}
}

// HelpMeCanais prints a list of topics related to channels in Go.
// It creates a slice of HelpMe structs, each containing a flag and a description
// of a specific topic about channels. The topics include understanding channels,
// directional channels, using channels, range and close, select statement,
// the comma ok idiom, convergence, divergence, and context.
// The function then prints the chapter title and calls PrintHelpMe to display the topics.
func HelpMeCanais() {
hlp := []format.HelpMe{
{Flag: "--entendendo-canais", Description: "Entendendo Canais"},
{Flag: "--canais-direcionais-utilizando-canais", Description: "Canais direcionais & utilizando canais"},
{Flag: "--range-e-close", Description: "Range e Close"},
{Flag: "--select", Description: "Select"},
{Flag: "--a-expressao-comma-ok", Description: "A expressão comma ok"},
{Flag: "--convergencia", Description: "Convergência"},
{Flag: "--divergencia", Description: "Divergência"},
{Flag: "--context", Description: "Context"},
}

fmt.Println("\nCapítulo 21: Canais")
format.PrintHelpMe(hlp)
}

// executeSection formats and processes a given section of the project.
// It takes a section name as a string parameter and uses the FormatSection
// function from the format package to apply formatting to the specified section
// within the root directory.
func executeSection(section string) {
format.FormatSection(rootDir, section)
}
Loading

0 comments on commit d4c5b50

Please sign in to comment.