Originalmente creé esto como una lista corta de temas a estudiar para volverme un Ingeniero de Software, pero creció hasta ser la gran lista que puede apreciar actualmente. Después de pasar por este plan de estudios, ¡fui contratado como Ingeniero de Desarrollo de Software en Amazon! (Art. en Inglés) Posiblemente no tengas que estudiar tanto como yo. De todos modos, todo lo que necesitas, esta aquí.
Nota: No necesitarás estudiar tanto como yo. He perdido mucho tiempo en aspectos que yo no necesitaba saber. Más información abajo. Te ayudaré a alcanzar tu meta sin que pierda su preciado tiempo.
Los elementos listados aquí le prepararan bien para una entrevista en cualquier compañía de software, incluyendo a los gigantes: Amazon, Facebook, Google o Microsoft.
Este es mi plan de estudios de varios meses para pasar de ser un Desarrollador Web (Autodidacta, sin título) a un Ingeniero de Software para una gran compañía.
Requisitos:
Mínima experiencia relacionada a la programación (variables, métodos/funciones, bucles...)
Paciencia
TIempo
Esto es para los nuevos Ingenieros de Software o aquellos que quieren cambiar del Desarrollo de Software/Web a Ingeniero de Software (Dónde el conocimiento de las Ciencias de Computación es requerido) Si tiene varios años de experiencia, y clama tenerlos como Ingeniero de Software, espere una entrevista más ardua.
Si tiene varios años de experiencia en el desarrollo de software/web, note que las grandes compañías (como Google, Amazon, Facebook y Microsoft) ven la Ingeniería de Software diferente al Desarrollo de Software/Web, requiriendo del conocimiento de las Ciencias de Computación.
Si desea ser un Ingeniero de Escalabilidad/Seguridad o un Ingeniero de Sistemas, estudie más de la lista opcional (Redes, Seguridad)
Si desea trabajar como un Ingeniero de Software para una gran compañía, estas son los aspectos que debes conocer.
Si, como yo, te perdiste la carrera de informática, esto te pondrá al día y te ahorrará cuatro años de tu vida.
Cuando comencé este proyecto, no sabía la diferencia entre un stack y un heap, no conocía la notación Big-O, nada acerca de árboles, ni cómo sacar la transversal de una gráfica. Si tenía que programar un algoritmo de clasificación, puedo decir que no hubiera sido muy bueno. Cada estructura de datos que había utilizado estaba incorporada al lenguaje, y yo no sabía cómo funcionaban realmente. Yo nunca tuve que manejar la memoria a menos que un proceso que yo estaba corriendo diera un error de “out of memory” y tenía que encontrar una alternativa. He usado pocos arreglos de varias dimensiones en mi vida y miles de arreglos asociativos, pero nunca he creado estructuras de datos desde cero.
Es un plan largo, puede que tome unos meses; pero si le resulta familiar mucho de esto, le tomara mucho menos tiempo.
Como usarlo
Todo lo que aparece abajo es un plan, y debería abordar los elementos en orden de arriba a abajo.
Estoy usando las características especiales de markdown de Github, incluyendo listas de tareas, para comprobar el progreso.
Cree una nueva rama para que pueda validar elementos como este, solo ponga una x en los corchetes: [x]
Haga fork a una rama y siga los comandos siguientes
Algunos videos solo están disponibles inscribiéndose a una clase de Coursera o EdX. Estos son llamados MOOCs. En ocasiones las clases no están en sesión, por lo que tendrá que esperar un par de meses, así que no tiene acceso.
Apreciaría su ayuda añadiendo fuentes siempre disponibles, publicas y gratuitas como videos de Youtube para acompañar a los videos del curso en línea.
Un curso enfocado a una entrevista centrada en Python; que cubre estructuras de datos, algoritmos, plantillas de entrevistas y mucho más.
Escoja un lenguaje para la entrevista
Puede usar un lenguaje con el que este cómodo para hacer la parte de código para la entrevista, pero para las grandes compañías, estas son buenas elecciones:
C++
Java
Python
También podría usar estos, pero primero deberá informarse. Puede haber advertencias:
JavaScript
Ruby
Debes sentirte muy cómodo con el lenguaje y ser experto.
El libro fue publicado en 2004 y es algo anticuado, pero es un recurso fantástico para la comprensión de una computadora en breve.
El autor inventó HLA, por lo que tiene muchas menciones y ejemplos en HLA. No es ampliamente utilizado, pero los ejemplos son decentes para ver cómo es un lenguaje ensamblador.
Estos capítulos valen la pena ser leídos para brindarle una buena base:
Chapter 2 - Numeric Representation
Chapter 3 - Binary Arithmetic and Bit Operations
Chapter 4 - Floating-Point Representation
Chapter 5 - Character Representation
Chapter 6 - Memory Organization and Access
Chapter 7 - Composite Data Types and Memory Objects
Para un tratamiento más rico y actualizado (2011), pero un trato más largo.
Específicos del lenguaje
Necesita escoger un lenguaje para la entrevista (mire arriba) Aquí están mis recomendaciones por lenguaje. No tengo recursos para todos los lenguajes, de modo ques son bienvenidas las adiciones.
Si ha leído alguno de estos, probablemente tenga todos los conocimientos de estructuras de datos y algoritmos que necesitará para resolver problemas de codificación.
Puede saltarse todas las video-lecturas en este proyecto, a menos que quiera una crítica.
Algunas personas recomiendan estos, pero creo exageran. A menos que tenga muchos años de experiencia en Ingeniería de Software y espere una entrevista mucho más difícil:
Importante: Leer este libro tendrá un valor limitado. Este libro es un buen resumen de algoritmos y estructuras de datos, pero no le enseñará cómo escribir un buen código. Necesita ser capaz de codificar una solución decente eficientemente.
Half.com es un buen recurso para libros a buenos precios.
Aka CLR, a veces CLRS, porque Stein llego tarde al juego.
El primer par de capítulos presentan soluciones inteligentes a problemas de programación (algunos muy antiguos con cinta de datos) pero solo es una introducción. Esta es una guía sobre el diseño y la arquitectura del programa, como Code Complete, pero mucho más corto.
"Algorithms and Programming: Problems and Solutions" by Shen
Un buen libro, pero después de trabajar con algunos problemas me fruste con Pascal, ciclos do while, 1-arreglos indexados y resultados poco claros de satisfacción post-condición.
Prefiero pasar tiempo en problemas de codificación de otro libro o problemas de codificación en línea.
Antes de iniciar
Esta lista creció a lo largo de varios meses, y sí, está un poco fuera de las manos.
Aquí algunos de mis errores para que pueda tener una mejor experiencia.
1. No recordará todo
Vi horas de video y tomé notas exactas de ellos, meses después había mucho que no recordaba. Pase tres días entre mis notas y haciendo tarjetas para poder repasar.
Para solucionar el problema construí un pequeño sitio de tarjetas para recordar donde podía añadir tarjetas de dos tipos: general y código.
Cada tarjeta tiene distinto formato.
Hice un sitio adaptado a moviles para revisarlo en mi celular y en mi Tablet, donde quiera estuviera.
Tenga en cuenta que empecé desde abajo y hay tarjetas que cubren todo, desde el lenguaje ensamblador y la trivia Python, hasta el Machine Learning y estadísticas. Es demasiado para lo que se requiere.
Nota en las tarjetas: La primera vez que reconozca y sepa la respuesta, no marque como conocido; necesitará contestar muchas veces correctamente antes de que en realidad lo sepa. La repetición pondrá ese conocimiento de forma más profunda en su cerebro.
Una alternativa a usar mi sitio de tarjetas es Anki, que me ha sido recomendado muchas veces. Usa un sistema de repetición para ayudarle a recordar. Es amigable con el usuario y disponible para todas las plataformas y tiene un sistema de sincronización en la nube. Cuesta $25 en iOS pero es gratuito en las otras plataformas.
Práctica, práctica, práctica… Hasta que me canse de ello y pueda hacerlo sin ningún problema (algunos usan técnicas y marcadores para recordar)
Trabajar dentro de las restricciones primarias (asignar / liberar memoria sin ayuda del garbage collection (excepto Python))
Hacer uso de los tipos incorporados para que tenga experiencia usando las herramientas de tipos incorporados para su uso en el mundo real (no escribiré mi propia implementación de listas enlazadas en producción)
Puede que no tenga tiempo de hacer todo esto para cada tema, pero lo intentaré.
Este es un libro corto, pero le dará un gran manejo en el lenguaje C, y si lo practica un poco, rápidamente conseguirá ser experto. Comprender C le ayudará a entender cómo funcionan los programas y la memoria.
Gotcha: Necesita tener conocimiento del apuntador a apuntador:
(Cuando se pasa un apuntador a una función este puede cambiar la dirección a la que el apuntador apunta)
Esta página es sólo para tener una idea sobre un apuntador a un apuntador. No recomiendo esta lista de estilo transversal. La legibilidad y sostenibilidad sufren debido a la astucia.
Implementar usando listas enlazadas, con el puntero de la cola:
enqueue(value) – Añade el valor en la posición de la cola.
dequeue() – Regresa el valor y elimina el valor más recientemente añadido(frontal)
empty()
Implementar usando arreglos de tamaño fijo:
enqueue(value) – Añade elemento al final del almacenamiento disponible.
dequeue() – Regresa el valor y elimina el elemento más recientemente añadido.
empty()
full()
Costo:
Una mala implementación usando lista enlazada donde se enqueue en la cabeza y dequeue en la cola sería O (n), porque usted necesitaría el siguiente al último elemento, causando un recorrido completo cada dequeue.
enqueue: O(1) (amortizado, Lista enlazada y arreglo [sondaje])
Los grafos pueden ser usados para representar muchos problemas en las Ciencias de la Computación, así que es una sección larga, como lo son los árboles y ordenamientos.
Notas:
Hay cuatro formas básicas de representar un grafo en memoria:
Objetos y apuntadores.
Matriz adyacente.
Lista adyacente.
Mapa adyacente.
Familiarícese con cada representación y sus pros y contras.
BFS and DFS – Conozca su complejidad computacional, sus compromisos y cómo implementarlos en código real.
Cuando se le haga una pregunta busque una solución basada en grafos. Si no la encuentra, continúe.
Este tema puede ser bastante difícil, ya que cada problema soluble PD debe definirse como una relación de recursión, y llegar a ella, puede ser complicado.
Sugiero que busque muchos ejemplos de problemas de PD hasta que tenga una comprensión sólida del patrón involucrado.
Videos:
Los videos de Skiena pueden ser duros de seguir ya que a veces usa el pizarrón, que es demasiado pequeño para verlo bien.
Conozca acerca de las clases más famosas de problemas de NP-completo, tales como el vendedor ambulante y el problema de la mochila, y sea capaz de reconocerlos cuando un entrevistador se los pide disfrazados.
Necesidades de recursos de proceso (memoria: código, almacenamiento estático, pila, monticulo y también descriptores de archivo, i /o)
Necesidades de recursos de hilos (partes anteriores (menos pila) con otros hilos en el mismo proceso, pero cada uno tiene su propio PC, contador de pila, registros y pila)
Bifurcación es realmente copia en escritura (sólo lectura) hasta que el nuevo proceso escribe en memoria, entonces hace una copia completa..
Cambio de contexto:
Cómo se inicia el cambio de contexto por el sistema operativo y el hardware subyacente.
La lectura de todos los documentos, de extremo a extremo con la comprensión completa, probablemente tomará más tiempo del que tiene. Recomiendo ser selectivo en los documentos y sus secciones.
Diseño del Sistema, Escalabilidad, Manejo de Datos
Puede esperar preguntas sobre el diseño del sistema si tiene más de 4 años de experiencia.
La escalabilidad y el diseño del sistema son temas muy extensos, con muchos aspectos y recursos, ya que hay mucho que considerar al diseñar un sistema de software / hardware que se puede escalar. Espere dedicarle un buen tiempo a esto.
Consideraciones:
Escalabilidad:
Destilar conjuntos de datos grandes a valores únicos.
Transformar un conjunto de datos en otro.
Manejo de cantidades de datos obscenamente grandes.
Vea la forma en "Messaging, Serialization, and Queueing Systems" debajo para la información sobre algunas de las tecnologías que pueden unir servicios.
Para aún más, vea la serie de videos "Mining Massive Datasets" en la sección de Series de video
Practicando el proceso de diseño del sistema: Aquí hay algunas ideas para tratar de trabajar en papel, cada una con cierta documentación sobre cómo se manejó en el mundo real:
Esta sección tendrá videos cortos en los que podrá visualizar rápidamente para revisar algunos de los conceptos importantes.
Es bueno si quieres repasar frecuentemente.
Series de videos cortos sobre temas de 2-3 minutos (23 videos)
Ahora que conoce todos los tópicos de las Ciencias de la Computación mencionados anteriormente, es tiempo de practicar respondiendo algunos problemas de programación.
La práctica de preguntas de programación no es sobre memorizar respuestas a problemas.
Por qué necesita practicar haciendo problemas de programación:
El reconocimiento de problemas, y donde las estructuras de datos y algoritmos adecuados encajan.
Reunir los requisitos para el problema.
Hablar sobre su camino a través del problema como lo hará en la entrevista.
Codificar en una pizarra o papel, no en un ordenador.
Llegar con la complejidad del tiempo y espacio para sus soluciones.
Probar sus soluciones.
Hay una gran introducción para la solución de problemas metódicos y comunicativos en una entrevista. Conseguirá esto de los libros para la entrevista de programación también, pero encontré esto excepcional:
Algorithm design canvas
¿No tiene pizarrón en casa? Tiene sentido. Soy un bicho raro y tengo una pizarra grande. En vez de una pizarra blanca, recoja un gran cuadernillo de dibujo de una tienda de arte. Puede sentarse en el sofá y practicar. Esta es mi "pizarra de sofá". He añadido la pluma en la foto para la escala. Si usa un bolígrafo, deseará poder borrarlo. Se ensucia rápido.
Vea los elementos de preparación en Cracking The Coding Interview and back of Programming Interviews Exposed.
Pensando en cuando llegue la entrevista
Piense en aproximadamente veinte preguntas de la entrevista que usted conseguirá, junto con las líneas de abajo. Tenga 2-3 respuestas para cada una.
Tener una historia, no sólo datos, sobre algo que logró.
¿Por qué quiere este trabajo?
¿Qué problema difícil ha resuelto?
¿Cuáles han sido sus mayores desafíos a los cuales se ha enfrentado?
¿Cuáles han sido los mejores / peores diseños que ha visto?
Ideas para mejorar un producto existente.
¿Cómo trabaja mejor, individualmente, o como parte de un equipo?
¿Cuáles de sus habilidades o experiencias serían claves en el rol? ¿Por qué?
¿Qué es lo que más disfruto en [ x trabajo / y proyecto]?
¿Cuál fue el mayor reto al que se enfrentó en [x trabajo / y proyecto]?
¿Cuál fue el error más difícil que enfrentó en [x trabajo / y proyecto]?
¿Qué aprendió en [x trabajo / y proyecto]?
¿Qué habría hecho mejor en [x trabajo / y proyecto]?
Preguntas para el entrevistador
Algunos de las mías (ya sé su respuesta, pero quiero su opinión o la perspectiva del equipo):
¿Qué tan grande es su equipo?
¿Cómo es su ciclo de desarrollo? ¿Haces waterfall / sprints / agile?
¿Son corrientes las fechas límite comunes? ¿O hay flexibilidad?
¿Cómo se toman las decisiones en su equipo?
¿Cuántas reuniones tienes por semana?
¿Siente que su ambiente de trabajo le ayuda a concentrarse?
¿En que estas trabajando?
¿Qué te gusta de ello?
¿Cómo es la vida laboral?
¡Felicitaciones!
Manténgase aprendiendo.
Nunca está de verdad realizado.
*****************************************************************************************************
*****************************************************************************************************
Todo lo que está debajo de este punto es opcional.
Mediante el estudio de estos, obtendrá una mayor exposición a más conceptos de la Ciencia de
la Computación, y estará mejor preparado para cualquier trabajo de Ingeniería de Software.
Usted será un Ingeniero de Software mucho más completo.
*****************************************************************************************************
*****************************************************************************************************
Es probable que estos temas no aparezcan en una entrevista, pero los añadí para ayudarle a convertirse en un Ingeniero de Software más completo, y ser consciente en ciertas tecnologías y algoritmos, para que tenga una caja de herramientas más grande.
Conocer por lo menos un tipo de árbol binario equilibrado (y saber cómo se implementa):
"Entre los árboles de búsqueda equilibrada, los árboles AVL y 2/3 están ahora pasados de moda, y los árboles rojo-negro parecen ser más populares.
Una estructura de datos auto-organizable particularmente interesante es el árbol biselados, que utilizan rotaciones para mover cualquier clave accedida a la raíz.." - Skiena
De estos, opté por implementar un árbol biselado. Por lo que he leído, no implementarás un árbol de búsqueda equilibrado en tu entrevista. Pero yo quería exponer la codificación de uno y bueno, los árboles son las rodillas de la abeja. He leído un montón de código de árbol rojo-negro.
Árboles biselados: Funciones insert, search, delete.
Si terminas implementando un árbol rojo / negro, intenta lo siguiente:
Funciones de búsqueda e inserción, saltándose eliminar.
Quiero aprender más acerca de los Árboles-B ya que se utiliza tan ampliamente con conjuntos de datos muy grandes.
En práctica:
Por lo que puedo decir, estos no se usan mucho en la práctica, pero pude ver dónde estarían:
El árbol AVL es otra estructura que soporta la búsqueda, inserción y eliminación de O (log n) Es más rígidamente equilibrado que los árboles rojo-negro, lo que lleva a una inserción y eliminación más lenta, pero más rápido la recuperación. Esto lo hace atractivo para las estructuras de datos que se pueden construir una vez y se cargan sin reconstrucción, como diccionarios de idiomas (o diccionarios de programas, como los opcodes de un ensamblador o intérprete)
En práctica:
Los árboles biselados son típicamente usados en la implementación de la memoria cache, ssignadores de memoria, enrutadores, recolectores de basura, compresión de datos, cuerdas (reemplazo de la cadena utilizada para cadenas de texto largas), en Windows NT (en la memoria virtual, en red y en el código del sistema de archivos) etc.
Éstos son una traducción de un árbol 2-3 (véase abajo)
En la práctica:
Los árboles rojo-negro ofrecen las peores garantías de tiempo de inserción, tiempo de borrado y tiempo de búsqueda.
Esto no solo los hace valiosos en aplicaciones sensibles al tiempo como las aplicaciones en tiempo real, sino que las convierte en elementos valiosos en otras estructuras de datos que proporcionan las garantías más desfavorables; por ejemplo, muchas estructuras de datos utilizadas en la geometría computacional pueden basarse en árboles rojos y negros, y el Completely Fair Scheduler utilizado en los kernels Linux actuales usa árboles de color rojo-negro. En la versión 8 de Java, la Colección HashMap se ha modificado de manera que en lugar de usar una lista enlazada para almacenar elementos idénticos con códigos de hash pobres, se utiliza un árbol Rojo-Negro.
En práctica:
Los árboles 2-3 tienen inserciones más rápidas a expensas de búsquedas más lentas (ya que la altura es más comparada con árboles AVL)
Usará árboles 2-3 muy raramente porque su implementación implica diferentes tipos de nodos. En su lugar, las personas utilizan árboles de color rojo negro.
En práctica:
Para cada árbol 2-4, hay árboles rojo-negro correspondientes con elementos de datos en el mismo orden. Las operaciones de inserción y supresión en árboles 2-4 también son equivalentes a la rotación de color en rojos y negros árboles. Esto hace que árboles 2-4 sean una herramienta importante para entender la lógica detrás de los árboles rojo-negros, y es por eso que muchos textos de algoritmo introductorios introducen árboles 2-4 justo antes de los árboles rojo-negro, aunque Los árboles 2-4 no son a menudo utilizados en la práctica.
Dato curioso: Es un misterio, pero la B puede ser por Boeing, Balanceado, o Bayer (co-inventor)
En práctica:
Árboles-B son ampliamente utilizados en bases de datos. La mayoría de los sistemas de archivos modernos utilizan árboles B (o variantes) Además de su uso en bases de datos, el árbol B también se utiliza en sistemas de archivos para permitir el acceso rápido y aleatorio a un bloque arbitrario en un archivo en particular. El problema básico es convertir la dirección de bloque de archivos i en una dirección de bloque de disco (o tal vez a una dirección de cilindro-cabezal)
MIT 6.851 - Memory Hierarchy Models (video)
- Cubre árboles-B de cache inconsistente, estructuras de datos muy interesantes.
- Los primeros 37 minutos son muy técnicos, puede saltarlos (B es tamaño de bloque, tamaño de línea de caché)
Agregué estos para reforzar algunas ideas ya presentadas anteriormente, pero no quería incluirlas arriba porque es demasiado. Es fácil exagerar en un tema. ¿Quieres ser contratado en este siglo, verdad?