Sobre o desenvolvimento de conhecimento de programação profunda

132

Ocasionalmente eu vejo perguntas sobre casos extremos e outros estranhos no Stack Overflow que são facilmente respondidos pelos gostos de Jon Skeet e Eric Lippert, demonstrando um profundo conhecimento da linguagem e suas muitas complexidades, < a href="http://blogs.msdn.com/b/ericlippert/archive/2011/06/30/following-the-pattern.aspx"> como este:

You might think that in order to use a foreach loop, the collection you are iterating over must implement IEnumerable or IEnumerable<T>. But as it turns out, that is not actually a requirement. What is required is that the type of the collection must have a public method called GetEnumerator, and that must return some type that has a public property getter called Current and a public method MoveNext that returns a bool. If the compiler can determine that all of those requirements are met then the code is generated to use those methods. Only if those requirements are not met do we check to see if the object implements IEnumerable or IEnumerable<T>.

É legal saber disso. Eu posso entender porque Eric sabe disso; ele está na equipe de compiladores, então ele tem que saber. Mas e aqueles que demonstram conhecimento tão profundo que não são de dentro?

Como meros mortais (que não estão no time de compiladores C #) descobrem coisas assim?

Especificamente, existem métodos que essas pessoas usam para sistematicamente erradicar esse conhecimento, explorá-lo e internalizá-lo (torná-lo seu próprio)?

    
por Robert Harvey 11.07.2011 / 22:34
fonte

10 respostas

165

Primeiramente, obrigado pelas palavras amáveis.

Se você deseja obter um conhecimento profundo de C #, é sem dúvida uma vantagem ter a especificação da linguagem, dez anos de notas de design, o código-fonte, o banco de dados de bugs e Anders, Mads. Scott e Peter no final do corredor. Eu sou certamente feliz, não há dúvida sobre isso.

No entanto, mesmo sem essas vantagens, ainda é possível obter um conhecimento profundo do assunto.

Quando comecei na Microsoft, estava trabalhando no interpretador JScript que acompanhava o Internet Explorer 3. Meu gerente na época me disse algo que foi um dos melhores conselhos que já recebi. Ele disse que queria que eu me tornasse o especialista reconhecido da Microsoft na sintaxe e semântica da linguagem JScript, e que eu deveria fazer isso procurando perguntas sobre esses aspectos do JScript e respondendo-as. Particularmente respondendo as perguntas para as quais eu não sabia as respostas, porque essas são as que eu aprenderia.

Obviamente, StackOverflow e outros fóruns públicos de perguntas e respostas são como beber de uma mangueira de fogo para esse tipo de coisa. Naquela época, eu lia o comp.lang.javascript e os fóruns internos da Microsoft "JS User" religiosamente e seguia o conselho do meu gerente: quando eu vi uma pergunta sobre a semântica da linguagem que eu não conhecia a resposta para, eu fiz o meu negócio para descobrir.

Se você quiser fazer um "mergulho profundo" assim, você tem que escolher com cuidado. Eu até hoje sou notavelmente ignorante de como o modelo de objeto do navegador funciona. Desde que me concentrei em me tornar o especialista em linguagem C # nestes últimos anos, sou notavelmente ignorante de como funcionam as várias classes nas bibliotecas de classes base. Tenho a sorte de ter um trabalho que preza conhecimentos profundos específicos; se o seu trabalho ou os seus talentos estiverem mais de acordo com a generalidade, aprofundar-se pode não funcionar para você.

Escrever um blog também é tremendamente útil; exigindo que eu explique tópicos complexos para outras pessoas, sou forçado a confrontar minha própria compreensão inadequada de vários tópicos o tempo todo.

    
por 13.07.2011 / 00:59
fonte
63

Tendo estado no lado do "guru" da conversa uma ou duas vezes, posso dizer-lhe que muitas vezes o que você percebe como "conhecimento profundo" de uma linguagem ou sistema de programação é frequentemente o resultado do "guru" recentemente lutando por um mês para resolver exatamente o mesmo problema. Isso é especialmente verdadeiro em um fórum onde as pessoas podem escolher quais perguntas elas responderão. Até mesmo os gostos de Jon Skeet e Eric Lippert tiveram que aprender o mundo em algum momento. Eles pegam seu conhecimento um conceito por vez, igual a qualquer outra pessoa.

    
por 11.07.2011 / 23:58
fonte
47

Parafraseando Yogi Bhajan:

"If you want to learn something, read about it; if you want to understand something, write about it; if you want to master something, program it."

A programação é como o desafio final do ensino. Ensinar computador faz algo requerer, que você conheça muito bem as suas coisas - ou você aprenderá a dominá-lo.

Por exemplo, se você quiser aprender física, escreva um mecanismo de física. Se você quer aprender xadrez, programe um jogo de xadrez. Se você quiser aprender um conhecimento profundo em C #, escreva um compilador C # (ou alguma outra ferramenta).

    
por 11.07.2011 / 23:17
fonte
25

Até onde eu sei, as formas de aprender isso são:

  • Leia sobre isso de alguém como Eric Lippert
  • Experimente e resolva os problemas em primeira mão.

O segundo caminho pode levar muito mais tempo, mas provavelmente resultará em um entendimento mais profundo (mas nem sempre).

    
por 11.07.2011 / 22:39
fonte
23

Eu diria que faça o seguinte:

Depois de aprender uma pilha de linguagens relativamente útil (aquelas que você precisa para um trabalho real) no nível em que você pode realizar as tarefas mais comuns, Pare de aprender mais idiomas até ter estudado pelo menos um em profundidade. Parte do problema em nossa indústria agora, na minha opinião, é que as pessoas só aprendem os primeiros 5-10% do idioma antes de passar para outro idioma. Depois de ter a capacidade de executar as tarefas mais comuns em um trabalho, comece a analisar uma coisa em profundidade. (Você pode voltar a ficar mais largo depois de ter alguma profundidade, depois ir e voltar entre os dois.)

Voluntário para as tarefas mais complexas e difíceis, aquelas que fazem você ter que ir em profundidade para resolver os problemas. Se não houver nenhum onde você trabalha, procure por tarefas de código aberto para fazer ou começar a trabalhar em um projeto pessoal que fará com que você tenha que ir em profundidade. Se o seu trabalho não tiver problemas interessantes, considere procurar um emprego mais desafiador.

Leia os livros avançados em um idioma (para o SQl Server, por exemplo, isso incluiria leitura sobre ajuste de desempenho e internos do banco de dados) em vez do tipo de livros Aprenda X em 30 dias.

Leia as perguntas interessantes aqui e outros lugares onde elas são perguntadas e tente resolver algumas delas. Se você quer aprender, tente resolver alguns sem ler as outras respostas primeiro. Mesmo que a pergunta já tenha sido respondida, você aprenderá mais se encontrar a resposta. Você pode até encontrar uma resposta melhor do que aquela que a pergunta tinha.

Faça algumas das perguntas mais difíceis. Avalie as respostas que você recebe, não apenas as use. Certifique-se de entender por que a resposta funcionaria ou não. Use essas respostas como um ponto de partida para pesquisar.

Encontre alguns bons blogs técnicos de especialistas conhecidos no campo e leia-os.

Pare de jogar fora seu conhecimento depois de terminar. Aprenda a reter. A maioria dos especialistas não precisa procurar a sintaxe comum. Eles não precisam reinventar a roda toda vez que enfrentam um problema, porque se lembram de como abordaram um problema semelhante antes. Eles podem conectar os pontos e ver como o problema X que eles fizeram dois anos atrás é semelhante ao problema Y que eles têm agora (espanta-me como poucas pessoas parecem capazes de fazer conexões assim). Consequentemente, eles têm mais tempo disponível para investigar assuntos mais interessantes.

    
por 12.07.2011 / 00:57
fonte
9

Você pode começar profundamente a estudar as especificações de idioma das pessoas que procura ser um especialista off. Por exemplo:

por 11.07.2011 / 23:32
fonte
6

Obtenha o Reflector ou qualquer outro descompilador (já que está pagando agora), e comece a abrir algumas das bibliotecas .NET mais usadas para aprenda como os internos funcionam. Combinado com um livro como o CLR via C # , você ficará muito mais fundo (mais fundo do que a maioria de nós trabalho regular).

    
por 11.07.2011 / 22:56
fonte
4

Eu desenvolvi esse tipo de conhecimento em C ++, participando de comp.lang.c++.moderated por alguns anos, mesmo que eu não estivesse trabalhando muito nesse código. Eu não tenho certeza como guru eu posso dizer que sou, no entanto.

Eu acho que há dois tipos de conhecimento que se pode aprender sobre uma linguagem de programação:

  1. Conhecendo curiosidades sobre o idioma e sabendo como evitar armadilhas.
  2. Saber como resolver problemas de forma eficaz.

O número 2 só pode ser alcançado programando-se no idioma e observando o código de outras pessoas, mas o número 1 pode ser obtido com muito tempo para ler sobre o idioma em seus fóruns de discussão, ver que tipos de perguntas as pessoas perguntam. e quais são as respostas. O StackOverflow é um bom lugar para isso também.

    
por 12.07.2011 / 03:48
fonte
4

Conhecimento profundo e conhecimento de programação significa estar confortável em todos os níveis de abstração. Ou seja,

  • bibliotecas e APIs
  • semântica de idiomas
  • otimizações do compilador
  • internos do compilador e geração de código
  • comportamento do tempo de execução e do coletor de lixo
  • problemas do conjunto arquitetônico e de instrução
Tudo que eu vi nos últimos 15 anos mostrou que somente se você realmente puder entrar no compilador e no tempo de execução, você terá uma chance de se tornar profundamente proficiente. Você pode ter que se forçar a dar o passo e começar a raciocinar (e construir) software no próximo nível de abstração menor na pilha , mas é a única maneira de se especializar.

Tudo o que temos é linguagem para abstração. Você deve entender como as linguagens de programação são projetadas e construídas para realmente saber o que a máquina está fazendo.

    
por 27.05.2012 / 23:07
fonte
3

Leia o Manual Fino Este não é um conhecimento particularmente profundo. Ele está publicado na especificação da linguagem C # seção 8.6.4. Você deve adquirir o hábito de, pelo menos, examinar as especificações dos idiomas que você usa, assim como verificar a documentação de todas as bibliotecas incorporadas.

De qualquer forma, esta não é a minha ideia de conhecimento profundo; é apenas um detalhe de implementação desinteressante. Poderia ser mais interessante se o designer explicasse por que foi feito dessa forma mais dinâmica, em vez de apenas verificar se o objeto implementa Iterable.

    
por 28.05.2012 / 08:08
fonte