Compare commits

...

19 Commits

  1. 2
      .gitignore
  2. 1
      aprendi-na-marra/.gitignore
  3. 6
      aprendi-na-marra/book.toml
  4. 102
      aprendi-na-marra/src/SUMMARY.md
  5. 42
      aprendi-na-marra/src/avisos.md
  6. 57
      aprendi-na-marra/src/intro.md
  7. 1
      aprendi-na-marra/src/pessoal/aprender-sobre-voce.md
  8. 1
      aprendi-na-marra/src/pessoal/assuma.md
  9. 1
      aprendi-na-marra/src/pessoal/blogar.md
  10. 1
      aprendi-na-marra/src/pessoal/cdc.md
  11. 1
      aprendi-na-marra/src/pessoal/codigo-ruim.md
  12. 1
      aprendi-na-marra/src/pessoal/coisas-que-voce-nao-sabe.md
  13. 1
      aprendi-na-marra/src/pessoal/diga-nao.md
  14. 1
      aprendi-na-marra/src/pessoal/especialistas.md
  15. 1
      aprendi-na-marra/src/pessoal/hora-de-parar.md
  16. 1
      aprendi-na-marra/src/pessoal/index.md
  17. 1
      aprendi-na-marra/src/pessoal/irritacao-com-arquitetura.md
  18. 1
      aprendi-na-marra/src/pessoal/lista-de-bugs-idiotas.md
  19. 1
      aprendi-na-marra/src/pessoal/micro-agressoes.md
  20. 1
      aprendi-na-marra/src/pessoal/mostre-solucao-idiota.md
  21. 1
      aprendi-na-marra/src/pessoal/mundo-da-ti.md
  22. 1
      aprendi-na-marra/src/pessoal/nao-pronto.md
  23. 1
      aprendi-na-marra/src/pessoal/observe-reacoes.md
  24. 1
      aprendi-na-marra/src/pessoal/pessoas-toxicas.md
  25. 1
      aprendi-na-marra/src/pessoal/responsabilize-se.md
  26. 1
      aprendi-na-marra/src/pessoal/sair.md
  27. 1
      aprendi-na-marra/src/pessoal/sindrome-do-heroi.md
  28. 1
      aprendi-na-marra/src/pessoal/solucao.md
  29. 8
      aprendi-na-marra/src/programacao/antes.md
  30. 52
      aprendi-na-marra/src/programacao/antes/custo-cognitivo.md
  31. 36
      aprendi-na-marra/src/programacao/antes/debuggers.md
  32. 34
      aprendi-na-marra/src/programacao/antes/entenda-atalhos.md
  33. 30
      aprendi-na-marra/src/programacao/antes/fluxo-de-dados.md
  34. 53
      aprendi-na-marra/src/programacao/antes/gherkin.md
  35. 118
      aprendi-na-marra/src/programacao/antes/numero-magico-sete.md
  36. 57
      aprendi-na-marra/src/programacao/antes/passos-como-comentarios.md
  37. 34
      aprendi-na-marra/src/programacao/antes/patterns-nao-sao-solucoes.md
  38. 65
      aprendi-na-marra/src/programacao/antes/programacao-funcional.md
  39. 52
      aprendi-na-marra/src/programacao/antes/specs-antes.md
  40. 33
      aprendi-na-marra/src/programacao/antes/usuarios.md
  41. 1
      aprendi-na-marra/src/programacao/controle-de-versao.md
  42. 1
      aprendi-na-marra/src/programacao/controle-de-versao/gerrit.md
  43. 1
      aprendi-na-marra/src/programacao/controle-de-versao/git-flow.md
  44. 1
      aprendi-na-marra/src/programacao/controle-de-versao/sempre-use-scv.md
  45. 1
      aprendi-na-marra/src/programacao/controle-de-versao/um-commit.md
  46. 1
      aprendi-na-marra/src/programacao/documentacao.md
  47. 1
      aprendi-na-marra/src/programacao/documentacao/documentacao-com-e.md
  48. 1
      aprendi-na-marra/src/programacao/documentacao/documentacao-e-contrato.md
  49. 1
      aprendi-na-marra/src/programacao/documentacao/documente.md
  50. 1
      aprendi-na-marra/src/programacao/documentacao/linguagens-com-documentacao.md
  51. 8
      aprendi-na-marra/src/programacao/index.md
  52. 1
      aprendi-na-marra/src/programacao/organizacao.md
  53. 1
      aprendi-na-marra/src/programacao/organizacao/bibliotecas.md
  54. 1
      aprendi-na-marra/src/programacao/organizacao/notas-em-papel.md
  55. 1
      aprendi-na-marra/src/programacao/organizacao/organizacao-de-projetos.md
  56. 1
      aprendi-na-marra/src/programacao/programando.md
  57. 1
      aprendi-na-marra/src/programacao/programando/comece-idiota.md
  58. 1
      aprendi-na-marra/src/programacao/programando/deixe-explodir.md
  59. 1
      aprendi-na-marra/src/programacao/programando/facil.md
  60. 1
      aprendi-na-marra/src/programacao/programando/fora-do-projeto.md
  61. 1
      aprendi-na-marra/src/programacao/programando/jogar-fora.md
  62. 1
      aprendi-na-marra/src/programacao/programando/lide-com-erro.md
  63. 1
      aprendi-na-marra/src/programacao/programando/mudancas-de-interface.md
  64. 1
      aprendi-na-marra/src/programacao/programando/otimizacao.md
  65. 1
      aprendi-na-marra/src/programacao/programando/parametros-booleanos.md
  66. 1
      aprendi-na-marra/src/programacao/programando/problemas-futuros.md
  67. 1
      aprendi-na-marra/src/programacao/programando/rode-localmente.md
  68. 1
      aprendi-na-marra/src/programacao/programando/solucao-permanente.md
  69. 1
      aprendi-na-marra/src/programacao/programando/tipos-de-dados.md
  70. 1
      aprendi-na-marra/src/programacao/programando/unidades.md
  71. 1
      aprendi-na-marra/src/programacao/programando/use-estruturas.md
  72. 1
      aprendi-na-marra/src/programacao/programando/use-timezones.md
  73. 1
      aprendi-na-marra/src/programacao/programando/use-utf8.md
  74. 1
      aprendi-na-marra/src/programacao/rodando.md
  75. 1
      aprendi-na-marra/src/programacao/rodando/adicione-e-remova.md
  76. 1
      aprendi-na-marra/src/programacao/rodando/arquivo-de-config.md
  77. 1
      aprendi-na-marra/src/programacao/rodando/composicao-de-aplicacoes-idiota.md
  78. 1
      aprendi-na-marra/src/programacao/rodando/logs-para-eventos.md
  79. 1
      aprendi-na-marra/src/programacao/rodando/monitoramento.md
  80. 1
      aprendi-na-marra/src/programacao/rodando/opcoes-de-linha-de-comando.md
  81. 1
      aprendi-na-marra/src/programacao/rodando/transparencia.md
  82. 1
      aprendi-na-marra/src/programacao/testes.md
  83. 1
      aprendi-na-marra/src/programacao/testes/linguagens-com-testes.md
  84. 1
      aprendi-na-marra/src/programacao/testes/testes-apis.md
  85. 1
      aprendi-na-marra/src/programacao/testes/testes-codigo-morto.md
  86. 1
      aprendi-na-marra/src/programacao/testes/testes-de-integracao.md
  87. 1
      aprendi-na-marra/src/programacao/testes/testes-na-linha-de-comando.md
  88. 1
      aprendi-na-marra/src/programando/rodando/composicao-de-aplicacoes.md
  89. 1
      aprendi-na-marra/src/times/a-ferramenta-certa-obvia.md
  90. 1
      aprendi-na-marra/src/times/a-ferramenta-certa.md
  91. 1
      aprendi-na-marra/src/times/cargo-cult.md
  92. 1
      aprendi-na-marra/src/times/discuta-com-o-time.md
  93. 1
      aprendi-na-marra/src/times/estilo-de-codigo-google.md
  94. 1
      aprendi-na-marra/src/times/estilo-de-codigo.md
  95. 1
      aprendi-na-marra/src/times/estilos-em-revisao-de-codigo.md
  96. 1
      aprendi-na-marra/src/times/formatador-de-codigo.md
  97. 1
      aprendi-na-marra/src/times/hero-projects.md
  98. 1
      aprendi-na-marra/src/times/index.md
  99. 1
      aprendi-na-marra/src/times/linguagens-tem-mais.md
  100. 4
      things-i-learnt/src/disclaimer.md
  101. Some files were not shown because too many files have changed in this diff Show More

2
.gitignore vendored

@ -0,0 +1,2 @@
*.sw?
book/*

1
aprendi-na-marra/.gitignore vendored

@ -0,0 +1 @@
book

6
aprendi-na-marra/book.toml

@ -0,0 +1,6 @@
[book]
authors = ["Julio Biason"]
language = "pt"
multilingual = false
src = "src"
title = "Coisas Que Aprendi Na Marra (em 30 Anos de Desenvolvimento de Software)"

102
aprendi-na-marra/src/SUMMARY.md

@ -0,0 +1,102 @@
# Resumo
- [Introdução](./intro.md)
- [Avisos](./avisos.md)
- [Programação](./programacao/index.md)
- [Antes de Sair Programando](./programacao/antes.md)
- [Specs Antes, Código Depois](./programacao/antes/specs-antes.md)
- [Passos Como Comentários](./programacao/antes/passos-como-comentarios.md)
- [Gherkin É Seu Amigo para Entender Expectativas](./programacao/antes/gherkin.md)
- [Design Patterns São Usados Para Dar Nomes as Coisas, Não Para Soluções](./programacao/antes/patterns-nao-sao-solucoes.md)
- [Pensar em Fluxo de Dados Ganha de Design Patterns](./programacao/antes/fluxo-de-dados.md)
- [O Número Mágico Sete, Mais ou Menos Dois](./programacao/antes/numero-magico-sete.md)
- [Custo Cognitivo É O Assassino do Entendimento](./programacao/antes/custo-cognitivo.md)
- [Aprenda O Básico de Programação Funcional](./programacao/antes/programacao-funcional.md)
- [Atalhos São Legais, Mas Apenas a Custo Prazo](./programacao/antes/entenda-atalhos.md)
- [Debuggers São Superestimados](./programacao/antes/debuggers.md)
- [Pense Nos Usuários](./programacao/antes/usuarios.md)
- [Testes De Software](./programacao/testes.md)
- [Testes Unitários São Bons, Testes de Integração São Mais Melhores](./programacao/testes/testes-de-integracao.md)
- [Testar Toda Função Gera Código Morto](./programacao/testes/testes-codigo-morto.md)
- [Testes Geram Uma API Melhor](./programacao/testes/testes-apis.md)
- [Crie Testes Que Você Saiba Rodar Na Linha de Comando](./programacao/testes/testes-na-linha-de-comando.md)
- [Boas Linguagens Tem Testes Embutidos](./programacao/testes/linguagens-com-testes.md)
- [Documentando Seu Código](./programacao/documentacao.md)
- [Documentação É Uma Carta de Amor Ao Seu Futuro Eu](./programacao/documentacao/documente.md)
- [A Documentação de uma Função É o Seu Contrato](./programacao/documentacao/documentacao-e-contrato.md)
- [Se A Documentação de uma Função Tem "E", Está Errado](./programacao/documentacao/documentacao-com-e.md)
- [Boas Linguagens Tem Documentação Embutida](./programacao/documentacao/linguagens-com-documentacao.md)
- [Controle de Versões](./programacao/controle-de-versao.md)
- [Sempre Use Um Controle de Versão](./programacao/controle-de-versao/sempre-use-scv.md)
- [Um Commit Por Alteração](./programacao/controle-de-versao/um-commit.md)
- [Gerrit É Uma Cagada](./programacao/controle-de-versao/gerrit.md)
- [Git-Flow É o Caminho](./programacao/controle-de-versao/git-flow.md)
- [Organização de Projetos](./programacao/organizacao.md)
- [Organize Seu Código por Tipo de Dado, Não Por Função](./programacao/organizacao/organizacao-de-projetos.md)
- [Crie Bibliotecas](./programacao/organizacao/bibliotecas.md)
- [Notas em Papel São Bem Úteis](./programacao/organizacao/notas-em-papel.md)
- [Escrevendo Código](./programacao/programando.md)
- [Esteja Pronto Para Jogar Código Fora](./programacao/programando/jogar-fora.md)
- [Resolver O Futuro Gera Problemas Futuros](./programacao/programando/problemas-futuros.md)
- [Não Use Booleanos Como Parâmetros](./programacao/programando/parametros-booleanos.md)
- [Cuidado Com as Alterações de Interface](./programacao/programando/mudancas-de-interface.md)
- [É Melhor Deixar A Aplicação Explodir Do Que Fazer Nada](./programacao/programando/deixe-explodir.md)
- [Se Você Sabe Como Lidar Com O Erro, Lide](./programacao/programando/lide-com-erro.md)
- [Tipos Dizem O Que Seus Dados São](./programacao/programando/tipos-de-dados.md)
- [Se Os Seus Dados Tem Estrutura, Use Uma Estrutura](./programacao/programando/use-estruturas.md)
- [Não Mexa Em Coisas Fora do Seu Projeto](./programacao/programando/fora-do-projeto.md)
- [Resista À Tentação do Fácil](./programacao/programando/facil.md)
- [Comece de Forma Idiota](./programacao/programando/comece-idiota.md)
- [Sempre Use Timezones nas Datas](./programacao/programando/use-timezones.md)
- [Sempre Use UTF-8 nas Strings](./programacao/programando/use-utf8.md)
- [Otimização É Para Compiladores](./programacao/programando/otimizacao.md)
- [Unidades Fazem as Coisas Mais Claras](./programacao/programando/unidades.md)
- [Se Não Roda No Seu Computador, Está Errado](./programacao/programando/rode-localmente.md)
- [Nada Mais Permanente Que Uma Solução Temporária](./programacao/programando/solucao-permanente.md)
- [Fazendo As Coisas Andarem](./programacao/rodando.md)
- [O Arquivo de Config É Seu Amigo](./programacao/rodando/arquivo-de-config.md)
- [Opção de Linha de Comando São Esquisitas Mas Úteis](./programacao/rodando/opcoes-de-linha-de-comando.md)
- [Não Apenas Composição de Funções, Mas Composição de Aplicações](./programando/rodando/composicao-de-aplicacoes.md)
- [Mesmo Para Composição de Aplicações, Comece Idiota](./programacao/rodando/composicao-de-aplicacoes-idiota.md)
- [Logs São Para Eventos, Não Interface Com o Usuário](./programacao/rodando/logs-para-eventos.md)
- [Seja Transparente Com o Usuário](./programacao/rodando/transparencia.md)
- [Uma Versão para Adicionar, Uma Para Remover](./programacao/rodando/adicione-e-remova.md)
- [Aprenda a Monitorar](./programacao/rodando/monitoramento.md)
- [Comunidades e Times](./times/index.md)
- [Uma Linguagem É Mais Que Uma Linguagem](./times/linguagens-tem-mais.md)
- [Entenda e Afaste-se do "Cargo Cult"](./times/cargo-cult.md)
- ["A Ferramenta Certa" Tem Sempre Algo Por Trás](./times/a-ferramenta-certa.md)
- ["A Ferramenta Certa" É Mais Óbvia Do Que Você Pensa](./times/a-ferramenta-certa-obvia.md)
- [Revisão de Código Não É Para Validar Estilo](./times/estilos-em-revisao-de-codigo.md)
- [Formatadores de Código São Ok, Mas Nenhuma Bala de Prata](./times/formatador-de-codigo.md)
- [Estilo de Código: Siga-o!](./times/estilo-de-codigo.md)
- [... A Não Ser Que Seja o Estilo Google](./times/estilo-de-codigo-google.md)
- [Hero Projects: Você Vai Ter Que Fazer](./times/hero-projects.md)
- [Alterações Globais Devem Ser Discutidas com o Time](./times/discuta-com-o-time.md)
- [Pessoal](./pessoal/index.md)
- [Empresas Procuram por Especialistas, Mas Ficam com os Generalistas](./pessoal/especialistas.md)
- [Mantenha Uma Lista de Bugs Idiotas Que Levaram Mais de 1 Hora para Resolver](./pessoal/lista-de-bugs-idiotas.md)
- [Quando É Hora de Parar, É Hora de Parar](./pessoal/hora-de-parar.md)
- [Códigos de Conduta Protege](./pessoal/cdc.md)
- [Aprenda a Dizer Não](./pessoal/diga-nao.md)
- [Responsabilize-se Pelo Uso do Seu Código](./pessoal/responsabilize-se.md)
- [Não Diga Que Está Pronto Quando Não Estiver](./pessoal/nao-pronto.md)
- [Pessoas Se Irritam Com Arquitetura Porque Elas Se Importam](./pessoal/irritacao-com-arquitetura.md)
- [Você Vai Aprender Sobre Você Na Marra](./pessoal/aprender-sobre-voce.md)
- [Preste Atenção Como as Pessoas Reagem à Você](./pessoal/observe-reacoes.md)
- [Não Confunda "Hero Project" com "Síndrome do Herói"](./pessoal/sindrome-do-heroi.md)
- [Cuidado com Pessoas Tóxicas](./pessoal/pessoas-toxicas.md)
- [Cuidado com Micro-Agressões](./pessoal/micro-agressoes.md)
- [Pessoas Tóxicas/Agressivas Não Tem Solução -- A Menos Que Seja Você](./pessoal/solucao.md)
- [Perceba Quando For Hora de Sair](./pessoal/sair.md)
- [O Mundo da T.I. É Bem Pequeno](./pessoal/mundo-da-ti.md)
- [Escrever um Blog Sobre a Sua Solução Idiota É Melhor que o Silêncio](./pessoal/blogar.md)
- [Não Esconda Sua Solução Idiota](./pessoal/mostre-solucao-idiota.md)
- [Mantenha Uma Lista de Coisas Que Você Não Sabe](./pessoal/coisas-que-voce-nao-sabe.md)
- [Você Sempre Tem Tempo](./pessoal/tempo.md)
- [Assuma Suas Merdas](./pessoal/assuma.md)
- [Não Defenda Código Ruim](./pessoal/codigo-ruim.md)
<!--
vim:spelllang=pt tw=0:
-->

42
aprendi-na-marra/src/avisos.md

@ -0,0 +1,42 @@
# Avisos
Existe uma coisa mágica que você precisa saber sobre esse livro: É tudo
opinião pessoal.
Um monte de coisas que eu vou comentar pelo livro vai sair da minha
experiência pessoal em vários projetos -- sistema de aplicação, backends web,
sistemas embarcados, aplicações móveis, stream processing -- em várias
linguagens -- C, C++, Python, Java, Clojure, Rust. E, como parte de
experiência pessoal, tudo vai refletir a minhão opinião sobre os assuntos
abordados.
Obviamente, você não precisa concordar com cada um dos pontos colocados. Mas
eu espero que pelo menos esses comentários façam você repensar esses assuntos.
Ainda, algumas vezes eu posso mencionar algum exemplo que pessoas que me
conhecem -- porque trabalharam comigo, me ouviram reclamar de algum projeto,
herdaram um dos meus projetos, _eu_ herdei um dos projetos _deles_ -- podem
reconhecer do que eu estou falando e achar que eu estou atacando o autor
original.
Eu não estou.
Nós cometemos erros. Algumas vezes nós não conhecemos o assunto que estamos
atacando, algumas vezes nós não temos a especificação completa, algumas vezes
nós não temos o tempo certo para escrever as coisas da forma certa numa hora
de crise. E é por isso que algumas coisas não ficam tão bonitas quanto
deveriam. Se você acha que eu estou atacando o autor original de algum
exemplo, basta olhar as coisas que eu mesmo escrevi e você vai ver que eu fiz
coisas bem piores.
Mas eu preciso do exemplo. Eu espero que mostrando para outras pessoas alguns
desses erros possa fazer com que as coisas melhorem. Eu quero mostrar de onde
saiu a minha opinião sobre os assuntos abordados. E, de novo, eu não estou
atacando o autor do código original. Eu posso até chamar o código de
"estúpido", mas não estou chamando o _autor_ de estúpido.
Com isso em mente...
<!--
vim:spelllang=pt:
-->

57
aprendi-na-marra/src/intro.md

@ -0,0 +1,57 @@
# Introdução
"Coisas Que Eu Aprendi Na Marra (Em 30 Anos de Desenvolvimento de Software)"
começou como uma simples sequencia de toots (o mesmo que "tweets", mas no
[Mastodon](https://functional.cafe/@juliobiason) quando eu estava pensando em
escrever uma nova apresentação?
Mas porque "uma nova apresentação"?
Eu participo de um grupo chamado "[Tchelinux](https://tchelinux.org)" com o
qual eu atravessei o estado; nós normalmente fazemos eventos em universidades
e falamos para pessoas que estão começando a universidade, explicando coisas
sobre software livre (libre) e algumas vezes falando sobre coisas que essas
pessoas normalmente não veriam no currículo da universidade.
Uma coisa que me incomoda é que poucas apresentações falam sobre "quando as
coisas dão errado". Todas apresentações mostram protótipos ou comentam os
pontos positivos de alguma coisa, e escondem tudo que poderia dar de
errado[^1]. Obviamente, depois de trabalhar por 30 anos com desenvolvimento de
software, eu vi uma boa quantidade de coisas que dão errado -- algumas vezes
numa montanha gigantesca de cagadas -- e por isso pensei "Talvez essa seja uma
coisa que as pessoas gostariam de ouvir".
(E pra ser completamente honesto, algumas dessas cagadas gigantescas foram
totalmente culpa minha.)
E foi assim que a sequencia de toots começou. Antes que eu percebesse, eu
passei praticamente o dia todo postando esse tipo de coisa (felizmente, a
minha caixa de "coisas pra fazer" estava praticamente vazia na época) e a
lista chegou a 30 pontos, mais adendos e alguns pontos com algumas
explicações. E foi assim que eu decidi transformar num post do meu blog.
(Aliás, minto: Alguém mencionou no Functional Café que eu deveria fazer um
post no meu blog para facilitar a leitura.)
A única coisa que eu pensei quando agrupei tudo num post era "isso vai ajudar
as pessoas a ler o conteúdo ao invés de ter que sair correndo atrás dos toots
no Mastodon". Mas aí o posto apareceu no Reddit. E no Twitter. E no
HackerNews. E no YCombination. E nenhum desses foi feito por mim.
Mas uma coisa: Cada ponto estava limitado pelo tamanho de um toot, que são 500
caracteres. Algumas vezes, isso não é o suficiente para expandir um ponto,
explicá-lo corretmente e adicionar alguns exemplos.
E foi assim que esse "livro" nasceu.
Uma coisa que você precisa ter em mente aqui: *Essas são minhas opiniões*. Eu
entendo que não é tudo "preto no branco" como eu coloco aqui, e experiencias
de outras pessoas podem não ser exatamente iguais. Ainda, você fica um pouco
cínico sobre tecnologia depois de 30 anos. Então... vá com calma, pois [Hic
sunt dracones](https://pt.wikipedia.org/wiki/Hic_sunt_dracones).
[^1]: Sim, eu também sou culpado de fazer isso.
<!--
vim:spelllang=pt:
-->

1
aprendi-na-marra/src/pessoal/aprender-sobre-voce.md

@ -0,0 +1 @@
# Você Vai Aprender Sobre Você Na Marra

1
aprendi-na-marra/src/pessoal/assuma.md

@ -0,0 +1 @@
# Assuma Suas Merdas

1
aprendi-na-marra/src/pessoal/blogar.md

@ -0,0 +1 @@
# Escrever um Blog Sobre a Sua Solução Idiota É Melhor que o Silêncio

1
aprendi-na-marra/src/pessoal/cdc.md

@ -0,0 +1 @@
# Códigos de Conduta Protege

1
aprendi-na-marra/src/pessoal/codigo-ruim.md

@ -0,0 +1 @@
# Não Defenda Código Ruim

1
aprendi-na-marra/src/pessoal/coisas-que-voce-nao-sabe.md

@ -0,0 +1 @@
# Mantenha Uma Lista de Coisas Que Você Não Sabe

1
aprendi-na-marra/src/pessoal/diga-nao.md

@ -0,0 +1 @@
# Aprenda a Dizer Não

1
aprendi-na-marra/src/pessoal/especialistas.md

@ -0,0 +1 @@
# Empresas Procuram por Especialistas, Mas Ficam com os Generalistas

1
aprendi-na-marra/src/pessoal/hora-de-parar.md

@ -0,0 +1 @@
# Quando É Hora de Parar, É Hora de Parar

1
aprendi-na-marra/src/pessoal/index.md

@ -0,0 +1 @@
# Pessoal

1
aprendi-na-marra/src/pessoal/irritacao-com-arquitetura.md

@ -0,0 +1 @@
# Pessoas Se Irritam Com Arquitetura Porque Elas Se Importam

1
aprendi-na-marra/src/pessoal/lista-de-bugs-idiotas.md

@ -0,0 +1 @@
# Mantenha Uma Lista de Bugs Idiotas Que Levaram Mais de 1 Hora para Resolver

1
aprendi-na-marra/src/pessoal/micro-agressoes.md

@ -0,0 +1 @@
# Cuidado com Micro-Agressões

1
aprendi-na-marra/src/pessoal/mostre-solucao-idiota.md

@ -0,0 +1 @@
# Não Esconda Sua Solução Idiota

1
aprendi-na-marra/src/pessoal/mundo-da-ti.md

@ -0,0 +1 @@
# O Mundo da T.I. É Bem Pequeno

1
aprendi-na-marra/src/pessoal/nao-pronto.md

@ -0,0 +1 @@
# Não Diga Que Está Pronto Quando Não Estiver

1
aprendi-na-marra/src/pessoal/observe-reacoes.md

@ -0,0 +1 @@
# Preste Atenção Como as Pessoas Reagem à Você

1
aprendi-na-marra/src/pessoal/pessoas-toxicas.md

@ -0,0 +1 @@
# Cuidado com Pessoas Tóxicas

1
aprendi-na-marra/src/pessoal/responsabilize-se.md

@ -0,0 +1 @@
# Responsabilize-se Pelo Uso do Seu Código

1
aprendi-na-marra/src/pessoal/sair.md

@ -0,0 +1 @@
# Perceba Quando For Hora de Sair

1
aprendi-na-marra/src/pessoal/sindrome-do-heroi.md

@ -0,0 +1 @@
# Não Confunda "Hero Project" com "Síndrome do Herói"

1
aprendi-na-marra/src/pessoal/solucao.md

@ -0,0 +1 @@
# Pessoas Tóxicas/Agressivas Não Tem Solução -- A Menos Que Seja Você

8
aprendi-na-marra/src/programacao/antes.md

@ -0,0 +1,8 @@
# Antes de Sair Programando
Antes de sentar na frente do computador e abrir o seu editor de textos/IDE para
escrever código, talvez você precise dar um passo para trás e pensar algumas coisas.
<!--
vim:spelllang=pt:
-->

52
aprendi-na-marra/src/programacao/antes/custo-cognitivo.md

@ -0,0 +1,52 @@
# Custo Cognitivo É O Assassino do Entendimento
"[Dissonância Cognitiva](https://en.wikipedia.org/wiki/Cognitive_dissonance)" é
um nome bonito para dizer "Eu preciso lembrar duas (ou mais) coisas diferentes
e contraditórias ao mesmo tempo para entender isso". Manter essas coisas
diferentes na sua cabeça cria um custo que fica acumulando quanto mais
indiretas essas coisas são (porque você precisa manter todas elas ao mesmo
tempo).
(Aviso: Eu gosto de usar a expressão "dissonância cognitiva" para parecer
inteligente. Eu explico depois a diferença entre "dissonância cognitiva" e
"custo cognitivo".)
Para dar um exemplo (leve) de custo cognitivo, eu vou lhe mostrar o seguinte:
* Você tem uma função chamada `sum()`. Ela retorna o somatório de uma lista de
números.
* O sistema está cheio de funções que começam com `is_`. Essas funções fazem um
teste e retorno um valor booleano.
* Existe uma função chamada `is_even()`. Ela recebe um número e retorna True se
o valor é par e False se o valor for ímpar.
Bem simples, certo? Uma função faz o somatório de números e outra retorna um
booleano.
Agora, o que você pensaria se visse isso, em Python:
```python
sum(is_even(x) for x in my_list)
```
Espera aí, eu não tinha dito que `sum()` faz o somatório de números? E que
`is_even()` retorna um booleano? Como é que eu somo booleanos? Qual é o
resultado esperado de "True + True + False"?
Infelizmente, isso funciona. Porque alguém, a muito tempo atrás, não achava que
booleanos era importantes o suficiente e usaram um inteiro no lugar. E todo
mundo que veio depois cometeu o mesmo erro.
Mas, para você, você vai ver uma linha que diz "somando uma lista de booleanos
retorna um número". E isso são duas coisas diferentes que você tem que, de
repente, manter em mente quando estiver lendo essa linha.
É por isso que [tipos são importantes](../programando/tipos-de-dados.md). E
custo cognitivo também está relacionado com [o número mágico
sete](./numero-magico-sete.md) porque você tem que manter duas coisas
ao mesmo tempo em mente, mas o primeiro é sobre itens relacionados, enquanto
que custo cognitivo se refere a coisas diferentes.
<!--
vim:spelllang=pt:
-->

36
aprendi-na-marra/src/programacao/antes/debuggers.md

@ -0,0 +1,36 @@
# Debuggers São Superestimados
Volta e meia eu escuto alguém reclamando que alguns editores de código são
ruins porque é difícil usar um debugger dentro deles. Eu diria que essa visão
está errada.
Mas vamos tirar algo do caminho antes de mais nada: Eu não estou querendo dizer
que debuggers são ruins e que você não deveria nunca usar um. Debuggers tem o
seu uso, mas toda vez que eu tentei usar um, era porque havia alguma outra
coisa faltando.
Quando eu estava usando um framework em Java, eu tive alguns problemas com o
código que eu havia escrito. Eu esperava que [a aplicação
explodisse](../programando/deixe-explodir.md) porque eu não coloquei nada para
lidar com os problemas. O que aconteceu foi que o framework escondeu o erro e
reiniciou o processamento. Para encontrar o que estava acontecendo, eu tive que
conectar um debugger e ver o que havia de errado com os dados; se eu não
fizesse isso, eu não teria a menor ideia de onde estava o problema.
O debugger era necessário aqui? Eu acredito que não. Se o framework mostrasse o
erro (explodisse, botasse uma textão nos logs, seja lá o que for), eu não
precisaria usar o debugger. Mas, porque havia coisas faltando, eu fui _forçado_
a usar um debugger.
Além disso, a longo prazo, você acaba com problemas em lugares onde você não
pode conectar um debugger -- por exemplo, no seu ambiente de produção. Você até
_pode_, mas não _deveria_. Por outro lado, se você estiver [logando
eventos](../rodando/logs-para-eventos.md), então você veria o que está
acontecendo, sem um debugger.
De novo, não quero desmerecer debuggers, mas a longo prazo, eles se tornam
inúteis e acabam apontando para lugares onde o suporte ao redor está faltando.
<!--
vim:spelllang=pt:
-->

34
aprendi-na-marra/src/programacao/antes/entenda-atalhos.md

@ -0,0 +1,34 @@
# Atalhos São Legais, Mas Apenas a Custo Prazo
Várias linguagens/bibliotecas/frameworks vem com alguma funcionalidade para
fazer com que você escreva menos código do que normalmente precisaria.
Mas o uso desses atalhos uma hora não vão servir para o que você precisa e aí
você vai precisar entender o que é que o atalho faz de verdade.
Frameworks e bibliotecas -- e até mesmo algumas linguagens -- vêm com "helpers"
para a maior parte das coisas com boilerplate. Ao invés de digitar 5 linhas de
código várias vezes, você usa uma função simples; ao invés de escrever a função
com 5 parâmetros, você ignora alguns dados e usa uma função com apenas um. Ou
você pode adicionar uma macro de expansão em cima da sua estrutura/classe e os
pontos faltantes vão ser automaticamente completados.
Não me entenda errado, eu acho atalhos super úteis.
Mas você precisa entender o que é que a macro/função está escondendo de você.
Porque mais cedo ou mais tarde, vai aparecer aquele caso em que o atalho não é
a solução perfeita e você precisa apenas mudar um pequeno detalhe. E aí você
vai ficar andando em círculos porque, bom, como é que diabos a macro/função faz
_aquilo_?
Eu já me dei mal com [Spring](http://spring.io/) e [Serde](https://serde.rs/')
porque eu comecei usando os atalhos sem entender o que eles faziam. E quando eu
precisei resolver um problema que o atalho não conseguia resolver sozinho, eu
tive que me aprofundar na documentação. E como eu pulei vários passos e fui
direto pro atalho, eu levei um bom tempo para realmente _entender_ o que é que
eu precisava fazer de diferente do que o que o atalho faz para resolver meu
problema.
<!--
vim:spelllang=pt:
-->

30
aprendi-na-marra/src/programacao/antes/fluxo-de-dados.md

@ -0,0 +1,30 @@
# Pensar em Fluxo de Dados Ganha de Design Patterns
Quando você estiver tentando encontrar uma solução para o seu problema, pense
na forma como os dados irão fluir pelo seu código.
Ao invés de focar em design patterns, uma forma melhor é pensar na forma como
o dado vão fluir -- e ser transformado -- no seu cóðigo.
Por exemplo, o usuário irá digitar um número. Você vai pegar esse número e
encontrar o registro específico no banco de dados. Essa é uma transformação --
não, não é "Eu vou pegar o número e receber uma coisa completamente diferente
baseado nesse número"; você está transformando o número num registro, usando o
banco de dados como transformação.
(Sim, eu sei, não parece óbvio de cara, mas se você tem que pensar que os dois
são representações do mesmo dado.)
A maior parte das vezes que eu fiz isso, eu consegui criar uma design mais
óbvio para minhas aplicações. Eu não pensei em quantas funções/classes seriam
necessárias para fazer essas transformações, isso foi algo que eu pensei
_depois_ de conseguir ver como os dados iriam fluir no código.
De certa forma, essa forma de pensar deixar as coisas mais simples porque você
tem uma lista de passos de transformações que você precisa fazer, de forma que
você coloca um depois do outro, descrevendo _exatamente_ o que o seu código
faz, o que previne um monte de código ruim no futuro.
<!--
vim:spelllang=pt:
-->

53
aprendi-na-marra/src/programacao/antes/gherkin.md

@ -0,0 +1,53 @@
# Gherkin É Seu Amigo para Entender Expectativas
Gherkin é um formato de arquivo para escrever testes de comportamento (BDD -
Behavior Driven Development). Mas também pode ser usado para dar a você
algumas dicas do que deve ser feito.
Então, vamos falar um pouco sobre o Gherkin:
[Gherkin](https://en.wikipedia.org/wiki/Cucumber_(software)#Gherkin_language)
é um formato de arquivo criado para o [Cucumber](https://en.wikipedia.org/wiki/Cucumber_(software)),
onde são descritos os cenários, o que há neles, quais ações o usuário/sistema
irá fazer e o qual é o resultado esperado dessas ações, em alto nível,
permitindo que pessoas sem experiência em programação possam descrever qual é
o resultado esperado de um sistema.
Embora Gherkin tenha nascido com o Cucumber, esse formato é suportado por
várias linguagens, através de bibliotecas externas.
Um arquivo Gherkin típico pode ser parecer com isso:
* **Dado que** _estado inicial do sistema_
* **Quando** _ação feita pelo usuário ou por um sistema externo_
* **Então** _estado esperado_
Ou, num formato mais concreto:
* **Dado que* o sistema está recuperando todos os tweets que o usuário deu
"like"
* **Quando** é encontrado um tweet com um anexo
* **Então** o anexo deve ser saldo junto com o texto do tweet
Simples, não?
E porque eu estou mencionando o Gherkin?
Algumas vezes, as especificações não são a forma mais direta de informação
sobre o que é esperado do sistema, e você não consegue pensar em como
[escrever os passos necessários](./passos-como-comentarios.md). Se você está
confuso sobre o que deve escrever, perguntar para a pessoa responsável para
escrever algo parecido com o Gherkin pode lhe trazer mais informações do que
deve ser feito.
Obviamente, não vai ser completo. Pessoas tendem a esquecer situações de erro
-- como preencher o campo de nome somente com números, usar letras num campo
de idade, tweets sem nenhum texto e apenas anexos -- mas pelo menos com uma
descrição do sistema em Gherkin, você pode ter uma visão melhor do todo.
Também, você pode não gostar de escrever especificações. Tudo bem, você pode
trocar elas por Gherkin.
<!--
vim:spelllang=pt:
-->

118
aprendi-na-marra/src/programacao/antes/numero-magico-sete.md

@ -0,0 +1,118 @@
# O Número Mágico Sete, Mais ou Menos Dois
"[The magical number](https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two)"
(O Número Mágico Sete, Mais Ou Menos Dois) é um artigo sobre a psicologia do
número de coisas que nós conseguimos manter na nossa memória ao mesmo tempo.
Pelo menos duas vezes eu vi esse tipo de construção onde uma função faz um
processamento, mais o retorno é o resultado desse processamento, mais o
resultado de uma segunda função e um processamento. Nada muito grande. Mas a
segunda função também faz um processamento e chama uma terceira função. E a
terceira função chama uma quarta. E a quarta, uma quinta. E a quinta função
chama uma sexta.
E "processamento" não era nada pequeno, como "adicionar dois" ou "multiplicar
por si mesmo ou por um valor configurável".
Algo do tipo:
```
func_1
+-- func_2
+-- func_3
+-- func_4
+-- func_5
+-- func6
```
(Se você estiver curioso sobre o verdadeiro processamento que eu vi, era uma
classe com uma função que fazia um processamento e chamava uma função de uma
classe injetada com injeção de dependências -- que é bem legal. Mas a
classe/dependência injetada tinha uma dependência injetada, e a terceira
injeção de dependência _também_ tinha uma dependência injetada e assim por
diante.)
Agora, quando você está tentando entender esse tipo de código para encontrar
um problema, você precisa manter em mente o que a primeira, segunda, terceira,
quarta, quinta e sexta funções fazem, porque elas ficam se chamando
(internamente).
Isso causa uma sobrecarga mental que não deveria ser necessária.
Não apenas isso, mas imagine que você bote um log antes e depois de chamar
`func_1`: o primeiro log vai mostrar os dados antes de serem enviados para a
função e o segundo log vai mostrar o resultado da chamada.
Aí você vai ficar com a impressão que `func_1` faz um monte de coisas, sendo
que ela faz uma transformação simples e passa adiante (novamente,
internamente).
(Eu tive essa experiência estranha com uma função chamada `expand`, que o log
antes da chamada mostrar os dados crus, compactado, mas o resultado não era
era o resultado descompactado, mas os dados já processados depois de
compactados.)
E qual seria a solução pra isso, você deve estar perguntando.
Bom, se ao invés de fazer a `func_1` chamada a `func_2`, você pode fazer ela
retornar o resultado (que não necessariamente é o resultado final) e _então_
chamar `func_2` com esse resultado.
Algo do tipo:
```
result1 = func_1
result2 = func_2(result1)
result3 = func_3(result2)
result4 = func_4(result3)
result5 = func_5(result4)
result6 = func_6(result5)
result7 = func_7(result6)
```
(Se voltarmos a nossa cadeira de injeção de dependências, você pode imaginar
quao invés de fazer DI7[^1] receber DI6 [que iria receber DI5 como
dependência, que iria receber DI4 como dependência, que iria receber DI3 como
dependência e assim por diante], você pode receber todas as dependências
injetadas numa única passada e aí iniciar a função que iria chamar as
dependência num só tacada, ao invés de encadear uma na outra.)
Agora você consegue entender _exatamente_ como é que os dados são
transformados -- e as funções teriam nomes melhores, como `expand`,
`break_lines`, `name_fields` e assim por diante, de forma que você consiga ver
que os dados compactados que eu comentei anteriormente são descompactados, o
conteúdo é quebrado linha por linha, e as linhas estão sendo tratadas para
colocar os nomes nos campos e assim por diante (e alguém poderia até mesmo
dizer que as coisas ficariam mais claras se depois de `break_lines` tivesse
uma função chamada `break_fields`, o que faria a função de `name_fields` mais
óbvia -- e uma construção como essa faria com que essa alteração fosse
trivial).
"Não isso não performa!" alguém pode gritar. Bom, talvez seja um pouco menos
performático que o original com chamadas aninhadas (porque não precisaria
criar e destruir os frames na stack, simplesmente iria empilhar os frames e
destruir tudo no final), mas otimização é para compiladores, não pessoas. O
seu trabalho é fazer com que o código seja _legível_ e _inteligível_. Se você
precisa de performance, você precisa pensar numa melhor sequência de passos
(ou um armazenamento de dados melhor), não uma solução terrível de ser
entendida.
Só uma nota rápida: Embora o artigo acima indique o número é próximo de 7,
novas pesquisas mostram que esse número é bem mais baixo que isso, mais para 4.
Então simplesmente fazendo `func_1` chamar `func_2`, que chamaria `func_3`,
que chamaria `func_4` já seria o suficiente para sobrecarregar alguém e fazer
com que eles percam a ideia do que o código faz.
PS: Se você conhecer um pouco de programação funcional, eu estou sugerindo
usar [composição de
funções](https://pt.wikipedia.org/wiki/Composi%C3%A7%C3%A3o_de_fun%C3%A7%C3%B5es)
ao invés de fazer chamadas aninhadas.
---
[^1]: A classe no sétimo nível de injeção de dependência; a primeira classe
com dependências injetadas seria "DI1".
<!--
vim:spelllang=pt:
-->

57
aprendi-na-marra/src/programacao/antes/passos-como-comentarios.md

@ -0,0 +1,57 @@
# Passos Como Comentários
Você não ver o caminho para resolver o seu problema? Escreva os passos como
comentários no seu código.
Você está lá, olhando para um arquivo vazio, se perguntando como é que vai
resolver o problema. Uma dica:
Pegue as especificações que você (ou alguém) escreveu. Quebre cada ponto num
série de passos para chegar ao resultado esperado. Você pode escrever em
qualquer linguagem, se você não quiser fazer em inglês[^1].
A partir daí, preencha os espaços entre os comentários com código.
Por exemplo, se você tiver uma especificação que diz "conecte ao servidor X e
recupere todos os dados. Salve o conteúdo num banco de dados. Lembre-se que a
API do servidor X permite que se passe um ID (o último ID visto) e você pode
usar isso para não ficar pedindo o mesmo conteúdo várias vezes". Fácil, né?
Escrevendo isso comentário, com os passos que você tem que fazer, você pode
chegar a ter algo do tipo:
```
// conectar ao servidor X
// recuperar os dados
// mandar os dados para o banco de dados
```
Ah, você esqueceu a parte do ID. Sem problemas, você adiciona esse passo no
lugar certo -- no nosso exemplo, não faz sentido conectar ao servidor antes de
ter o último ID visto, por exemplo:
```
// abrir o arquivo de configuração
// pegar o último ID visto; se o arquivo estiver vazio, não tem último ID
// conectar ao servidor X
// recuperar os dados a partir do último ID visto
// enviar os dados para o banco.
// salvar o último ID no arquivo de configuração
```
Agora ficou "fácil"[^2] : Você só precisa adicionar o código.
Se você estiver procurando por uma opção melhor, você pode transformar os
comentários em funções e, ao invés de ficar escrevendo o código entre os
comentários, você escreve a funcionalidade na função e, dessa forma, mantém
uma visão limpa do que a aplicação faz.
---
[^1]: Só porque "inglês" é a lingua franca da programação.
[^2]: Sim, eu estou sendo sarcástico.
<!--
vim:spelllang=pt:
-->

34
aprendi-na-marra/src/programacao/antes/patterns-nao-sao-solucoes.md

@ -0,0 +1,34 @@
# Design Patterns São Usados Para Dar Nomes as Coisas, Não Para Soluções
Infelizmente, a maior parte das vezes que eu vi design patterns sendo
aplicados, ele foram aplicados como uma forma de achar uma solução, e acabaram
forçando o problema a ser "distorcido" para caber no pattern.
Eu acredito que a grande maioria dos "vamos aplicar _esse_ design pattern"
antes que o problema seja entendi -- ou mesmo que se tenha tentando achar uma
solução -- vem como uma forma de [cargo cult](../../times/cargo-cult.md): "Nós
vimos que pessoas usaram esse pattern e resolveram o problema deles, então
vamos fazer o mesmo e resolver o nosso problema". Ou, pior: "Esse design
pattern foi criado por _pessoa famosa_, então vamos usar".
Mas a verdade é que design patterns _não_ devem ser usados como uma forma de
encontrar uma solução para qualquer problema. Você pode usar alguns deles como
base para a solução, mas você deve focar no _problema_, não no _pattern_.
"Será que o Visitor Pattern resolve isso?" é a pergunta errada. "O que devemos
usar para resolver nosso problema?" é a pergunta que realmente deve ser feita.
Uma vez que você resolveu o problema, você pode olhar e ver que é um visitor
pattern -- ou qualquer outro pattern. Se a solução não se parece com o
pattern, tudo bem, porque você _resolveu o problema_. E se o pattern
_resolveu_ seu problema... bom, parabêns, você sabe como chamar a sua
solução.
Eu vi isso acontecer várias vezes: Pessoas tem um problema; pessoas decidem
usar um pattern; o pattern não resolve o problema (não resolve exatamente
100%, mas acima de 50%); o que acontece é que as pessoas começam a destorcer o
problema para que ele se encaixe no pattern ou, pior, começam a adicionar
camadas para transformar o problema no pattern.
<!--
vim:spelllang=pt:
-->

65
aprendi-na-marra/src/programacao/antes/programacao-funcional.md

@ -0,0 +1,65 @@
# Aprenda O Básico de Programação Funcional
Nessa altura do campeonato, você deve ter ouvido falar de como programação
funcional é legal. Existem vários conceitos nela, mas tenha em mente os
conceitos mais básicos dela.
Um monte de apresentações sobre programação funcional vêm com palavras
estranhas como "functors" e "monads". Não que seja prejudicial conhecer o que
elas querem dizer (aviso: eu ainda não sei). Mas algumas coisas da programação
funcional são fáceis de entender e usar.
Por exemplo, imutabilidade. Isso quer dizer que os seus dados não podem mudar
depois de criados. Você tem um registro de um usuário e o usuário mudou de
senha? Não, não mude o valor do campo de senha, crie um novo registro de
usuário com a senha atualizada e remova o antigo. Eu sei que isso cria uma
sequencia de "cria e destrói" que basicamente não fazem sentido (porque você
deveria alocar memória para um novo usuário, copiar todos os campos com exceção
de um, definir apenas um campo, e liberar a memória do antigo? Não faz
sentido!) mas, a longo prazo, isso previne resultados estranhos, principalmente
depois de você entender e começar a usar threads.
(A ideia é prevenir um estado compartilhado -- memória -- entre partes do seu
código.)
Outro conceito útil são funções puras. Funções puras são funções que, se
chamadas com os mesmos parâmetros, sempre retornam o mesmo resultado, não
importa quantas vezes você as chame. Um exemplo de função não pura é o
`random()`: cada vez que você chama `random()`, você tem como retorno um valor
diferente[^1]. Um exemplo de uma função pura seria algo parecido com isso em
Python:
```python
def mult(x):
return x * 4
```
Não importa quantas vezes você chame `mult2)`, sempre terá o 8 como resultado.
Outro exemplo seria nossa senha imutável apresentada acima: Você pode
facilmente escrever uma função que recebe um registro de usuário e retorna um
novo registro com a senha alterada. Você pode chamar a função várias vezes e
ainda ter o mesmo resultado no final.
Funções puras são úteis porque, principalmente, elas são fáceis de serem
testadas.
Segundo, elas são fáceis de serem encadeadas num [fluxo de
dados](./fluxo-dedados.md): Como elas não tem estado interno (que é o
verdadeiro motivo de serem chamadas funções puras), você pode facilmente chamar
uma depois da outra e não importa quantas vezes você passe valores entre elas,
elas sempre produzem o mesmo resultado. E como cada função, dado a mesma
entrada, produz o mesmo resultado, encadeando todas elas _também_ gera o mesmo
resultado.
Só esses dois conceitos podem fazer com que você tenha mais código (de novo,
você está criando um novo registro ao invés de simplesmente alterar apenas um
campo), mas o resultado final é que o seu código ficará mais robusto.
[^1]: Com exceção de Haskell, mas ela requer que você envie uma semente toda
vez, fazendo com que você tenha valores baseados nessa semente, e assim a
função ainda é pura.
<!--
vim:spelllang=pt:
-->

52
aprendi-na-marra/src/programacao/antes/specs-antes.md

@ -0,0 +1,52 @@
# Specs Antes, Código Depois
"Sem requisitos ou design, programação é a arte de adicionar bugs em um
arquivo texto vazio." -- Louis Srygley
Se você não sabe o que você está tentando resolver, você não vai saber o que
programar.
Várias vezes nós temos essa sensação de "me deixa programar!" Mas sem entender
qual é o problema que tem que ser resolvido, você vai acabar escrevendo um
monte de coisas que não resolve nada -- ou, pelo menos, nada que _deveria_ ser
resolvido.
Então fica a dica: Tente fazer uma especificação simples daquilo que você quer
resolver. Tenha em mente que mesmo com as especificações, você pode ter que
[jogar código fora](../programando/jogar-fora.md), porque o seu entendimento
do problema vai aumentar conforme o projeto avança.
Sim, é um paradoxo: Você precisa saber o que escrever para saber o que
programar para evitar perder tempo resolvendo o problema errado, mas a
especificação pode estar errada, e aí você vai, _invariavelmente_, acabar
resolvendo o problema errado de qualquer forma. Então, qual o ponto de tudo
isso? O ponto é, a especificação reflete o seu entendimento do problema _num
determinado ponto_: Tudo que você (e o seu time) sabem está _lá_.
Das vezes que eu passei mais tempo olhando para meu código, me perguntando o
que fazer na sequencia, foi quando nós não tínhamos o próximo passo definido:
Eram pontos faltantes para solução, ou nós não tínhamos as estruturas de
comunicação definidas, ou algo do tipo. Normalmente, quando isso acontecia, eu
fiquei brincando no Twitter ou no Mastodon ao invés de tentar resolver o
problema. Agora, quando você se pegar perguntando isso -- "Eu não sei o que
fazer agora, eu não sei se eu terminei de resolver o problema atual" -- então
talvez seja hora de parar um pouco e falar com outras pessoas para descobrir o
que fazer.
Outro ponto sobre isso: Erik Deitrich escreveu um post sobre "Não Aprenda a
Programar - Aprenda a Automatizar" ([Don’t Learn to Code — Learn to
Automate](https://daedtech.com/dont-learn-to-code-learn-to-automate/)), que é
uma coisa que eu tenho que concordar porque a maior parte de nós, quando
estamos programado, pensamos "Eu preciso fazer isso, depois eu pego aquilo e
coloco lá, e de lá eu faço essa outra coisa". Basicamente, nós criamos
modelos de especificações na nossa mente, passo a passo, naquilo que nós
precisamos fazer -- basicamente, aquilo que precisamos automatizar. E, a
partir daí, tudo pode ficar até mais fácil, porque agora você pode pegar essa
especificação e fazer "Primeiro, eu como é que eu faço isso; Ok, entendi,
agora eu tenho que pegar o resultado daquilo e colocar lá" e assim por diante.
Você até tem um caminho para aprendizado, se você estiver iniciando a
programar.
<!--
vim:spelllang=pt:
-->

33
aprendi-na-marra/src/programacao/antes/usuarios.md

@ -0,0 +1,33 @@
# Pense Nos Usuários
Pense em como os dados que você está coletando dos seus usuário será usado --
isso é muito importante atualmente, onde "privacidade" é um serviço premium.
Eu já tive uma discussão com um CTO sobre a coleta do número de IMEI na nossa
aplicação mobile. Basicamente, não tínhamos nenhum motivo para capturar essa
informação mas, como ele colocou na época, "Nós queremos saber se um usuário
usa dois telefones, ou se dois usuários usam o mesmo telefone" (e isso não
seria usado para melhorar o serviço em praticamente nada). Eu levantei o fato
de que não precisamos dessa informação e que sentia que basicamente estaríamos
invadindo a privacidade dos nossos usuários. E ainda assim, ele decidiu
continuar com a coleta. Minha resposta: "Ok, eu vou fazer, mas quero deixar
anotado que eu não estou feliz com essa solução".
No final, a aplicação foi barrada no store... por estar capturando o IMEI.
Mas há casos e casos. Se você realmente _realmente_ precisar capturar os dados
do usuário, tenha certeza que estes estão protegidos contra acessos indevidos,
seja por ações externas (alguém achou uma falha de segurança na sua aplicação)
ou internal (um funcionário infeliz resolveu levar os dados dos seus cliente
com ele).
E tenha certeza, _haverá_ uma falha de segurança em algum ponto, é só uma
questão de tempo. Se você puder, a melhor forma de proteger os dados dos seus
usuários é nunca capturar dado algum. Quando for encontrada a falha de
segurança no seu sistema ou quando um colega sair da empresa de forma infeliz,
não haverão dados para serem expostos ao mundo, de qualquer forma. Não tem como
ser mais seguro que isso.
<!--
vim:spelllang=pt:
-->

1
aprendi-na-marra/src/programacao/controle-de-versao.md

@ -0,0 +1 @@
# Controle de Versões

1
aprendi-na-marra/src/programacao/controle-de-versao/gerrit.md

@ -0,0 +1 @@
# Gerrit É Uma Cagada

1
aprendi-na-marra/src/programacao/controle-de-versao/git-flow.md

@ -0,0 +1 @@
# Git-Flow É o Caminho

1
aprendi-na-marra/src/programacao/controle-de-versao/sempre-use-scv.md

@ -0,0 +1 @@
# Sempre Use Um Controle de Versão

1
aprendi-na-marra/src/programacao/controle-de-versao/um-commit.md

@ -0,0 +1 @@
# Um Commit Por Alteração

1
aprendi-na-marra/src/programacao/documentacao.md

@ -0,0 +1 @@
# Documentando Seu Código

1
aprendi-na-marra/src/programacao/documentacao/documentacao-com-e.md

@ -0,0 +1 @@
# Se A Documentação de uma Função Tem "E", Está Errado

1
aprendi-na-marra/src/programacao/documentacao/documentacao-e-contrato.md

@ -0,0 +1 @@
# A Documentação de uma Função É o Seu Contrato

1
aprendi-na-marra/src/programacao/documentacao/documente.md

@ -0,0 +1 @@
# Documentação É Uma Carta de Amor Ao Seu Futuro Eu

1
aprendi-na-marra/src/programacao/documentacao/linguagens-com-documentacao.md

@ -0,0 +1 @@
# Boas Linguagens Tem Documentação Embutida

8
aprendi-na-marra/src/programacao/index.md

@ -0,0 +1,8 @@
# Programação
Eu sou desenvolvedor de software. Eu escrevo código. E aqui estão algumas das
coisas que eu aprendi sobre o assunto.
<!--
vim:spelllang=pt:
-->

1
aprendi-na-marra/src/programacao/organizacao.md

@ -0,0 +1 @@
# Organização de Projetos

1
aprendi-na-marra/src/programacao/organizacao/bibliotecas.md

@ -0,0 +1 @@
# Crie Bibliotecas

1
aprendi-na-marra/src/programacao/organizacao/notas-em-papel.md

@ -0,0 +1 @@
# Notas em Papel São Bem Úteis

1
aprendi-na-marra/src/programacao/organizacao/organizacao-de-projetos.md

@ -0,0 +1 @@
# Organize Seu Código por Tipo de Dado, Não Por Função

1
aprendi-na-marra/src/programacao/programando.md

@ -0,0 +1 @@
# Escrevendo Código

1
aprendi-na-marra/src/programacao/programando/comece-idiota.md

@ -0,0 +1 @@
# Comece de Forma Idiota

1
aprendi-na-marra/src/programacao/programando/deixe-explodir.md

@ -0,0 +1 @@
# É Melhor Deixar A Aplicação Explodir Do Que Fazer Nada

1
aprendi-na-marra/src/programacao/programando/facil.md

@ -0,0 +1 @@
# Resista À Tentação do Fácil

1
aprendi-na-marra/src/programacao/programando/fora-do-projeto.md

@ -0,0 +1 @@
# Não Mexa Em Coisas Fora do Seu Projeto

1
aprendi-na-marra/src/programacao/programando/jogar-fora.md

@ -0,0 +1 @@
# Esteja Pronto Para Jogar Código Fora

1
aprendi-na-marra/src/programacao/programando/lide-com-erro.md

@ -0,0 +1 @@
# Se Você Sabe Como Lidar Com O Erro, Lide

1
aprendi-na-marra/src/programacao/programando/mudancas-de-interface.md

@ -0,0 +1 @@
# Cuidado Com as Alterações de Interface

1
aprendi-na-marra/src/programacao/programando/otimizacao.md

@ -0,0 +1 @@
# Otimização É Para Compiladores

1
aprendi-na-marra/src/programacao/programando/parametros-booleanos.md

@ -0,0 +1 @@
# Não Use Booleanos Como Parâmetros

1
aprendi-na-marra/src/programacao/programando/problemas-futuros.md

@ -0,0 +1 @@
# Resolver O Futuro Gera Problemas Futuros

1
aprendi-na-marra/src/programacao/programando/rode-localmente.md

@ -0,0 +1 @@
# Se Não Roda No Seu Computador, Está Errado

1
aprendi-na-marra/src/programacao/programando/solucao-permanente.md

@ -0,0 +1 @@
# Nada Mais Permanente Que Uma Solução Temporária

1
aprendi-na-marra/src/programacao/programando/tipos-de-dados.md

@ -0,0 +1 @@
# Tipos Dizem O Que Seus Dados São

1
aprendi-na-marra/src/programacao/programando/unidades.md

@ -0,0 +1 @@
# Unidades Fazem as Coisas Mais Claras

1
aprendi-na-marra/src/programacao/programando/use-estruturas.md

@ -0,0 +1 @@
# Se Os Seus Dados Tem Estrutura, Use Uma Estrutura

1
aprendi-na-marra/src/programacao/programando/use-timezones.md

@ -0,0 +1 @@
# Sempre Use Timezones nas Datas

1
aprendi-na-marra/src/programacao/programando/use-utf8.md

@ -0,0 +1 @@
# Sempre Use UTF-8 nas Strings

1
aprendi-na-marra/src/programacao/rodando.md

@ -0,0 +1 @@
# Fazendo As Coisas Andarem

1
aprendi-na-marra/src/programacao/rodando/adicione-e-remova.md

@ -0,0 +1 @@
# Uma Versão para Adicionar, Uma Para Remover

1
aprendi-na-marra/src/programacao/rodando/arquivo-de-config.md

@ -0,0 +1 @@
# O Arquivo de Config É Seu Amigo

1
aprendi-na-marra/src/programacao/rodando/composicao-de-aplicacoes-idiota.md

@ -0,0 +1 @@
# Mesmo Para Composição de Aplicações, Comece Idiota

1
aprendi-na-marra/src/programacao/rodando/logs-para-eventos.md

@ -0,0 +1 @@
# Logs São Para Eventos, Não Interface Com o Usuário

1
aprendi-na-marra/src/programacao/rodando/monitoramento.md

@ -0,0 +1 @@
# Aprenda a Monitorar

1
aprendi-na-marra/src/programacao/rodando/opcoes-de-linha-de-comando.md

@ -0,0 +1 @@
# Opção de Linha de Comando São Esquisitas Mas Úteis

1
aprendi-na-marra/src/programacao/rodando/transparencia.md

@ -0,0 +1 @@
# Seja Transparente Com o Usuário

1
aprendi-na-marra/src/programacao/testes.md

@ -0,0 +1 @@
# Testes De Software

1
aprendi-na-marra/src/programacao/testes/linguagens-com-testes.md

@ -0,0 +1 @@
# Boas Linguagens Tem Testes Embutidos

1
aprendi-na-marra/src/programacao/testes/testes-apis.md

@ -0,0 +1 @@
# Testes Geram Uma API Melhor

1
aprendi-na-marra/src/programacao/testes/testes-codigo-morto.md

@ -0,0 +1 @@
# Testar Toda Função Gera Código Morto

1
aprendi-na-marra/src/programacao/testes/testes-de-integracao.md

@ -0,0 +1 @@
# Testes Unitários São Bons, Testes de Integração São Mais Melhores

1
aprendi-na-marra/src/programacao/testes/testes-na-linha-de-comando.md

@ -0,0 +1 @@
# Crie Testes Que Você Saiba Rodar Na Linha de Comando

1
aprendi-na-marra/src/programando/rodando/composicao-de-aplicacoes.md

@ -0,0 +1 @@
# Não Apenas Composição de Funções, Mas Composição de Aplicações

1
aprendi-na-marra/src/times/a-ferramenta-certa-obvia.md

@ -0,0 +1 @@
# "A Ferramenta Certa" É Mais Óbvia Do Que Você Pensa

1
aprendi-na-marra/src/times/a-ferramenta-certa.md

@ -0,0 +1 @@
# "A Ferramenta Certa" Tem Sempre Algo Por Trás

1
aprendi-na-marra/src/times/cargo-cult.md

@ -0,0 +1 @@
# Entenda e Afaste-se do "Cargo Cult"

1
aprendi-na-marra/src/times/discuta-com-o-time.md

@ -0,0 +1 @@
# Alterações Globais Devem Ser Discutidas com o Time

1
aprendi-na-marra/src/times/estilo-de-codigo-google.md

@ -0,0 +1 @@
# ... A Não Ser Que Seja o Estilo Google

1
aprendi-na-marra/src/times/estilo-de-codigo.md

@ -0,0 +1 @@
# Estilo de Código: Siga-o!

1
aprendi-na-marra/src/times/estilos-em-revisao-de-codigo.md

@ -0,0 +1 @@
# Revisão de Código Não É Para Validar Estilo

1
aprendi-na-marra/src/times/formatador-de-codigo.md

@ -0,0 +1 @@
# Formatadores de Código São Ok, Mas Nenhuma Bala de Prata

1
aprendi-na-marra/src/times/hero-projects.md

@ -0,0 +1 @@
# Hero Projects: Você Vai Ter Que Fazer

1
aprendi-na-marra/src/times/index.md

@ -0,0 +1 @@
# Comunidades e Times

1
aprendi-na-marra/src/times/linguagens-tem-mais.md

@ -0,0 +1 @@
# Uma Linguagem É Mais Que Uma Linguagem

4
things-i-learnt/src/disclaimer.md

@ -1,9 +1,9 @@
# Disclaimer
There is one magical thing you need to know when reading this book: It's all
personal opinion
personal opinion.
A lot of stuff I'm going to discuss throughout this book will come directly
A lot of stuff I'm going to comment throughout this book will come directly
from my personal experience in several projects -- system applications, web
backend, embedded, mobile, stream processing -- in several different languages
-- C, C++, Python, Java, Clojure, Rust. And, because it comes from personal

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save