You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 KiB

Coding Interview University

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í.

Durante muchos meses he estudiado diariamente de 8 a 12 horas. Esta es mi historia: Por qué estudié a tiempo completo durante 8 meses para una entrevista con Google. (Art. Inglés)

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.

¡Mucha suerte!

Traducciones: - [Bahasa Indonesia](translations/README-id.md) - [Bulgarian](translations/README-bg.md) - [Español](translations/README-es.md) - [German](translations/README-de.md) - [Japanese (日本語)](translations/README-ja.md) - [Polish](translations/README-pl.md) - [Português Brasileiro](translations/README-ptbr.md) - [Russian](translations/README-ru.md) - [Tiếng Việt - Vietnamese](translations/README-vi.md) - [Urdu - اردو](tanslations/README-ur.md) - [Uzbek](translations/README-uz.md) - [বাংলা - Bangla](translations/README-bn.md) - [ខ្មែរ - Khmer](translations/README-kh.md) - [简体中文](translations/README-cn.md) - [繁體中文](translations/README-tw.md)
Traducciones en progreso:

¿Qué es esto?

Coding at the whiteboard - from HBO's Silicon Valley

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)


Tabla de contenido

---------------- Todo debajo de esta marca es opcional ----------------


¿Por qué usarlo?

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

Haga fork del repositorio de Github jwasham/coding-interview-university haciendo click sobre el botón "Fork".

Clónalo en un repositorio local:

git clone git@github.com:<tu_usuario_de_github_/coding-interview-university.git
git checkout -b progress
git remote add jwasham https://github.com/jwasham/coding-interview-university
git fetch --all

Marque todas las cajas con una x después de que completa los cambios

git add .
git commit -m "Marcado con X"
git rebase jwasham/main
git push --set-upstream origin progress
git push --force

Más acerca de características de Github para markdown

No sienta que no es lo suficientemente listo

Acerca de los recursos de vídeo

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.

Prepárese para la entrevista

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.

Lee más acerca de opciones:

Vea recursos de programas aquí

Verá algunos materiales de aprendizaje de C, C++ y Python abajo, porque estoy aprendiendo. Hay algunos libros involucrados, ve al final.

Lista de libros

Esta es una lista más corta que la que yo usé. Está abreviada para ahorrarle tiempo.

Preparación para la entrevista

Si dispone de mucho tiempo adicional:

Arquitectura de Computadores

Si no dispone de mucho tiempo:

  • Write Great Code: Volume 1: Understanding the Machine
    • 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
      • Chapter 9 - CPU Architecture
      • Chapter 10 - Instruction Set Architecture
      • Chapter 11 - Memory Architecture and Organization

Si tiene más tiempo (Yo quiero este libro):

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.

Recursos adicionales específicos del lenguaje aquí.

C++

No he leído estos dos, pero están altamente calificados y escritos por Sedgewick. Él es asombroso.

Si tiene una mejor recomendación para C++, por favor hágamelo saber. Busco fuentes comprensivas.

Java

O:

  • Data Structures and Algorithms in Java
    • Por Goodrich, Tamassia, Goldwasser.
    • Usado como texto opcional en el curso de Informática impartido en UC Berkeley.
    • Vea mi reporte de la versión de Python debajo. Este libro abarca los mismos tópicos.

Python

Libros Opcionales

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:

  • Algorithm Design Manual (Skiena)

    • Como un resumen y un reconocimiento de problemas.
    • La porción del catálogo de algoritmos está más allá del alcance de la dificultad que obtendrá en una entrevista.
    • Este libro consta de dos partes:
      • Libro de clase sobre estrcutura de datos y algoritmos
        • Pros:
          • Es un buen resumen como cualquier libro de algoritmos debe ser.
          • Buenas historias de sus experiencias resolviendo problemas en la industria y en la academia
          • Ejemplos codificados en C.
        • Cons:
          • Puede ser así de denso o impenetrable como los CLRS, en algunos casos, los CLRS pueden proveer una mejor alternativa para algunos temas.
          • Capítulos 7, 8, 9 pueden ser un martirio intentar darles seguimiento, ya que no están bien explicados o requieren más cerebro del que tengo.
          • No me malentiendan: Me gusta Skiena, su estilo de enseñanza y manierismos, pero no puedo ser material de Stony Brook.
      • Catálogo de algoritmos:
        • Es la verdadera razón para comprar el libro.
        • Actualizare esto, una vez haya pasado por este.
    • Se puede adquirir en Kindle
    • Half.com es un gran recurso para libros de textos a buen precio.
    • Respuestas:
    • Errata
  • Introduction to Algorithms

    • 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.
  • Programming Pearls

    • 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.

Lea por favor para que no cometa mis errores:

Retaining Computer Science Knowledge

2. Use tarjetas para recordar

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.

Haga el suyo gratis:

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.

Mis tarjetas en el formato de Anki: https://ankiweb.net/shared/info/25173560 (Gracias@xiewenya)

3. Revise, revise, revise

Mantuve una serie de hojas clave en ASCII, OSI stack, notación Big-O y más. Las estudie cuando tenía tiempo libre.

Tome un descanso de los problemas de programación por media hora y repase sus tarjetas.

4. Enfóquese

Hay muchas distracciones que le pueden quitar tiempo valioso. Enfocarse y concentrarse es difícil.

Lo que no verá cubierto

Estas son tecnologías predominantes, pero no están cubiertas por este plan de estudios:

  • SQL.
  • Javascript.
  • HTML, CSS, y otras tecnologías front-end.

El plan diario

Algunos temas tomarán un día y otros tomarán varios. Algunos son solo para aprender sin nada que implementar.

Cada día yo tomé un tema de los siguientes, vi videos sobre el tema y escribía una implementación:

  • C - usando estructuras y funciones que toman una estructura * y otra cosa como argumentos.
  • C++ - sin utilizar tipos incorporados.
  • C++ - usando tipos incorporados, como std::list de STL para una lista enlazada.
  • Python - usando tipos incorporados (para seguir practicando Python)
  • y escribir pruebas para asegurarme de que lo estoy haciendo bien, a veces simplemente usando simples declaraciones assert()
  • Puede hacer Java o algo más, esto es solo lo mío.

No necesita todo esto. Solo necesita un lenguaje para la entrevista

¿Por qué codificar en todo esto?

  • 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é.

Puede ver mi código aquí:

No es necesario recordar las entrañas de cada algoritmo.

Escriba código en un pizarrón o en papel, pero no en la computadora. Pruebe con alguna entrada de prueba y después pruébelos en la computadora.

Conocimientos Previos

Complejidad algorítmica / Big-O / Análisis asintótico

Estructuras de datos

  • Arreglos

    • Implemente un vector automáticamente redimensionable.
    • Descripción:
    • Implemente un vector (Arreglo mutable con redimensionamiento automático):
      • Practique codificar usando arreglos y apuntadores, y un apuntador matemático para saltar a un índice en lugar de utilizar la indexación.
      • Nuevo arreglo de información primaria con memoria asignada.
        • Puede asignar un arreglo entero, simplemente no use sus características.
        • Empiece con 16, o si el número inicial es mayor, use potencias del 2 - 16, 32, 64, 128.
      • size() Número de elementos.
      • capacity() Número de elementos soportados.
      • is_empty()
      • at(index) Regresa el elemento al índice dado. Falla si el índice esta fuera de sus limites.
      • push(item)
      • insert(index, item) Inserta el elemento en el índice, intercambia el valor del índice y desplaza los elementos a la derecha.
      • prepend(item) Puede usar para insertar encima del índice 0.
      • pop() Elimina del final, regresa el valor.
      • delete(index) Elimina el elemento en el índice, intercambia todos desplazándolos a la izquierda.
      • remove(item) Busca el valor y elimina el índice que lo contiene, aunque este en varios lugares.
      • find(item) Busca el valor y regresa el primer índice con ese valor, devuelve -1 si no lo encuentra.
      • resize(Nueva capacidad) // Función privada.
        • Cuando alcance el límite, redimensiona al doble el tamaño.
        • Cuando se haga “pop” a un elemento, si el tamaño es 1/4 de la capacidad, redimensiona a la mitad.
    • Tiempo:
      • O(1) Para añadir/eliminar al final (Amortizado para asignaciones por más espacio), índice o actualización.
      • O(n) Para insertar/eliminar donde sea.
    • Espacio:
      • Contiguo en la memoria, por lo que la proximidad ayuda al rendimiento.
      • Espacio necesario = (capacidad de matriz, que es> = n) * tamaño del elemento, pero incluso si 2n, todavía O (n))
  • Listas Enlazadas

    • Descripción:
    • C Code (video) - No todo el video, solo porciones acerca de la estructura de nodos y la asignación de memoria.
    • Listas enlazadas vs Arreglos:
    • why you should avoid linked lists (video)
    • 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.
    • Implemente (Lo hice con y sin un puntero de cola):
      • size() Regresa el número de elementos en la lista.
      • empty() Un bool que regresa verdadero si está vacío.
      • value_at(index) Regresa el valor del el n-avo elemento (usando 0 como primero)
      • push_front(value) Añade un elemento al frente de la lista.
      • pop_front() Elimina el elemento frontal y regresa su valor.
      • push_back(value) Añade un elemento al final.
      • pop_back() Elimina el último elemento y devuelve su valor.
      • front() Obtiene el valor del elemento frontal.
      • back() Obtiene el valor del último elemento.
      • insert(index, value) Inserta valor en el índice, por lo que el valor actual en ese índice es apuntado al nuevo elemento en el índice.
      • erase(index) Borra el nodo del índice dado.
      • value_n_from_end(n) Regresa el valor del nodo en la n-ava posición a partir del final de la lista.
      • reverse() Pone al revés toda la lista.
      • remove_value(value) Borra el primer elemento en la lista con ese valor.
    • Doble lista enlazada:
  • Pila:

  • Cola o fila

    • Queue (video)
    • Circular buffer/FIFO
    • [Review] Queues in 3 minutes (video)
    • 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])
      • dequeue: O(1) (Lista enlazada y arreglo)
      • empty: O(1) (Lista enlazada y arreglo)
  • Matriz asociativa

Información adicional

Árboles

Ordenamientos

Como resumen aquí esta una representación visual de 15 algoritmos de ordenamiento Si necesita más detalle de este tema vea “Ordenamientos” en Detalles adicionales de ciertos temas

Grafos

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.

||| Obtendrá más prácticas de grafos en el libro de Skiena (vea Sección de libros debajo) y en los libros de entrevistas.

Más información adicional

Diseño del Sistema, Escalabilidad, Manejo de Datos


Revisión final

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)
  • Series de videos cortos sobre temas de 2-5 minutos - Michael Sambol (48 videos):

Practica de preguntas de programación

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.

my sofa whiteboard

Complementos:

Lea y resuelva problemas de programación (en ese orden):

Vea Lista de libros

Ejercicios de programación/Desafíos

Una vez haya aprendido, ponga ese cerebro a trabajar. Tome desafíos de programación todos los días y tantos como pueda.

Videos de preguntas de entrevistas de código:

Sitios de desafíos:

Repositorios con desafíos:

Bosquejos de entrevista:

Una vez cerca de la entrevista

Su CV (Currículum Vitae)

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.
*****************************************************************************************************
*****************************************************************************************************

Libros adicionales

Aprendizaje adicional

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.

--

Detalles adicionales de ciertos temas

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?

Series de videos

Siéntese y disfrute. "Netflix and skill" :P

Cursos de Informática