-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #46 from fabianoflorentino/development
Development to Main
- Loading branch information
Showing
8 changed files
with
371 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
--- | ||
description: | ||
name: "Capítulo 20: Exercícios Ninja Nível 9" | ||
sections: | ||
- title: "Na prática: Exercício #1" | ||
text: | | ||
Alem da goroutine principal, crie duas outras goroutines. | ||
- Cada goroutine adicional devem fazer um print separado. | ||
- Utilize waitgroups para fazer com que suas goroutines finalizem antes de o programa terminar. | ||
- Solução: | ||
- https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/01_foda/main_foda.go | ||
- https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/01_moleza/main_moleza.go | ||
- title: "Na prática: Exercício #2" | ||
text: | | ||
- Esse exercício vai reforçar seus conhecimentos sobre conjuntos de métodos. | ||
- Crie um tipo para um struct chamado "pessoa" | ||
- Crie um método "falar" para este tipo que tenha um receiver ponteiro (*pessoa) | ||
- Crie uma interface, "humanos", que seja implementada por tipos com o método "falar" | ||
- Crie uma função "dizerAlgumaCoisa" cujo parâmetro seja do tipo "humanos" e que chame o método "falar" | ||
- Demonstre no seu código: | ||
- Que você pode utilizar um valor do tipo "*pessoa" na função "dizerAlgumaCoisa" | ||
- Que você não pode utilizar um valor do tipo "pessoa" na função "dizerAlgumaCoisa" | ||
- Se precisar de dicas, veja: https://gobyexample.com/interfaces | ||
- Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/02/main.go | ||
- title: "Na prática: Exercício #3" | ||
text: | | ||
- Utilizando goroutines, crie um programa incrementador: | ||
- Tenha uma variável com o valor da contagem | ||
- Crie um monte de goroutines, onde cada uma deve: | ||
- Ler o valor do contador | ||
- Salvar este valor | ||
- Fazer yield da thread com runtime.Gosched() | ||
- Incrementar o valor salvo | ||
- Copiar o novo valor para a variável inicial | ||
- Utilize WaitGroups para que seu programa não finalize antes de suas goroutines. | ||
- Demonstre que há uma condição de corrida utilizando a flag -race | ||
- Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/03/main.go | ||
- title: "Na prática: Exercício #4" | ||
text: | | ||
- Utilize mutex para consertar a condição de corrida do exercício anterior. | ||
- Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/04/main.go | ||
- title: "Na prática: Exercício #5" | ||
text: | | ||
- Utilize atomic para consertar a condição de corrida do exercício #3. | ||
- Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/05/main.go | ||
- title: "Na prática: Exercício #6" | ||
text: | | ||
- Crie um programa que demonstra seu OS e ARCH. | ||
- Rode-o com os seguintes comandos: | ||
- go run | ||
- go build | ||
- go install | ||
- Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/06/main.go | ||
- title: "Na prática: Exercício #7" | ||
text: | | ||
- "If you do not leave your comfort zone, you do not remember the trip" — Brian Chesky | ||
- Faça download e instale: https://obsproject.com/ | ||
- Escolha um tópico dos que vimos até agora. Sugestões: | ||
- Motivos para utilizar Go | ||
- Instalando Go | ||
- Configurando as environment variables (e.g. GOPATH) | ||
- Hello world | ||
- go commands e.g. go help | ||
- Variáveis | ||
- O operador curto de declaração | ||
- Constantes | ||
- Loops | ||
- init, cond, post | ||
- break | ||
- continue | ||
- Funções | ||
- func (receiver) identifier(params) (returns) { code } | ||
- Métodos | ||
- Interfaces | ||
- Conjuntos de métodos | ||
- Tipos | ||
- Conversão? | ||
- Concorrência vs. paralelismo | ||
- Goroutines | ||
- WaitGroups | ||
- Mutex | ||
- Grave um vídeo onde *você* ensina o tópico em questão. | ||
- Faça upload do vídeo no YouTube. | ||
- Compartilhe o vídeo no Twitter e me marque no tweet (@ellenkorbes). |
153 changes: 153 additions & 0 deletions
153
internal/exercicios_ninja_nivel_9/resolution_exercise.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package exercicios_ninja_nivel_9 | ||
|
||
import ( | ||
"fmt" | ||
"runtime" | ||
"sync" | ||
"sync/atomic" | ||
) | ||
|
||
var ws sync.WaitGroup | ||
var mu sync.Mutex | ||
var contador int | ||
|
||
const numberOfGoroutines = 50000 | ||
|
||
// ResolucaoNaPraticaExercicio1 demonstrates the use of goroutines and WaitGroup in Go. | ||
// It creates 10 goroutines, each printing a message to the console. | ||
// The WaitGroup is used to wait for all goroutines to complete before the function returns. | ||
// Note: The variable 'i' is captured by reference in the goroutine, which may lead to unexpected results. | ||
func ResolucaoNaPraticaExercicio1() { | ||
var ws sync.WaitGroup | ||
ws.Add(10) | ||
|
||
for i := 0; i < 10; i++ { | ||
go func() { | ||
defer ws.Done() | ||
fmt.Println("Goroutine", i) | ||
}() | ||
} | ||
|
||
ws.Wait() | ||
} | ||
|
||
// ResolucaoNaPraticaExercicio2 creates an instance of the 'pessoa' struct with the name "fabiano" and age 39, | ||
// and then calls the 'dizerAlgumaCoisa' function, passing a pointer to this instance. | ||
// ResolucaoNaPraticaExercicio2 demonstrates the creation of a 'pessoa' struct instance | ||
// and the usage of the 'dizerAlgumaCoisa' function. The 'pessoa' struct has fields 'nome' | ||
// and 'idade'. The 'dizerAlgumaCoisa' function takes a pointer to a 'pessoa' instance | ||
// and performs some operation on it. This function showcases how to work with structs | ||
// and pointers in Go. | ||
func ResolucaoNaPraticaExercicio2() { | ||
p := pessoa{ | ||
nome: "fabiano", | ||
idade: 39, | ||
} | ||
|
||
dizerAlgumaCoisa(&p) | ||
} | ||
|
||
// ResolucaoNaPraticaExercicio3 demonstrates a concurrency issue with the use of goroutines and a shared variable. | ||
// The function initializes a WaitGroup to wait for 100 goroutines to complete their execution. | ||
// Each goroutine increments a shared counter variable `contador`. | ||
// However, due to the lack of synchronization mechanisms (like mutexes), the increments to `contador` are not atomic, | ||
// leading to a race condition. As a result, the final value of `contador` may not be 100 as expected. | ||
// The function prints the final value of `contador` after all goroutines have completed. | ||
func ResolucaoNaPraticaExercicio3() { | ||
var ws sync.WaitGroup | ||
ws.Add(100) | ||
|
||
var contador int | ||
|
||
for i := 0; i < 100; i++ { | ||
go func() { | ||
defer ws.Done() | ||
valor := contador | ||
valor++ | ||
contador = valor | ||
}() | ||
} | ||
|
||
ws.Wait() | ||
|
||
fmt.Println("Contador:", contador) | ||
} | ||
|
||
// ResolucaoNaPraticaExercicio4 demonstrates a concurrency example using goroutines, WaitGroup, and Mutex in Go. | ||
// The function initializes a WaitGroup to wait for 100 goroutines to complete their execution. | ||
// A shared counter variable is incremented by each goroutine in a thread-safe manner using a Mutex to avoid race conditions. | ||
// The Mutex ensures that only one goroutine can access and modify the counter at a time. | ||
// The function prints the value of the counter after each increment, but the print statement is outside the critical section, | ||
// which may lead to inconsistent output due to concurrent access. | ||
func ResolucaoNaPraticaExercicio4() { | ||
buildGoRoutine(numberOfGoroutines) | ||
ws.Wait() | ||
|
||
fmt.Println("All goroutines completed: ", contador) | ||
} | ||
|
||
// ResolucaoNaPraticaExercicio5 demonstrates the use of the atomic package to fix | ||
// a race condition in a concurrent program. The function initializes a counter | ||
// variable and a WaitGroup to synchronize 100 goroutines. Each goroutine increments | ||
// the counter atomically using atomic.AddInt32, ensuring that the increment operation | ||
// is thread-safe. The WaitGroup is used to wait for all goroutines to complete before | ||
// printing the final value of the counter. | ||
func ResolucaoNaPraticaExercicio5() { | ||
// Utilize atomic para consertar a condição de corrida do exercício #3. | ||
var contador int32 | ||
var ws sync.WaitGroup | ||
|
||
ws.Add(100) | ||
|
||
for i := 0; i < 100; i++ { | ||
go func() { | ||
defer ws.Done() | ||
atomic.AddInt32(&contador, 1) | ||
}() | ||
} | ||
|
||
ws.Wait() | ||
|
||
fmt.Println("Contador:", contador) | ||
} | ||
|
||
func ResolucaoNaPraticaExercicio6() { | ||
fmt.Printf("Sistema Operacional: %v\nArquitetura: %v\n", runtime.GOOS, runtime.GOARCH) | ||
} | ||
|
||
func ResolucaoNaPraticaExercicio7() { | ||
fmt.Println("https://dev.to/fabianoflorentino/a-interface-write-11c5") | ||
} | ||
|
||
type humanos interface { | ||
falar() | ||
} | ||
|
||
type pessoa struct { | ||
nome string | ||
idade int | ||
} | ||
|
||
func (p *pessoa) falar() { | ||
fmt.Println("Olá, meu nome é", p.nome) | ||
} | ||
|
||
func dizerAlgumaCoisa(h humanos) { | ||
h.falar() | ||
} | ||
|
||
func buildGoRoutine(i int) { | ||
ws.Add(i) | ||
|
||
for j := 0; j < i; j++ { | ||
go func() { | ||
defer mu.Unlock() | ||
v := contador | ||
v++ | ||
contador = v | ||
|
||
mu.Lock() | ||
ws.Done() | ||
}() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package exercicios_ninja_nivel_9 | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/fabianoflorentino/aprendago/pkg/format" | ||
) | ||
|
||
const rootDir = "internal/exercicios_ninja_nivel_9" | ||
|
||
func ExerciciosNinjaNivel9() { | ||
fmt.Printf("\n\nCapítulo 20: Exercícios Ninja Nível 9\n") | ||
|
||
executeSection("Na prática: Exercício #1") | ||
executeSection("Na prática: Exercício #2") | ||
executeSection("Na prática: Exercício #3") | ||
executeSection("Na prática: Exercício #4") | ||
executeSection("Na prática: Exercício #5") | ||
executeSection("Na prática: Exercício #6") | ||
executeSection("Na prática: Exercício #7") | ||
} | ||
|
||
func MenuExerciciosNinjaNivel9([]string) []format.MenuOptions { | ||
return []format.MenuOptions{ | ||
{Options: "--na-pratica-exercicio-1 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #1") }}, | ||
{Options: "--na-pratica-exercicio-1 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio1() }}, | ||
{Options: "--na-pratica-exercicio-2 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #2") }}, | ||
{Options: "--na-pratica-exercicio-2 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio2() }}, | ||
{Options: "--na-pratica-exercicio-3 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #3") }}, | ||
{Options: "--na-pratica-exercicio-3 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio3() }}, | ||
{Options: "--na-pratica-exercicio-4 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #4") }}, | ||
{Options: "--na-pratica-exercicio-4 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio4() }}, | ||
{Options: "--na-pratica-exercicio-5 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #5") }}, | ||
{Options: "--na-pratica-exercicio-5 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio5() }}, | ||
{Options: "--na-pratica-exercicio-6 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #6") }}, | ||
{Options: "--na-pratica-exercicio-6 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio6() }}, | ||
{Options: "--na-pratica-exercicio-7 --nivel-9", ExecFunc: func() { executeSection("Na prática: Exercício #7") }}, | ||
{Options: "--na-pratica-exercicio-7 --nivel-9 --resolucao", ExecFunc: func() { ResolucaoNaPraticaExercicio7() }}, | ||
} | ||
} | ||
|
||
func HelpMeExerciciosNinjaNivel9() { | ||
hlp := []format.HelpMe{ | ||
{Flag: "--na-pratica-exercicio-1 --nivel-9", Description: "Exibe o Exercício 1 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-1 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 1 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-2 --nivel-9", Description: "Exibe o Exercício 2 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-2 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 2 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-3 --nivel-9", Description: "Exibe o Exercício 3 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-3 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 3 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-4 --nivel-9", Description: "Exibe o Exercício 4 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-4 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 4 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-5 --nivel-9", Description: "Exibe o Exercício 5 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-5 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 5 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-6 --nivel-9", Description: "Exibe o Exercício 6 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-6 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 6 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-7 --nivel-9", Description: "Exibe o Exercício 7 do capítulo 20"}, | ||
{Flag: "--na-pratica-exercicio-7 --nivel-9 --resolucao", Description: "Exibe a resolução do Exercício 7 do capítulo 20"}, | ||
} | ||
|
||
fmt.Printf("\nCapítulo 20: Exercícios Ninja Nível 9\n") | ||
format.PrintHelpMe(hlp) | ||
} | ||
|
||
func executeSection(section string) { | ||
format.FormatSection(rootDir, section) | ||
} |
Oops, something went wrong.