No hace mucho tiempo, sobre la base de nuestra oficina, realizamos un curso de lectura gratuito "C ++ moderno y efectivo" y los grabamos en video. El curso fue diseñado para recién llegados en nuestro equipo de programadores, pasantes y todos los recién llegados. En este artículo nos gustaría destacar el propósito de este curso, el proceso de preparación para ello, para resumir. Esperamos que para algunos de ustedes nuestro curso de conferencias sea interesante y que aprecien nuestro trabajo. ¡Le deseamos una agradable visualización de los informes!
¿Cómo surgió la idea?
Nuestra empresa PVS-Studio está desarrollando un analizador de código estático que identifica errores y vulnerabilidades potenciales en el código fuente de programas escritos en C, C ++, C # y Java. Y no es un secreto para nadie que nos interese atraer jóvenes especialistas. A menudo sucede que los estudiantes que desean adquirir experiencia profesional en el campo de la programación y que aún carecen de conocimiento en este campo reciben capacitación práctica. Además, nuestros especialistas recién llegados también necesitan ayuda con el crecimiento profesional. En vista de lo anterior, se decidió preparar un curso de conferencias sobre programación y llevarlo a cabo. Esta idea perseguía al menos tres objetivos: mostrar a los jóvenes profesionales y pasantes cómo escribir código de manera más precisa, eficiente y segura; popularizar C ++ fuera de la oficina y demostrar que el lenguaje es prometedor desde el punto de vista del aprendizaje y seguir trabajando con él; para popularizar nuestra empresa como un empleador interesante. Una vez determinados los objetivos e inspirados por la idea, nos propusimos hacer realidad el sueño.
Preparación
Con una discusión más profunda de nuestra idea, comenzaron a aparecer tantas preguntas y tan pocas respuestas (sorprendentemente, ¿sí?). En la agenda estaban: el tiempo y el lugar, quién preparará el curso, quién lo conducirá, qué temas deben cubrirse, grabaremos el curso en video, cómo lo haremos, cómo promocionarlo, y dónde es mejor hacerlo y todavía hay un gran el número de preguntas que discutimos durante otras dos semanas y repetimos como un guión con las palabras: "¿Y cómo ...?", "¿Y quién ...?", "¿Y dónde ...?".
Y así, cuando los pensamientos e ideas de todos se "sincronizaron", se decidió que el curso estaría diseñado para 12 conferencias 2 veces por semana del 9 de julio al 15 de agosto. Andrei Karpov y Philip Handelyants fueron seleccionados como profesores.
En nuestro
canal de YouTube, hemos recopilado todos los videos en una lista de reproducción separada para una fácil visualización. También tenemos un
grupo VKontakte , que contiene toda la información sobre las conferencias. Por lo tanto, fue posible ir a la página de una conferencia separada, ver de qué se trataba, registrarse y luego también ver una grabación de la conferencia si algo quería repetirse o si una persona no podía asistir en persona.
Detengámonos en los temas de las conferencias y su contenido.
Innovaciones estándar de C ++ 11
C ++ 11 ... cuánto significado hay en estos cinco personajes ... La primera conferencia resultó ser la más larga y, tal vez, informativa, porque en casi dos horas Philip y los chicos discutieron muchas preguntas. Entonces comenzaron mirando el lenguaje C ++ y la relevancia de su uso. Luego fueron directamente a los mismos cambios en el estándar C ++ 11. Durante esta parte, se consideró la extensión del núcleo del lenguaje, a saber:
- inicialización universal;
- mover semántica;
- expresiones constantes generalizadas (constexpr) ;
- cambios en la definición del tipo de POD;
- listas de inicialización (std :: initializer_list <T>) ;
- inferencia de tipos mediante auto y decltype ;
- rango para ;
- funciones lambda;
- sintaxis de función alternativa;
- salida del tipo de retorno de la función;
- delegar constructores;
- especificadores por defecto / borrar para funciones;
- anulación / calificadores finales cuando se trabaja con polimorfismo;
- nullptr_t y nullptr ;
- y mucho, MUCHO más.
Después de discutir las extensiones del kernel, Philip habló sobre las extensiones de la biblioteca estándar, que incluyen:
- actualizar la biblioteca estándar para reflejar los cambios en el idioma central;
- multihilo: hilos ( std :: hilo ), mutexes ( std :: mutex, ... ), variables condicionales ( std :: conditional_variable, ... );
- Contenedores RAII ( std :: lock_guard, std :: unique_lock );
- tuplas ( std :: tuple) ;
- tablas hash ( std :: no ordenadas (_set / _multiset / _map / _multimap );
- expresiones regulares ( std :: regex );
- punteros inteligentes ( std :: unique_ptr, std :: shared_ptr, std :: weak_ptr );
- generadores de números pseudoaleatorios en lugar de rand () ;
- envoltorios de enlaces ( std :: reference_wrapper );
- contenedor generalizado para funciones ( std :: function );
- rasgos ( type_traits ).
Por supuesto, vale la pena entender que una cantidad tan enorme de información no se puede cubrir en detalle en dos horas, por lo que algunos puntos se contaron con más detalle, mientras que otros tenían una función de familiarización más.
C ++ 14 innovaciones estándar
La segunda conferencia se dedicó a revisar las innovaciones del estándar C ++ 14. No hubo muchos cambios, por lo que los oyentes "sufrieron" no durante 2 horas, sino solo 40 minutos :-). Como en la primera conferencia, se prestó atención a dos puntos principales: cambiar el núcleo de C ++ y cambiar la biblioteca estándar.
Esto es de lo que hablaron:
- salida del tipo de retorno para funciones sin especificar explícitamente la declaración final del tipo de retorno ( tipo de retorno final );
- decltype (auto) ;
- flexibilizar las restricciones para constexpr ;
- variables variables;
- inicialización agregada;
- literales binarios
- separadores de números;
- lambdas generalizadas;
- lista de captura lambda de funciones con inicialización;
- atributo [[en desuso]] , std :: shared_timed_mutex;
- búsqueda heterogénea de contenedores asociativos;
- literales de usuario estándar (s para std :: string ; h, min , s , ms , us , ns para std :: duración , if , i , il para la parte imaginaria de std :: complex );
- std :: get ahora puede obtener el valor de std :: tuple por tipo;
- std :: make_unique ;
- std :: integer_sequence ;
- funciones gratuitas std :: begin, std :: end, std :: cbegin, std :: cend, std :: rbegin, std :: rend, std :: crbegin, std :: crend ;
- std :: exchange .
Inferencia de tipos en C ++
Tras destacar las innovaciones de los estándares C ++ 11 y C ++ 14, nos centramos en el tema de la inferencia de tipos en C ++. ¿Por qué fue sobre este tema? Antes de C ++ 11, pocas personas pensaban a fondo sobre qué es y cómo funciona, con la excepción de los escritores y desarrolladores de compiladores de "plantillas mágicas".
Los tiempos pasan, y ahora el programador de C ++ debe tener en cuenta las innovaciones aceptadas por los estándares:
automático , enlaces de
reenvío ,
decltype , lista de captura lambda, inferencia de tipos por valor de retorno, etc.
Los desarrolladores han comenzado a utilizar activamente las innovaciones en código nuevo, y es muy importante comprender qué significa esto y qué hará el compilador en esta situación.
C ++ 17 innovaciones estándar
Hablando de C ++ moderno, era imposible no mencionar el último estándar C ++ existente. La narración se presentó de acuerdo con el esquema ya establecido: se consideraron los cambios en el núcleo y luego en la biblioteca estándar. Por lo tanto, consideramos:
- salida de tipos de clases de plantilla de constructores;
- throw () se considera noexcept y se marca como depricated ;
- noexcept se ha convertido en parte del sistema de tipos y ahora se tiene en cuenta al elegir sobrecargas de funciones;
- copiar elisión ;
- convolución ( expresión de pliegue );
- if / switch con inicializador;
- si constexpr , enlaces estructurados ;
- espacios de nombres anidados;
- nuevos atributos [[ fallthrough ]], [[ maybe_unused ]] y [[ nodiscard ]];
- literales reales hexadecimales;
- static_assert acepta el mensaje como un parámetro opcional en lugar de uno obligatorio;
- typename ahora está permitido en las opciones de plantilla de plantilla ;
- Otra nueva regla para la salida de tipo automático con brace-initializer-list ;
- variables en línea ;
- auto se puede usar en parámetros de plantilla;
- directiva del preprocesador __has_include ;
- registrarse se ha convertido en una palabra reservada y aún no se utiliza;
- std :: string_view ;
- std :: opcional ;
- std :: cualquiera ;
- std :: variante ;
- std :: byte ;
- std :: uncaught_exceptions en lugar de std :: uncaught_exception ;
- boost :: filesystem con cambios inundados como std :: filesystem ;
- try_emplace e insert_or_assign para matrices asociativas;
- funciones libres std :: size , std :: empty y std :: data ;
- variables de plantilla para type_traits ( std :: * _ v <T ...> ).
STL: concepto, contenedores, iteradores
La quinta conferencia estuvo completamente dedicada a la biblioteca de plantillas estándar. Discutimos la historia de STL, en qué consiste y cómo comenzar a usarlo. Hablamos con más detalle sobre los contenedores estándar (
vector ,
list ,
forward_list ,
deque , ...), los contenedores de adaptador (
stack ,
queue ,
priority_queue ,
heap ) y los tipos de iterador (
input ,
output ,
forward ,
bidirectional ,
random ,
contiguous ).
STL: Algoritmos, Envolturas, Objetos Funcionales
En esta conferencia, continuaron trabajando en el STL. Philip habló sobre el hecho de que no necesita practicar ciclismo y es hora de comenzar a usar algoritmos STL estándar. Se consideraron varias categorías de algoritmos, envoltorios funcionales útiles (
más ,
menos , ...).
El análisis estático como parte integral del desarrollo al escribir programas en C ++
Philip decidió relajarse un poco :-), y nuestro director técnico, Andrey Karpov, realizó la séptima conferencia. Habló sobre el análisis estático en general, y por qué es necesario usarlo en el trabajo. Andrei explicó la relación directa entre usar un analizador estático y mejorar la calidad del código cuando se trabaja en un proyecto grande. Sería una tontería hablar de análisis estático sin ejemplos de nuestra realidad laboral, por lo tanto, naturalmente, los ejemplos de errores detectados por PVS-Studio también se incluyeron en la conferencia. Hablamos sobre las formas correctas e incorrectas de usar herramientas de análisis de código.
PVS-Studio que codifica técnicas estándar y generales para desarrollar diagnósticos efectivos de C ++
Philip todavía está descansando, y Andrei y sus alumnos miraron un poco la cocina interna de PVS-Studio, considerando dos temas.
En primer lugar, hablamos un poco sobre el estándar de codificación adoptado por nuestro equipo y por qué decidimos diseñar el código de esta manera, y no de otra manera.
En segundo lugar, discutimos algunos métodos de microoptimización de código que usamos al desarrollar el analizador. Discutimos sobre la famosa frase "la optimización prematura es la raíz de todo mal". El tema se tocó de pasada, pero Andrei pronto planea dedicarle un informe por separado "¡
La optimización prematura es malvada! ¡Viva la optimización prematura! " En la conferencia C ++ Rusia. Así que invitamos a todos a esta maravillosa conferencia y al informe de Andrey.
La conferencia estuvo dirigida principalmente a los pasantes de nuestra empresa y aquellos que eventualmente quieren convertirse en ellos. Con respecto al contenido, aquí se discutieron esos momentos del estándar de codificación PVS-Studio:
- disposiciones generales;
- Filas
- nomenclatura variable;
- tipo de nombre;
- nomenclatura de funciones;
- alineación de código;
- disposición de la mesa de una condición difícil;
- separación de espacios;
- optimización prematura;
- optimización de clases y estructuras;
- variables con vidas cortas y más.
Metaprogramación en C ++: plantillas, cálculos constexpr, etc.
Philip descansó, ganó fuerza y dijo "magia de plantilla". Todos saben que la metaprogramación con cada lanzamiento de un nuevo estándar se está volviendo cada vez más complicada e incomprensible, en las bases de código la cantidad de "plantilla mágica" está en constante crecimiento. La conferencia estableció la tarea de mantenerse actualizado, informando sobre los principales aspectos de la metaprogramación:
- funciones de plantilla;
- Clases de plantilla
- especialización total y parcial de plantillas;
- plantillas variables;
- convolución
Oyentes después de 30 minutos:
¡Pero eso no fue todo! Philip decidió
terminarlos con una charla
final sobre computación y manipulación de tipos en la etapa de compilación, sobre CRTP (patrón de plantilla curiosamente recurrente), SFINAE y detectores.
Montaje de proyectos C / C ++ y su optimización.
A los sobrevivientes de la conferencia anterior se les dijo cómo beber menos café y luchar menos con espadas mientras se compila su proyecto.
Se plantearon los siguientes aspectos:
- fases de traducción en C / C ++;
- adicciones
- plantillas externas;
- encabezados precompilados;
- compilación paralela y distribuida;
- caché del compilador;
- reemplazo de componentes de traducción: preprocesador, compilador, enlazador;
- Unidad de compilación individual (SCU);
- módulos
Comportamiento indefinido o cómo pegarse un tiro en el pie
“Algunas personas piensan que saben cómo se comportan C y C ++ cuando juegan con desbordamientos o punteros nulos. No, ellos no lo saben. Y nadie lo sabe. Aquí comienza el comportamiento indefinido, y la palabra "indefinido" significa que no podemos hacer suposiciones o suposiciones. Es simplemente imposible escribir programas en los que haya un comportamiento indefinido, punto. Considere el tema del comportamiento indefinido y algunos ejemplos de código que lo conducen a él ”, algo como esto fue el comienzo de la clase 11, en la que Andrei nuevamente se hizo cargo de Philip y destacó los puntos clave de este tema, incluida la terminología:
- comportamiento indefinido y no especificado;
- ir al extranjero la matriz;
- falta de destructor virtual;
- eliminar operador
- punteros nulos;
- turnos
- desbordamiento de enteros (errores de 64 bits);
- desbordamiento de enteros (suma de comprobación).
C ++ 20 y el futuro previsible
No pudimos terminar nuestro ciclo de conferencias con una historia sobre el lanzamiento inminente del último estándar C ++ 20. El énfasis principal se puso en conceptos (
Conceptos ), una biblioteca de rangos (
Rangos ), corutinas (
Corutinas ), módulos (
Módulos ), contratos (
Contratos ), un
operador de operador de comparación de tres vías <=> (
Operador de nave espacial ), macros para probar la funcionalidad (
Prueba de características macros ), atributos (
Atributos ),
std :: format ,
std :: jthread y mucho más ...
Y así, cuando se resolvieron todos los problemas organizativos, llegó el momento de darse cuenta de la idea.
Implementación
Por supuesto, llamaríamos a esta etapa "Expectativa-Realidad", porque, como suele suceder, todo lo que se piensa en las etapas de planificación cambia un millón más de veces en la etapa de implementación. Naturalmente, éramos conscientes de este hecho y estábamos listos (
no ) de que algo saldría mal. El principal problema para nosotros fueron los vecinos a continuación, que estaban reparando activamente los locales que alquilaron, y en nuestra oficina llegó un momento de perforación (sin comentarios), que no pudo sino afectar la grabación de las conferencias. En este sentido, casi la mitad de las conferencias del curso fueron reescritas nuevamente o algunas partes del video fueron filmadas. Y si en el caso de Andrei, no había nada que reescribir, ya que sus conferencias duraron aproximadamente una hora y tuvimos tiempo suficiente para que la compañía no llevara a cabo el trabajo de instalación desde abajo, entonces tuvimos que sufrir las conferencias de Philip, porque no duraron 1.5-2 horas por conferencia. Cada programador sobrevivirá y no todos los trabajadores pueden esperar tanto sin trabajar. Quizás esta situación fue la más imprevista, de lo contrario no hubo problemas serios.
Ahora hablemos sobre el comienzo del curso. Alrededor de 20 participantes se inscribieron en nuestra primera conferencia, pero de hecho asistieron 11 estudiantes. Por supuesto, entendimos que juzgar por el primer evento es estúpido, y decidimos ver lo que sucede después. El número de estudiantes para todo el curso cambiaba constantemente: aumentaba o disminuía. Sin embargo, nos gustó el hecho de que se formó una cierta "columna vertebral" del grupo, que estuvo presente en cada conferencia. De los profesionales, también puede resaltar la actividad de los participantes. Como en cualquier grupo nuevo, inicialmente todos se avergonzaron y escucharon en silencio la conferencia, pero en algún lugar alrededor de 3-4 conferencias esta restricción pasó y las clases se desarrollaron de manera más activa: preguntas, discusiones, solo comunicación en vivo después de la conferencia, y hubo casos, cuando una persona continúa comunicándose con el profesor durante otros 40-50 minutos, porque está muy interesado en el tema y realmente quiere desarrollarse en esta dirección. Esto no podía sino alegrarse, ya que entendimos que en parte contribuimos a este hecho (+100 al karma).

Los más persistentes recibieron certificados.
Resumen
Un indicador clave de la efectividad de nuestra empresa es el logro de objetivos. ¿Se ha vuelto más fácil trabajar para jóvenes especialistas y pasantes en nuestro equipo en términos de socialización y mejora de las habilidades profesionales? Definitivamente, sí, ya que las conferencias se basaron en ejemplos específicos que nuestros programadores encuentran mientras trabajan. Además, esta forma de capacitación contribuyó a la aceleración del proceso de adaptación en el equipo para los nuevos empleados. ¿Podríamos popularizar el lenguaje C ++ fuera de la oficina? Francamente, creemos que hay 50/50. Por un lado, había personas muy interesadas que no solo asistieron a nuestras conferencias, sino que también las revisaron más tarde, buscaron información adicional sobre un tema en particular y vinieron totalmente armados para la próxima conferencia. Sí hay preparación! Hubo un caso en el que estaba lloviendo mucho y un hombre entró mojado para no perderse la lección. Esto lo entiendo: ¡celo! Por otro lado, inicialmente había más personas que deseaban asistir a nuestro curso "desde afuera" que al final. Tengo al menos tres razones para esto:
- La base de CA eran los estudiantes y, tal vez, al haberse inscrito en el curso, tenían una cierta idea sobre el tema, pero sus expectativas no coincidían con la realidad, porque, a pesar de que el curso cubría aspectos generales de la programación en C / C ++, Una gran cantidad de temas especializados y de enfoque limitado.
- El curso tuvo lugar en pleno verano (sí, sabemos que este año no es un argumento, especialmente si vives en el centro de Rusia). Muchos simplemente abandonaron la ciudad y no pudieron asistir al curso, incluso si estaban interesados en él.
- Hubo programadores laborales que saben todo sin nuestro curso :)
En conclusión, me gustaría decir que consideramos exitosa la idea de crear nuestro propio curso de programación pequeña, porque esta experiencia ayudó a nuestra empresa a optimizar algunos procesos de trabajo internos y mostrar claramente nuestros estándares a los futuros solicitantes.
Si tiene alguna pregunta, tal vez incluso sugerencias o ideas, no dude en dejar comentarios, hablaremos :). Y sí, gracias por leer este artículo.
Enlace a la selección de informes: "C ++ moderno y eficaz"
Vkontakte y
YouTube . Estaremos agradecidos si los comparte en las redes sociales.