De vez en cuando veo preguntas sobre casos extremos y otras rarezas en Stack Overflow que son respondidas fácilmente por personas como Jon Skeet y Eric Lippert, lo que demuestra un profundo conocimiento del lenguaje y sus muchas complejidades, como esta:
Puede pensar que para usar un
foreach
bucle, la colección sobre la que está iterando debe implementarIEnumerable
oIEnumerable<T>
. Pero resulta que eso no es realmente un requisito. Lo que se requiere es que el tipo de la colección debe tener un método público llamadoGetEnumerator
, y que debe devolver algún tipo que tenga un getter de propiedad pública llamadoCurrent
y un método públicoMoveNext
que devuelva abool
. Si el compilador puede determinar que se cumplen todos esos requisitos, el código se genera para usar esos métodos. Solo si no se cumplen esos requisitos, verificamos si el objeto se implementaIEnumerable
o noIEnumerable<T>
.
Eso es algo genial para saber. Puedo entender por qué Eric sabe esto; él está en el equipo compilador, así que tiene que saberlo. ¿Pero qué pasa con aquellos que demuestran un conocimiento tan profundo que no son expertos?
¿Cómo se enteran los simples mortales (que no están en el equipo del compilador de C #) sobre cosas como esta?
Específicamente, ¿existen métodos que estas personas usen para erradicar sistemáticamente dicho conocimiento, explorarlo e internalizarlo (hacerlo propio)?
fuente
Respuestas:
En primer lugar, gracias por las amables palabras.
Si desea obtener un conocimiento profundo de C #, sin duda es una ventaja tener la especificación del lenguaje, diez años de notas de diseño, el código fuente, la base de datos de errores y Anders, Mads, Scott y Peter justo al final del pasillo. Ciertamente soy afortunado, no hay duda al respecto.
Sin embargo, incluso sin esas ventajas, todavía es posible obtener un conocimiento profundo del tema.
Cuando comencé en Microsoft, estaba trabajando en el intérprete JScript que se incluía con Internet Explorer 3. Mi gerente en ese momento me dijo algo que fue uno de los mejores consejos que he recibido. Dijo que quería que me convirtiera en el experto reconocido de Microsoft en la sintaxis y la semántica del lenguaje JScript, y que debería hacerlo buscando preguntas sobre esos aspectos de JScript y respondiéndolas. Particularmente respondiendo las preguntas para las que no sabía las respuestas, porque esas son las que aprendería.
Obviamente, StackOverflow y otros foros públicos de preguntas y respuestas son como beber de una manguera de bomberos para ese tipo de cosas. En aquel entonces, leí religiosamente comp.lang.javascript y nuestros foros internos de "usuarios de JS" de Microsoft y seguí el consejo de mi gerente: cuando vi una pregunta sobre la semántica del idioma para la que no sabía la respuesta, lo hice. Mi negocio es averiguarlo.
Si quieres hacer una "inmersión profunda" como esa, debes elegir con cuidado. Hasta el día de hoy, soy notablemente ignorante de cómo funciona el modelo de objetos del navegador. Como me he concentrado en convertirme en el experto en lenguaje C # estos últimos años, soy notablemente ignorante de cómo funcionan las diversas clases en las bibliotecas de clases base. Soy afortunado porque tengo un trabajo que premia el conocimiento profundo específico; Si su trabajo o sus talentos están más en línea con ser un generalista, profundizar podría no funcionar para usted.
Escribir un blog también es tremendamente útil; Al exigirme que explique temas complejos a otras personas, me veo obligado a enfrentar mi propia comprensión inadecuada de varios temas todo el tiempo.
fuente
Después de haber estado en el lado del "gurú" de la conversación una o dos veces, puedo decirle que muchas veces lo que percibe como "conocimiento profundo" de un lenguaje o sistema de programación es a menudo el resultado del "gurú" que lucha recientemente por un mes para resolver exactamente el mismo problema. Eso es especialmente cierto en un foro donde las personas pueden elegir qué preguntas responderán. Incluso los gustos de Jon Skeet y Eric Lippert tuvieron que aprender hola mundo en un punto. Recogen su conocimiento un concepto a la vez, igual que cualquier otra persona.
fuente
Parafraseando a Yogi Bhajan:
La programación es como el último desafío de enseñanza. Enseñar a la computadora a hacer algo requiere que conozcas tus cosas realmente bien, o aprenderás a dominarlas.
Por ejemplo, si quieres aprender física, escribe un motor de física. Si quieres aprender ajedrez, programa un juego de ajedrez. Si desea aprender un profundo conocimiento de C #, escriba un compilador de C # (o alguna otra herramienta).
fuente
Hasta donde yo sé, las formas de aprender esto son:
La segunda forma puede llevar mucho más tiempo, pero probablemente resultará en una comprensión más profunda (pero no siempre).
fuente
Yo diría que hagas lo siguiente:
Después de aprender una pila relativamente útil de idiomas (los que necesita para un trabajo real) en el nivel en el que puede realizar las tareas más comunes, deje de aprender más idiomas hasta que haya estudiado al menos uno en profundidad. Parte del problema en nuestra industria en este momento, en mi opinión, es que las personas solo aprenden el primer 5-10% del idioma antes de pasar a otro idioma. Una vez que tenga la capacidad de realizar las tareas más comunes en un trabajo, comience a analizar una cosa en profundidad. (Puede volver a obtener amplitud después de obtener algo de profundidad, luego ir y venir entre los dos).
Voluntario para las tareas más complejas y difíciles, las que hacen que tengas que profundizar para resolver los problemas. Si no hay ninguno donde trabaje, busque tareas de código abierto para hacer o comience a trabajar en un proyecto personal que lo obligará a profundizar. Si su trabajo no tiene problemas interesantes, considere buscar un trabajo más desafiante.
Lea los libros avanzados en un idioma (para SQl Server, por ejemplo, esto incluiría leer sobre ajuste de rendimiento y aspectos internos de la base de datos) en lugar del tipo de libros de aprender X en 30 días.
Lea las preguntas interesantes aquí y en otros lugares donde se hacen y trate de resolverlas usted mismo. Si quieres aprender, intenta resolver algunas sin leer primero las otras respuestas. Incluso si la pregunta ya ha sido respondida, aprenderá más si encuentra la respuesta usted mismo. Incluso podría encontrar una mejor respuesta que la que tenía la pregunta.
Haga algunas de las preguntas más difíciles. Evalúa las respuestas que te dan, no las uses solo. Asegúrese de entender por qué la respuesta funcionaría o no. Use esas respuestas como punto de partida para investigar.
Encuentre algunos buenos blogs técnicos de expertos conocidos en el campo y léalos.
Deja de tirar tu conocimiento una vez que hayas terminado con él. Aprende a retener. La mayoría de los expertos no tienen que buscar la sintaxis común. No tienen que reinventar la rueda cada vez que enfrentan un problema porque recuerdan cómo abordaron un problema similar antes. Pueden conectar los puntos y ver cómo el problema X que hicieron hace dos años es similar al problema Y que tienen ahora (me sorprende cómo pocas personas parecen capaces de hacer conexiones como esa). En consecuencia, tienen más tiempo disponible para dedicar a la investigación de temas más interesantes.
fuente
Puede comenzar estudiando a fondo las especificaciones de idioma de las que busca ser un experto. Por ejemplo:
fuente
foreach
y detalla el comportamiento descrito en la publicación de blog citada de Eric Lippert. Si alguien alguna vez se encuentra pensando algo como "Me pregunto cómo funciona realmente foreach ...", este sería un buen lugar para comenzar a buscar.Obtenga Reflector o cualquier otro descompilador (ya que está pagando ahora), y comience a abrir algunas de las bibliotecas .NET más utilizadas para aprender cómo funcionan las partes internas. En combinación con un libro como CLR a través de C #, se volverá bastante profundo (más profundo de lo que la mayoría de nosotros realizaremos su trabajo habitual).
fuente
BitConverter
clases, y descubrí laIsLittleEndian
bandera específica del sistema.Desarrollé ese tipo de conocimiento en C ++ al pasar
comp.lang.c++.moderated
un par de años, a pesar de que realmente no estaba trabajando tan duro para codificarlo en ese momento. Sin embargo, no estoy seguro de qué gurú puedo decir que soy.Creo que hay dos tipos de conocimiento que uno puede aprender sobre un lenguaje de programación:
El número 2 solo se puede lograr programando en el lenguaje y mirando el código de otras personas, pero el número 1 se puede lograr tomando mucho tiempo para leer sobre el idioma en sus foros de discusión, ver qué tipo de preguntas hacen las personas y cuáles son las respuestas son StackOverflow es un buen lugar para eso también.
fuente
El conocimiento profundo y la experiencia en programación significa sentirse cómodo en todos los niveles de abstracción. Es decir
Todo lo que he visto en los últimos 15 años ha demostrado que solo si realmente puedes entrar en el compilador y el tiempo de ejecución, tienes la oportunidad de ser profundamente competente. Puede que tenga que obligarse a dar el paso y comenzar a razonar (y construir) software en el siguiente nivel de abstracción más bajo en la pila , pero es la única forma de experiencia.
Todo lo que tenemos es lenguaje para la abstracción. Debe comprender cómo se diseñan y construyen los lenguajes de programación para saber realmente lo que está haciendo la máquina.
fuente
Lea el buen manual Esto no es un conocimiento particularmente profundo. Está publicado en la sección de especificación del lenguaje C # 8.6.4. Debería habituarse al menos a eliminar las especificaciones de los idiomas que utiliza, así como a eliminar la documentación de todas las bibliotecas integradas.
De todos modos, esta no es mi idea de conocimiento profundo; es solo un detalle de implementación poco interesante. Podría ser más interesante si el diseñador explicara por qué se hizo de esta manera más dinámica, en lugar de simplemente verificar que el objeto implemente Iterable.
fuente