Artigo original: How to think like a programmer — lessons in problem solving

Escrito por: Richard Reis

Tradução em português europeu

Se tens interesse em programação, é possível que já tenhas visto esta citação:

"Toda a gente neste país deve aprender a programar um computador, porque ensina-te a pensar." — Steve Jobs

Também te deves ter questionado sobre o que é, exatamente, pensar como um programador e sobre como podes fazê-lo.

Essencialmente, trata-se de um modo mais eficiente de resolver problemas.

Nesta publicação, o meu objetivo é ensinar-te esse modo.

No final da publicação, ficarás a saber exatamente quais os passos a dar para ser um(a) melhor solucionador(a) de problemas.

Qual é a importância disso?

A resolução de problemas é a habilidade das habilidades.

Todos temos problemas. Grandes e pequenos. O modo como lidamos com eles é, por vezes, bem… bastante aleatório.

A não ser que tenhas um sistema, esta é a forma como provavelmente "resolves" os problemas (que é o que eu fazia quando comecei a programar):

  1. Tentar uma solução.
  2. Se não funcionar, tentar outra.
  3. Se também não funcionar, repetir o passo 2 até teres sorte.

Vejamos: por vezes, podes ter sorte. Esse, porém, é o pior modo de resolver problemas, além de ser um enorme desperdício de tempo.

A melhor forma envolve a) ter uma estrutura e b) praticá-la.

"Quase todos os empregadores dão prioridade a competências de resolução de problemas.

A resolução de problemas é, de maneira quase unânime, a qualificação mais importante procurada pelos empregadores… mais do que proficiência em linguagens de programação, depuração e design de sistemas.

Demonstrar pensamento computacional ou a capacidade de decompor problemas grandes e complexos é tão valioso (se não mais) como as competências técnicas necessárias para a vaga." — Hacker Rank (2018 Relatório de Competências do Programador)

Ter uma estrutura

Para encontrar a estrutura certa, segui o conselho no livro de Timothy Ferriss, "The 4-Hour Chef".

Levou-me a entrevistar duas pessoas muito interessantes: C. Jordan Ball (classificado em primeiro ou segundo em mais de 65 mil utilizadores no Coderbyte) e V. Anton Spraul (autor do livro "Think Like a Programmer: An Introduction to Creative Problem Solving").

Fiz-lhes algumas perguntas, e adivinha? As respostas de ambos foram bastante semelhantes!

Brevemente, também vais sabê-las.

Nota: isto não significa que fizeram tudo do mesmo modo. Toda a gente é diferente. Tu serás diferente. Se, no entanto, começares com princípios que todos concordamos que são bons, vais muito mais longe e mais rápido.

"O maior erro que vejo novos programadores a fazer é focarem-se em aprender a sintaxe em vez de aprender como resolver problemas." — V. Anton Spraul

Então, o que deves fazer quando te deparas com um novo problema?

Aqui estão os passos:

1. Compreender

Saber exatamente o que está a ser perguntado. A maioria dos problemas difíceis são difíceis porque não os compreendes (e por isso é que este é o primeiro passo).

Como saber quando compreendes um problema? Quando o conseguires explicar por palavras tuas.

Lembras-te de estar preso num problema, começas a explicá-lo e reparas, instantaneamente, em problemas na lógica que ainda não tinhas reparado?

A maioria dos programadores conhece essa sensação.

É por isso que devemos escrever o nosso problema, rabiscar um diagrama, ou falar com alguém sobre ele (ou alguma coisa… há quem utilize um pato de borracha).

"Se não conseguires explicar alguma coisa em termos simples, não a compreendes." — Richard Feynman

2. Planificar

Não avances logo para a resolução sem teres um plano (e esperar que por acaso consigas desenrascar-te pelo caminho). Planifica a tua solução!

Nada te pode ajudar se não conseguires escrever os passos exatos.

Em programação, isso quer dizer que não começas logo a resolver. Dá tempo ao teu cérebro para analisar o problema e processar a informação.

Para obter um bom plano, responde a esta questão:

"Dado um valor de entrada X, quais são os passos necessários para obter o resultado Y?"

Nota: os programadores têm uma ótima ferramenta para ajudá-los com isto… Comentários!

3. Dividir

Presta atenção. Este é o passo mais importante de todos.

Não tentes resolver um grande problema. Vais arrepender-te.

Em vez disso, divide o problema em problemas mais pequenos. Esses problemas são muito mais fáceis de resolver.

Depois, resolve cada sub-problema, um de cada vez. Começa pelo mais simples. Mais simples significa que sabes a resposta (ou estás perto de saber a resposta).

Depois disso, o mais simples significa que este sub-problema a ser resolvido não depende da resolução de outros.

Assim que resolveres todos os sub-problemas, junta os pontos.

Conectar todas as tuas "sub-soluções" vai dar-te a solução para o problema original. Parabéns!

Esta técnica é o pilar da resolução de problemas. Memoriza-a (relê este passo, caso necessário).

"Se conseguisses ensinar a todos os programadores principiantes uma habilidade de resolução de problemas, esta deveria ser a 'técnica de redução do problema'.
Por exemplo, vamos supor que és um novo programador e pedem-te para escrever um programa que lê dez números e tenta perceber qual deles é o terceiro maior. Para um novo programador, esta pode ser uma tarefa complicada, apesar de ser necessária apenas sintaxe de programação básica.
Se estiveres preso, deves reduzir o problema para algo mais simples. Em vez do terceiro maior número, por que não encontrar o maior de todos? Ainda muito complicado? Que tal encontrar o maior de apenas três números? Ou o maior de dois?
Reduz o problema até ao ponto em que sabes como resolvê-lo e escreve a solução. Depois, expande ligeiramente o problema e escreve de novo uma solução correspondente, continuando assim até chegares ao ponto inicial." — V. Anton Spraul

4. Sem saber o que fazer?

Neste momento, deves estar a pensar "Ei, Richard... isso é muito bonito, mas e se eu não souber o que fazer nem conseguir resolver um sub-problema?"

Em primeiro lugar, respira fundo. Em segundo, é justo.

No entanto, não te preocupes. Isto acontece a todos!

A diferença é que os melhores programadores/solucionadores de problemas ficam mais curiosos com bugs/erros do que irritados.

Na verdade, aqui estão três coisas para tentares fazer quando te deparares com um obstáculo:

  • Debug: vai passo a passo pela tua solução e tenta encontrar onde ocorreu o erro. Os programadores chamam a isto de debugging (na verdade, isto é tudo o que um debugger faz).
"A arte do debugging é compreender o que realmente indicaste ao teu programa para fazer e não o que pensas que mandaste fazer." — Andrew Singer
  • Reavaliar: Dá um passo atrás. Olha para o problema a partir de uma nova perspetiva. Existe alguma coisa que possa ser substituída por uma abordagem mais genérica?
"Por vezes, ficamos tão perdidos nos detalhes de um problema que ignoramos os princípios gerais que resolveriam o problema num nível mais genérico. […]
Um exemplo clássico disso é, claro, a soma de uma longa lista de números inteiros consecutivos, 1 + 2 + 3 + … + n, onde um Gauss muito jovem rapidamente reconheceu que era simplesmente n(n+1)/2, evitando assim o trabalho de ter de fazer a adição." — C. Jordan Ball

Nota: outro modo de reavaliar é começar de novo. Apaga tudo e começa de novo com a cabeça fresca. Estou a falar a sério. Vais ficar estupefacto com a eficácia disto.

  • Pesquisa: ahh, o velho amigo Google. Leste bem. Não interessa qual é o teu problema. Ele, provavelmente, já foi resolvido por alguém. Encontra essa pessoa/solução. Na verdade, faz isto mesmo que tenhas resolvido o problema! Podes aprender muito com as soluções de outras pessoas.

Atenção: não procures pela solução de um grande problema. Procura apenas soluções para os sub-problemas. Por quê? Porque a não ser que tenhas dificuldades (mesmo que poucas), não vais aprender nada. Se não aprenderes nada, desperdiçaste o teu tempo.

Praticar

Não fiques à espera de ser o(a) melhor ao fim de apenas uma semana. Se quiseres ser bom a resolver problemas, resolve muitos problemas!

Pratica. Pratica. Pratica. Será apenas uma questão de tempo até reconheceres que "este problema era facilmente resolvido com <inserir conceito aqui>".

Como praticar? Existem opções até dizer chega!

Puzzles de xadrez, problemas matemáticos, Sudoku, Go, Monopoly, jogos, e assim por diante.

Na realidade, um padrão comum entre pessoas bem sucedidas é o seu hábito de praticar "micro-resolução de problemas". Por exemplo, Peter Thiel joga xadrez e Elon Musk joga jogos.

"Byron Reeves disse que 'Se quiseres ver como se parecerá a liderança das empresas em três a cinco anos, observa o que está a acontecer nos jogos online.'
Avançamos até hoje. Elon [Musk], Reid [Hoffman], Mark Zuckerberg e muitos outros dizem que os jogos foram fundamentais no seu sucesso em criar as suas empresas." — Mary Meeker (2017 – Relatório de tendências na internet)

Isto quer dizer que devo dedicar-me apenas a jogar? Nem por isso.

O que são os jogos, contudo? É isso mesmo: resolução de problemas!

Então, o que deves fazer é encontrar um canal para praticar. Algo que te permita resolver muitos micro-problemas (idealmente, algo que gostes).

Por exemplo, eu gosto de desafios de programação. Todos os dias, tento resolver pelo menos um desafio (geralmente no Coderbyte).

Tal como disse, todos os problemas partilham padrões semelhantes.

Conclusão

É isto!

Agora, compreendes melhor o que significa "pensar como um programador".

Também sabes que a resolução de problemas é uma habilidade incrível para cultivar (a habilidade das habilidades).

Como se isto não fosse suficiente, repara como também sabes o que tens de fazer para praticar as tuas habilidades de resolução de problemas!

Ufa Muito interessante, certo?

Por fim, desejo que encontres muito problemas.

Leste bem. Pelo menos, agora saberás como resolvê-los! Além disso, vais aprender que, com cada solução, estás a evoluir.

"Assim que achares que navegaste um obstáculo com sucesso, outro emerge. Isso, porém, é o que torna a vida interessante.[…]
A vida é o processo de lidar com todos estes impedimentos — uma série de linhas fortificadas que temos de ultrapassar.
De cada vez, vais aprender alguma coisa.
De cada vez, vais desenvolver força, sabedoria e perspetiva.
De cada vez, um pouco mais de competição fica para trás. Até que tudo o que resta és tu: a melhor versão de ti próprio." — Ryan Holiday (O obstáculo é o caminho)

Agora, é hora de começar a resolver problemas!

Boa sorte!

Agradecimentos especiais a C. Jordan Ball e V. Anton Spraul. Todos os bons conselhos vieram deles.

Obrigado pela leitura! Se gostaste, compartilha este artigo com quem quiseres. Isso vai ajudar outras pessoas a verem a história.