- Ferramentas para desenvolvedores são mais difíceis porque precisam projetar não só a lógica que o computador vai executar, mas também o modelo mental que outras pessoas vão entender e usar
- Um onboarding rápido não é um recurso extra, e sim algo mais próximo do próprio produto; é preciso reduzir o atrito de configuração, token de API e primeira execução para que a pessoa consiga testar no notebook em poucos minutos
- Em vez de longas explicações sobre conceitos centrais, usuários aprendem padrões mais rápido mexendo em exemplos que funcionam, e quanto mais pontos de partida próximos do problema houver, maiores as chances de sucesso
- Mensagens de erro, número de conceitos, nomenclatura, forma de configuração, padrões, mágica e açúcar sintático mudam o caminho de sucesso do usuário, então é preciso um design legível e personalizável
- Uma boa experiência para desenvolvedores não é simplesmente reduzir funcionalidades, mas manter o alcance do que se pode construir enquanto reduz drasticamente a complexidade que é preciso conhecer
Código para humanos também lida com modelos mentais
- Escrever código para computadores é pegar grandes objetivos de negócio e quebrá-los em instruções lógicas que o computador consiga seguir
- Em códigos manipulados diretamente por pessoas, como frameworks, bibliotecas, APIs, SDKs, DSLs, DSLs embutidas e linguagens de programação, não basta que sejam executáveis
- Esse tipo de código precisa, ao mesmo tempo, instruir o computador e considerar como o usuário vai ler e entender aquele código
- Projetar ferramentas para desenvolvedores exige não só ciência da computação, mas também uma compreensão psicológica de como o usuário raciocina
A experiência inicial é o próprio produto
- O feedback sobre ferramentas para desenvolvedores costuma vir principalmente de usuários avançados que usam o produto com frequência
- Usuários que travam logo no começo não deixam feedback, o que cria um viés de sobrevivência
- Assim como produtos de consumo otimizam o funil de onboarding, ferramentas para desenvolvedores também devem tratar o caminho até a primeira execução como parte central do produto
- Vale a pena até mudar a própria estrutura do produto para acelerar o onboarding
- eliminar configurações obrigatórias
- tornar a configuração de tokens de API extremamente simples
- reduzir o atrito inicial
- permitir que a pessoa use o produto no próprio notebook em poucos minutos
- Num ambiente com ferramentas para desenvolvedores em excesso, é difícil esperar que alguém tenha energia ou paciência para entender profundamente a diferença entre pacotes NPM de cache LRU
Exemplos ensinam mais rápido do que conceitos centrais
- Diferentemente de computadores, que seguem instruções rígidas, humanos são fortes em reconhecimento de padrões
- Muita documentação de ferramentas para desenvolvedores começa explicando o modelo de dados central, relações, conceitos atômicos, configuração e forma de execução, mas pessoas aprendem melhor alterando casos que já funcionam e observando o resultado
- Vários exemplos podem ser mais úteis do que uma explicação de 5.000 palavras sobre “core concepts”
- usuários aprendem como a ferramenta funciona ao observar exemplos
- quem já tem um problema a resolver pode encontrar um ponto de partida suficientemente próximo
- quanto mais pontos de partida houver, maior a chance de encontrar um exemplo perto do que precisa
Empurrando o usuário para o poço do sucesso
- O estado padrão da programação se parece mais com ficar corrigindo algum tipo de erro o tempo todo
- Usuários podem gastar a maior parte do tempo com a ferramenta tentando descobrir “o que não está funcionando”
- Quando desenvolvedores chegam ao sucesso mais rápido, gostam da ferramenta; quando continuam travando em erros, tendem a culpar a ferramenta
- Todo erro é uma oportunidade de devolver o usuário ao caminho feliz
- incluir snippets de código na mensagem de exceção
- mostrar avisos úteis quando houver chance de o usuário fazer algo estranho
- fornecer as ações necessárias para que o usuário consiga ter sucesso
Reduzindo a sobrecarga conceitual
- Cada novo conceito que precisa ser entendido antes de usar a ferramenta vira um ponto de atrito
- Dá para aceitar 2 ou 3 conceitos, mas pouca gente vai querer aprender 8 conceitos novos
- No Kubernetes, nem todos os conceitos são necessários no começo, mas quanto mais conceitos novos aparecem, maior fica a carga
- Há algo de elegante em frameworks poderosos que funcionam com apenas 3 a 5 conceitos
- Quando alguém usa React pela primeira vez, depois de uma ou duas horas e de passar a ladeira conceitual inicial, pode surgir a sensação de que dá para construir estruturas grandes com poucos blocos simples
- O objetivo não é apenas reduzir a quantidade de conceitos, mas diminuir os conceitos que o usuário precisa conhecer sem reduzir o alcance do que pode ser construído
- Ferramentas excelentes conseguem reduzir 90% da complexidade mantendo a mesma capacidade
- E uma ferramenta que reduz 90% da complexidade e só perde 10% da capacidade ainda pode ser muito boa
O princípio conceitual do pato
- Se dentro de um framework existe um elemento que recebe valores e calcula novos valores, geralmente é melhor chamá-lo de function do que inventar nomes como “compute node”, “valuator” ou “frobniscator”
- A ideia de que, se algo anda como pato e grasna como pato, provavelmente é um pato, também pode ser aplicada ao design conceitual
- Mesmo que haja pequenas diferenças ou que os valores sejam armazenados em cache, se estiver perto o suficiente de uma function, dá para chamá-la assim
- Usar termos já existentes conecta o usuário a modelos mentais que ele já possui e reduz muito o quanto precisa ser explicado
Tornando programável
- Usuários fazem coisas inesperadas com codebases e podem colocar elementos do framework dentro de
for-loop, funções ou outras estruturas - Por isso, quase tudo em um framework precisa ser programável
- Algumas direções de design relacionadas se conectam entre si
- permitir chamada direta no código, sem passar por CLI
- reduzir arquivos de configuração e trocar por SDK ou API
- em vez de permitir criar apenas um, parametrizar para permitir criar n
- Esse tipo de design pode levar usuários a descobrir novos casos de uso
- Aproveitar o desejo de “hackear” em cima do framework pode gerar alguma confusão, mas também descobertas inesperadas
É preciso cuidado com mágica, padrões e açúcar sintático
- Suponha que exista uma função
run_notebookpara executar um Jupyter notebook na nuvem, e que o usuário precise especificar qual imagem de contêiner usar - Há várias escolhas possíveis
- exigir sempre o argumento
image=... - definir uma imagem padrão com a maior parte das bibliotecas de ciência de dados instaladas e permitir override
- inspecionar o código da célula e escolher a imagem de forma “mágica” com base nas dependências necessárias
- além da abordagem mágica, também permitir que o usuário escolha uma imagem específica
- exigir sempre o argumento
- Para reduzir a quantidade de entrada exigida e cobrir a faixa mais ampla de casos de uso, a última opção pode parecer a melhor
- Mas, tirando a primeira, todas deixam problemas
- a mágica quebra em algumas situações
- quem lê código que depende de padrões pode não perceber que existe possibilidade de personalização
- A menos que o padrão se aplique em mais de 97% dos casos e a mágica acerte mais de 99% das vezes, é preciso muito cuidado
- Programar não é golfe, e o trabalho de quem fornece a ferramenta não é apenas minimizar a quantidade de código que o usuário escreve
- Perl foi fortemente otimizada para código curto, mas programas podiam parecer uma sequência de caracteres especiais; Python, mesmo com código 50% mais longo, era mais fácil de ler e entender
- As pessoas leem código 10 vezes mais do que escrevem, então legibilidade importa
- Açúcar sintático deve ser avaliado pelo mesmo critério
- pode haver vontade de criar sintaxe especial para casos de uso comuns
- mas isso pode enfraquecer a consistência e tornar menos claro como personalizar
- se o açúcar sintático não se aplicar em mais de 99% dos casos, talvez seja melhor não introduzi-lo
Princípios de design para quem vai usar pela primeira vez
- Ainda há muitos problemas de design ao escrever código para humanos
- a maioria das coisas deveria ser imutável, mas não todas
- evitar scaffolding, ou seja, geração de código
- tornar o loop de feedback extremamente rápido
- permitir que usuários lidem facilmente com funcionalidades que serão descontinuadas
- usar testes automatizados nos snippets de código da documentação e dos exemplos
- Projetar a experiência do primeiro usuário é parecido com produzir uma música pop
- Mesmo ouvindo a música mil vezes, o produtor precisa imaginar, na 999ª vez, como ela vai soar para quem está ouvindo pela primeira vez
- Em ferramentas para desenvolvedores, para quem já criou aquilo repetidas vezes, é muito difícil imaginar a experiência de um usuário de primeira viagem
1 comentários
Comentários do Hacker News
Cada pessoa aprende de um jeito diferente. No meu caso, antes de entrar em exemplos, preciso primeiro dos conceitos centrais. Isso vale ainda mais quando os conceitos centrais não são muito simples.
Muitos tutoriais parecem uma forma de montar Lego de mãos dadas. É algo como: “Aqui estão as peças de Lego; se você me acompanhar enquanto faço um projetinho de brinquedo, até o fim do dia vai saber mexer com Lego”.
Esse método não funciona bem para mim. Quero saber como e por que as decisões são tomadas, e quero enxergar pela perspectiva do autor. Quero entender qual é a sensação de cada peça de Lego, como elas se conectam entre si e como se chega a um determinado design.
Seguir um tutorial sem ao menos uma explicação mínima dos conceitos de alto nível parece engenharia reversa de algo que não deveria exigir isso. Quando vejo uma nova biblioteca ou framework, costumo ler o texto de introdução e pular os exemplos de código de “primeiros passos”. Em geral, há mais discussão conceitual nas seções “avançadas”, então começo por elas; depois vou para a referência da API para entender as interfaces importantes; e, por fim, volto aos exemplos básicos de código do início do tutorial.
Hoje em dia, com muito mais frequência, simplesmente mergulho e começo a trabalhar direto pelos exemplos, e sinto que sou mais produtivo assim. Em certo grau, é uma questão de confiança. É acreditar que as pessoas que criaram software de qualidade pensaram o suficiente para tornar as interfaces fáceis de entender nos casos de uso comuns, sem que eu precise escavar fundo nos detalhes internos.
Claro que encontro com frequência obstáculos que exigem ir mais a fundo. Mas essas situações acontecem porque houve outras 10 coisas que consegui superar com sucesso só com uma impressão superficial. Então, quando de fato preciso me aprofundar, geralmente não considero isso perda de tempo.
Esse tipo de ferramenta cria uma determinada estrutura de pastas, arquivos de template e ferramentas pré-configuradas. Se eu não entendo imediatamente, em alto nível, o que os arquivos gerados fazem e por que foram criados daquele jeito, fico desconfortável com tanta mágica que não compreendo.
Sempre que algo novo aparece, preciso de uma introdução de alto nível que explique seu propósito conectando-o a conceitos que já conheço. Não fico confortável lidando com uma caixa-preta mágica antes de entender, ao menos por alto, as principais interfaces dessa caixa-preta. Por exemplo, se eu fosse aprender create-react-app do zero, provavelmente começaria logo a investigar o propósito das ferramentas que ele configura, como Babel ou ESLint.
Só alguns anos depois, vendo muitos bons exemplos práticos, é que entendi o que os conceitos queriam dizer. Depois dessa percepção, ajustei meu modo de aprender.
Primeiro passo uma vista de olhos pelos conceitos centrais; depois tento vários exemplos até entender por que aqueles conceitos são necessários; então leio os conceitos centrais com atenção para eliminar os casos de borda que os exemplos ingênuos deixaram de fora.
Dito isso, acho que começar por exemplos pode ajudar no bom design de APIs. Se você projeta uma API com “conceitos centrais primeiro”, é fácil acabar com uma API que só pode ser usada depois que a pessoa entende esses conceitos centrais, o que não é bom para usuários ocasionais.
Como é típico do estilo hacker, não havia citações. Vi só um pouco de pedagogia, mas é uma área enorme e madura, que deriva princípios modernos da psicologia da experiência de Dewey e Piaget. Há muito mais a dizer do que caberia não só em um post de blog, mas até em uma seção de um post.
O maior problema, como você apontou, é que as pessoas são diferentes. O problema seguinte é que nem sabemos ao certo por que essas diferenças surgem, nem quão estáveis elas são ao longo do tempo. O texto em si é bem escrito e explora bem a praticidade de uma estratégia educacional específica, mas eu gostaria que tivesse um pouco mais de humildade.
Há menos de duas semanas houve um texto parecido: https://news.ycombinator.com/item?id=41566097
Escrever para pessoas, no fim das contas, se resume a duas habilidades: empatia e escrita.
Há uma grande diferença entre escrever um pouco de código e escrever uma aplicação ou um produto. Este texto também é, no fim das contas, sobre isso, só que de forma menos explícita. A empatia é importante porque cria a diferença entre egocentrismo e orientação para o externo.
Um desenvolvedor egocêntrico se preocupa principalmente com facilidade, conveniência, vaidade de código e outros critérios subjetivos. No fim, só leva em conta o próprio esforço de comunicação. Um desenvolvedor orientado para o externo se preocupa principalmente com arquitetura e documentação, porque vê o sucesso como dependente de como outras pessoas recebem o que ele produziu.
Simplicidade é mais importante que facilidade. Isso porque um desenvolvedor orientado para o externo não consegue ler a mente dos outros nem saber o que eles vão achar fácil, mas sabe reduzir o número de etapas e manter o código pequeno.
Do ponto de vista do produto como um todo, escrever uma aplicação não é diferente, dentro do cérebro, de escrever um ensaio, um artigo ou um livro. O essencial é organização e função. O código vem depois, como as palavras na página. Quem só escreve trechos de código não desenvolve a habilidade de organização de nível mais alto que une tudo em um conjunto.
É por isso que detesto frameworks. Frameworks tiram dos desenvolvedores a prática necessária para escrever software original e, como resultado, os impedem de desenvolver habilidades de organização. A própria pessoa não consegue enxergar isso, mas para quem consegue é uma lacuna enorme e extremamente clara.
Mas agora as outras pessoas precisam aprender as abstrações deles e, nessa medida, ficam mais distantes dos conceitos de base. Isso pode tornar mais difícil adquirir as habilidades essenciais necessárias para ir além do framework. Tive essa sensação ao aprender Rails e, no fim, percebi que ele escondia coisas demais, abandonei e fui tentar fazer do zero.
Perceber que isso é uma habilidade completamente diferente foi algo que abriu meus olhos. Por assim dizer, agora se tornou uma incógnita conhecida.
Como este código vai parecer para alguém com o chefe no seu pescoço, ou para alguém corrigindo um problema de produção às 2 da manhã? Você não sabe o valor dessa resposta até realmente precisar dela. E, no momento em que precisa, acaba pagando caro por ela. Isso se conseguir encontrar alguém que saiba fazer isso. Essas pessoas são raras.
Não concordo com a frase “humanos aprendem por exemplos, não por conceitos centrais”. Talvez seja preciosismo, mas nem todos os humanos funcionam assim.
Pessoas que preferem ir do geral para o concreto já são, em grande parte, ignoradas no ensino fundamental e médio, e só talvez passem a se encaixar melhor no ensino superior. Elas já são alienadas o suficiente; não há necessidade de negar até a existência delas.
Eu não entendia as nuances de quando fazer o quê, o que precisava ser feito exatamente ao mesmo tempo e o que precisava vir logo em seguida. Então o pai dela explicou brevemente o que a embreagem de fato faz e como a conexão entre as rodas e o motor afeta os dois lados.
Naquele instante entendi, e não precisei mais receber instruções sobre o que fazer em situações específicas. Uns 20 minutos depois, eu já conseguia sair e dirigir usando o freio de mão em uma subida inclinada para trás, algo considerado uma das partes mais difíceis do câmbio manual. Para algumas pessoas, entender como as coisas funcionam a partir de primeiros princípios é muito mais útil, e acho que há muitos desses “alguns” entre engenheiros de software.
Se há algo surpreendente em um exemplo, isso significa que meu modelo ainda não está completo. Ou então que o exemplo está errado.
Em vez de “isto é o que estamos tentando alcançar, isto funciona assim, e nós fazemos assim”, o que chega ao profissional é sempre apenas “nós fazemos assim”. Com uma mudança mínima, já não dá para raciocinar, ajustar e resolver o problema.
Até existe alguma documentação para tarefas realizadas com frequência, mas em geral está desatualizada ou incompleta. Como não é uma wiki, qualquer pessoa não pode simplesmente corrigir a qualquer momento; e, para corrigir a documentação, é preciso passar por um processo irritante, então ela acaba não sendo atualizada. Pensando bem, é bem parecido com a época em que eu estava no Exército.
Ainda estou passando por isso agora, ao reservar um tempo para aprender Drizzle ORM. Todos os primeiros materiais que encontrei eram “seis exemplos de queries”, e fiquei frustrado por não saber por que aquela sintaxe era usada e quais eram as outras opções. Eu fecho esse tipo de material e fico muito mais confortável com meu jeito de ler todas as páginas da documentação antes de fazer alguma coisa.
Não sei se ainda consigo fazer isso em tempo real. Esse método consome muitos ciclos de pensamento, então hoje combina mais com meu ritmo ler textos ou pausar vídeos para processar.
Muitas vezes acabei ensinando, na hora, pessoas que ainda não tinham entendido. Quando se tem uma teoria sobre um sistema, dá para responder perguntas que um colega que mal passou da memorização simples não consegue responder.
É uma frase de Code Complete: “Uma pequena parte do trabalho de programação é escrever programas para que computadores possam lê-los; a parte maior é escrevê-los para que outros seres humanos possam lê-los.” p. 733
Ficou na minha memória por quase 20 anos
É uma frase do prefácio da primeira edição de Structure and Interpretation of Computer Programs, de Abelson e Sussman, e precede Code Complete em 10 anos
É uma máxima que tento seguir, mas, estranhamente, os empregadores parecem sempre insistir na parte que o computador executa
É um pouco tangencial, mas, alguns dias atrás, enquanto eu fazia um jogo em Unity, fiquei pensando se as IDEs realmente não evoluíram muito nos últimos 10~20 anos
O IntelliSense básico certamente melhorou bastante, mas, fora alguns outros detalhes menores, o conceito inteiro de programar parece quase igual ao de antes
A maior mudança positiva está fora do editor. O acesso a bibliotecas e documentação ficou muito mais fácil, há uma quantidade enorme de perguntas e respostas de usuários, e também surgiram novas ferramentas como o ChatGPT, que às vezes reúnem essas respostas e dão uma resposta plausível
Mas, no geral, o ato de escrever código parece estagnado. Então, por enquanto, parei um pouco o trabalho no jogo e estou fazendo alguns experimentos. Não quero criar uma nova linguagem; quero passar para o computador todo trabalho braçal possível e me concentrar na criação
As três primeiras coisas que quero testar são estas: por que eu deveria me preocupar com pequenos detalhes da linguagem, como parênteses ou terminadores? A ferramenta não poderia autocompletar isso? Modificadores como cadeias de acesso private-public ou unsafe também não poderiam ter o conjunto mais eficiente determinado automaticamente pela ferramenta? Quando estou focado em uns 5 métodos que interagem entre si, quero vê-los todos numa só tela, sem abrir várias janelas e brigar com os sliders horizontal/vertical do VS. Se eu criei um HashSet e depois preciso trocar para Dictionary ou Tuple, queria que simplesmente trocasse e mostrasse só os pontos que exigem decisão, para eu aprovar ou corrigir manualmente. No Unity, também queria poder clicar em um método ou conjunto de dados e mandar convertê-lo para um Burst Job e o conjunto de NativeData associado
Mas, no fim, tudo é abstração, e estamos apenas escrevendo comandos para que uma máquina muito burra calcule dados
Você perguntou se a ferramenta não poderia autocompletar parênteses ou terminadores, mas o computador é algo realmente simples, e a linguagem de programação é um canal para transmitir o que está na sua mente. Esses delimitadores são tão importantes quanto as palavras-chave da linguagem, porque fazem parte das regras. Para autocompletá-los, seriam necessárias mais regras e mais delimitadores
Se você quer ver vários métodos que interagem entre si em uma só tela, existem Vim e Emacs, ou IDEs Smalltalk como Pharo
Transformações de dados podem ser feitas com macros do Vim e do Emacs. Mas a verdade é que a codificação dos dados é muito importante. Para o computador, tudo são bits; nós é que atribuímos significado a esses bits e criamos regras para manipulá-los de acordo com esse significado. Para mudar de forma de um conjunto de regras para outro, são necessárias mais regras
Recomendo experimentar ambientes de programação ao vivo. Coisas como o SLIME do Common Lisp, o Pharo do Smalltalk e o inspetor web do JavaScript. É como trabalhar em um navio no meio do mar, em vez de colocar um navio em terra firme e imaginar como seria navegar
A parte mais difícil da programação é pensar e aprender. Digitar mais rápido não ajuda tanto assim
Por exemplo, ao escrever um programa em C, dava para fazer “f” se expandir para “for (=; <=; ++) {;}” ou para o estilo de indentação de sua preferência
Muitos editores de programação modernos também oferecem configurações semelhantes, mas infelizmente, em muitos casos, o procedimento é mais complicado do que era há muito tempo
Se a linguagem de programação tiver uma sintaxe verbosa, acho necessário dedicar tempo a definir templates no editor para escrever rapidamente qualquer estrutura de programa com o mínimo de teclas possível
Questões como escolher entre HashSet, Dictionary e Tuple têm impacto de desempenho, e nem sempre fica claro, em termos abstratos, qual deve ser usado. Em linguagens explícitas como Java, e provavelmente C# também, deve ser possível refatorar para que chamadas de método recebam outro tipo. Então você altera um método e refatora todas as chamadas dele
Experimentei Gemini Pro e ChatGPT o1, e ambos são realmente ruins programando em Python e JavaScript. Escrevem código com bugs e, ao tentar corrigir um bug, frequentemente introduzem outro. Em ambos, a sensação é de que se apressam para responder em vez de pensar nos requisitos. Acho que ainda estamos um pouco longe de ferramentas que “leiam nossa mente” do jeito que queremos ou entendam o que é importante e o que não é
Algo que pode ser ainda pior são os dados de treinamento. Como a maior parte do código é feita por programadores abaixo da média e medianos, essas ferramentas acabam adotando os padrões de pensamento de um programador médio. Mesmo que fossem treinadas apenas com código da mais alta qualidade, não está claro se a maioria dos programadores conseguiria dar os prompts corretos. Então, se você vem programando há 10~20 anos, há uma boa chance de ficar sempre um pouco decepcionado com ferramentas das quais espera magia instantânea
Ainda assim, ferramentas de análise estática não baseadas em IA já são excelentes há muito tempo e vão melhorar ainda mais. Ao adicionar IA a elas, podem ficar ainda melhores. Se você pensar nas ferramentas não como artistas a quem se entrega uma especificação para receber um resultado decente, mas como algo que ajuda você a ser o artista, acredito que possa ter uma ótima experiência
Também pode ser interessante experimentar dizer à IA o que você gostaria que o editor fizesse mais e pedir ajuda para configurá-lo. Há muitas ferramentas não baseadas em IA em forma de plugins. Usar um grande modelo de linguagem para escolher plugins que se encaixem no seu modo de vida pode ser o mais eficiente
https://haystackeditor.com/
Ainda não usei, mas pretendo experimentar
O título do texto é discutível. Código é escrito exclusivamente para humanos. O computador não precisa de “código”, especialmente de código de alto nível. Para o computador, instruções em linguagem de máquina bastam
Escrevemos código porque instruções em linguagem de máquina são difíceis demais para humanos escreverem, e ainda mais difíceis de ler
Não devemos pensar em código como uma forma de interagir com o computador. Código é uma forma de os humanos formalizarem pensamentos, tornando-os tão não ambíguos que até uma máquina consiga segui-los
Divulgando de forma altruísta um post de blog que escrevi e compartilhei na semana passada
Move Fast & Document Things [1]
A intenção não era escrever um texto filosófico, mas compartilhar dicas práticas sobre como nossa pequena equipe [2] impõe uma cultura de escrita de código para nós mesmos e uns para os outros, não por meio de automação ou IA, mas por revisões profundas e difíceis
Amigos pessoais que são líderes de engenharia em outras organizações disseram todos: “Nós fazemos exatamente a mesma coisa, mas você realmente colocou isso por escrito”. Se tiver sido útil, peço uma recomendação
[1] https://olshansky.substack.com/p/move-fast-and-document-thin...
[2] https://github.com/pokt-network/poktroll/graphs/contributors
“Livros e tutoriais demais de programação seguem a ideia de ‘vamos construir uma casa do zero, tijolo por tijolo’, mas o que eu quero é ‘aqui está uma casa funcionando; vamos mudar alguma coisa e ver o que acontece’”
Aprendi programação por conta própria desse jeito. Passei anos usando bem programas pequenos, simples e meio ruins
Mais tarde, descobri que isso não me tornava adequado para vagas melhores de desenvolvimento de software, porque eu não tinha nenhum conhecimento básico de design de software, linguagens de programação ou computadores. Como não aprendi do jeito chato, foi uma experiência de humildade sair de entrevistas percebendo o quanto eu não sabia
É preciso sempre ler a documentação inteira e sempre aprender os fundamentos
Todo o meu código é escrito para humanos
Seja esse humano eu mesmo, seja alguma pobre pessoa que precise entender minhas intenções daqui a alguns anos
Não acho que escrever código em si seja difícil. O que mostra talento é raciocinar sobre o problema de forma abrangente, colaborar com outras partes interessadas para descobrir o melhor caminho e conduzi-las por ele, aprender habilidades especializadas como matemática nova ou convenções do setor, conceber algoritmos eficientes e comunicar a estrutura e os padrões do programa de modo que tenham limites claros e elegantes
No fim, muita coisa depende de comunicação e clareza
Uma grande parte deste texto é sobre documentação, e teria ajudado muito se tivesse referenciado o modelo 4doc: https://docs.divio.com/documentation-system/
Basicamente, a ideia é não fornecer apenas documentação de referência, mas também documentação de uso. E colocá-la em primeiro lugar, porque geralmente é a parte de toda a documentação que os usuários querem ver primeiro
Claro, isso é em geral; eu costumo ir direto para o material de referência, mas nem sempre
Isso não quer dizer que o 4doc seja uma solução universal ou uma lei natural. Hillel Wayne também trata bem dos problemas dele aqui: https://www.hillelwayne.com/post/problems-with-the-4doc-mode...