不久前,在我们办公室的基础上,我们举办了免费讲座“现代而有效的C ++”并将其录制在视频中。 该课程是专为刚加入我们的程序员,实习生和所有参与者的团队而设计的。 在本文中,我们要强调本课程的目的,准备过程,以进行总结。 我们希望我们的讲座对您中的某些人会很有趣,并且您会喜欢我们的工作。 祝您阅读愉快!
这个主意是怎么来的
我们公司PVS-Studio正在开发一种静态代码分析器,该代码分析器可以识别用C,C ++,C#和Java编写的程序的源代码中的错误和潜在漏洞。 对于任何有兴趣吸引年轻专家的人来说,这都不是秘密。 经常会发生这样的情况:希望获得编程领域专业经验并且仍然缺乏该领域知识的学生接受实践培训。 此外,我们新到的专家还需要专业发展方面的帮助。 鉴于上述情况,决定准备并进行有关编程的课程。 这个想法至少追求三个目标:向年轻的专业人员和实习生展示如何更准确,更有效和更安全地编写代码; 在办公室外推广C ++,并从学习和进一步使用的角度证明该语言很有前景; 使我们的公司成为一个有趣的雇主。 在确定目标并受到创意启发后,我们着手实现梦想。
准备工作
随着对我们想法的进一步讨论,出现了这么多问题和很少答案(令人惊讶的是,是吗?)。 议程上的内容是:时间和地点,由谁来准备课程,由谁来主持课程,应涵盖哪些主题,我们将在视频上录制该课程,我们将如何做,如何推广它以及在哪里做得更好,而且还有很多地方我们讨论了另外两个星期的问题的数量,并用破折号重复出现,并写着:“但是……如何”,“谁……?”,“哪里……?”
因此,当每个人的思想和想法“同步”时,决定从7月9日至8月15日,每周两次进行12次讲座设计。 安德烈·卡尔波夫(Andrei Karpov)和菲利普·汉德利恩(Philip Handelyants)被选为讲师。
在我们的
YouTube频道上,我们将所有视频收集在一个单独的播放列表中,以方便观看。 我们还有一个
VKontakte小组 ,其中包含讲座的所有信息。 因此,如果想要重复某件事或如果一个人不能亲自出席,则可以转到单独的演讲页面,查看其内容,进行注册,然后再观看演讲记录。
让我们来研究一下演讲的主题及其内容。
C ++ 11标准创新
C ++ 11 ...这五个字符的含义是什么...第一次演讲是最长的,也许是很有启发性的,因为菲利普和伙计们在近两个小时内讨论了很多问题。 因此,他们首先研究了C ++语言及其使用的相关性。 然后他们直接了解了C ++ 11标准的最新变化。 在这一部分中,考虑了语言核心的扩展,即:
- 通用初始化
- 移动语义;
- 广义常量表达式(constexpr) ;
- POD类型定义的更改;
- 初始化列表(std :: initializer_list <T>) ;
- 通过auto和decltype进行类型推断;
- 范围;
- lambda函数;
- 替代函数语法;
- 函数返回类型的输出;
- 委托建设者;
- 默认/删除功能说明符;
- 使用多态时覆盖/最终限定词;
- nullptr_t和nullptr ;
- 还有很多。
在讨论了内核扩展之后,Philip讨论了对标准库的扩展,其中包括:
- 更新标准库以反映核心语言的变化;
- 多线程:线程( std :: thread ),互斥对象( std :: Mutex,... ),条件变量( std :: conditional_variable,... );
- RAII包装器( std :: lock_guard,std :: unique_lock );
- 元组( std :: tuple) ;
- 哈希表( std ::无序(_set / _multiset / _map / _multimap );
- 正则表达式( std :: regex );
- 智能指针( std :: unique_ptr,std :: shared_ptr,std :: weak_ptr );
- 伪随机数生成器代替rand() ;
- 链接包装器( std :: reference_wrapper );
- 函数的通用包装器( std :: function );
- 特质 ( type_traits )。
当然,值得理解的是,如此大量的信息无法在两个小时内得到详细介绍,因此,对某些要点进行了详细介绍,而有些则具有了更熟悉的功能。
C ++ 14标准创新
第二堂课专门讨论C ++ 14标准的创新。 变化不多,因此听众“忍受”了2个小时,而不是2个小时:-)。 像在第一堂课中一样,注意力集中在两个要点上:更改C ++内核和更改标准库。
这是他们谈论的内容:
- 函数的返回类型输出,而无需显式指定返回类型的最终声明( 尾随返回类型 );
- 十进制类型(自动) ;
- 放松对constexpr的限制;
- 可变变量
- 聚合初始化;
- 二进制文字
- 数字分隔符;
- 广义λ
- lambda捕获具有初始化功能的列表;
- 属性[[deprecated]] ,std :: shared_timed_mutex;
- 异构搜索关联容器;
- 标准用户文字(对于std :: string是s;对于std:duration 来说 是 h,min , s , ms , us , ns ,对于std :: complex的虚部来说是if , i , il );
- std :: get现在可以按类型从std :: tuple获取值;
- std :: make_unique ;
- std :: integer_sequence ;
- 免费功能std :: start,std :: end,std :: cbegin,std :: cend,std :: rbegin,std :: rend,std :: crbegin,std :: crend ;
- std ::交换 。
C ++中的类型推断
在强调了C ++ 11和C ++ 14标准的创新之后,我们集中讨论了C ++中的类型推断主题。 为什么要谈论这个话题? 在C ++ 11之前,除了“模板魔术师”的编写者和编译器开发人员之外,很少有人对它的含义及其工作方式进行彻底的思考。
时光飞逝,现在C ++程序员需要考虑标准接受的创新:
自动 ,
转发链接,
decltype ,lambd捕获列表,通过返回值进行类型推断等。
开发人员已开始在新代码中积极使用创新,因此了解这种含义以及在这种情况下编译器将执行的工作非常重要。
C ++ 17标准创新
说到现代C ++,不可能不提及最新的现有C ++标准。 叙述是根据已经建立的方案进行的:考虑内核中的更改,然后考虑标准库中的更改。 因此,我们考虑了:
- 构造函数输出模板类的类型;
- throw()被认为是noexcept并被标记为depriced ;
- noexcept已成为类型系统的一部分,现在在选择函数重载时已将其考虑在内;
- 复制省略 ;
- 卷积( fold表达式 );
- 如果/用初始化器切换 ;
- 如果是constexpr , 结构化绑定 ;
- 嵌套的名称空间;
- 新属性[[ fallthrough ]],[[ maybe_unused ]]和[[ nodiscard ]];
- 十六进制实数;
- static_assert接受消息作为可选参数,而不是必需参数;
- 现在, 模板模板选项中允许使用typename ;
- 使用brace-initializer-list 自动输出类型的另一个新规则;
- 内联变量;
- auto可以在模板参数中使用;
- 预处理程序指令__has_include ;
- 寄存器已成为保留字,尚未使用;
- std :: string_view ;
- std ::可选 ;
- std ::任何
- std ::变体 ;
- std ::字节 ;
- std :: uncaught_exceptions代替std :: uncaught_exception ;
- boost ::文件系统 ,其变化泛滥为std ::文件系统 ;
- try_emplace和insert_or_assign用于关联数组;
- 免费函数std :: size , std :: empty和std :: data ;
- type_traits的模板变量( std :: * _ v <T ...> )。
STL:概念,容器,迭代器
第五讲完全是关于标准模板库的。 我们讨论了STL的历史,它的组成以及如何开始使用它。 我们更详细地讨论了标准容器(
vector ,
list ,
forward_list ,
deque等),适配器容器(
stack ,
queue ,
priority_queue ,
heap )和迭代器类型(
输入 ,
输出 ,
转发 ,
双向 ,
随机 ,
连续 )。
STL:算法,包装器,功能对象
在本讲座中,他们继续研究STL。 Philip谈到了您不需要从事自行车制造这一事实,现在该开始使用标准STL算法了。 考虑了各种类别的算法,有用的功能包装器(
加号 ,
减号 ,...)。
静态分析是编写C ++程序时开发不可或缺的一部分
菲利普决定放松一下:-),我们的技术总监安德烈·卡尔波夫(Andrey Karpov)举行了第七次演讲。 他谈到了静态分析,以及为什么必须在工作中使用它。 Andrei解释了在大型项目中使用静态分析器与提高代码质量之间的直接关系。 在没有实际工作实例的情况下谈论静态分析是很愚蠢的,因此,讲座中自然也包含了PVS-Studio检测到的错误的示例。 我们讨论了使用代码分析工具的正确与错误方法。
PVS-Studio编码标准和用于开发有效C ++诊断程序的通用技术
菲利普(Philip)仍在休息,安德烈(Andrei)和他的学生们对PVS-Studio内部厨房稍微看了一眼,考虑了两个主题。
首先,我们讨论了我们团队采用的编码标准,以及为什么我们决定以这种方式设计代码,而不是其他。
其次,我们讨论了开发分析器时使用的一些代码微优化方法。 我们讨论了著名的短语“过早的优化是万恶之源”。 话题一去不复返了,但是Andrei很快计划给它单独发表一份报告:“
过早的优化是邪恶的!万岁的过早的优化! ”在C ++俄罗斯会议上。 因此,我们邀请所有人参加这次精彩的会议和Andrey的报告。
讲座主要针对我们公司的实习生以及最终想要成为他们的人。 关于内容,这里讨论了PVS-Studio编码标准的这些时刻:
- 一般规定;
- 行数
- 变量命名
- 类型命名;
- 功能命名;
- 代码对齐;
- 困难情况下的桌子布置;
- 分隔空间;
- 过早的优化;
- 优化班级规模和结构;
- 寿命短和更多的变量。
C ++中的元编程:模板,constexpr计算等。
菲利普休息了一会,变得有力量,并要求“模板魔术”。 众所周知,随着新标准的发布,元编程正变得越来越复杂和难以理解,在代码库中,“模板魔术”的数量正在不断增长。 讲座将任务设置为最新,并介绍了元编程的主要方面:
- 模板功能;
- 模板类
- 模板的全部和部分专业化;
- 可变模板;
- 卷积。
30分钟后的听众:
但这还不是全部! Philip决定在编译阶段
最后讨论计算和类型操纵,CRTP(奇特重复发生的模板模式)模式,SFINAE和检测器,以
完成这些工作 。
C / C ++项目的组装及其优化
上一讲的幸存者被告知如何在编写项目时少喝咖啡,少用剑战斗。
提出了以下方面:
- C / C ++中的翻译阶段;
- 瘾
- 外部模板;
- 预编译头文件;
- 并行和分布式编译;
- 编译器缓存;
- 替换翻译组件:预处理器,编译器,链接器;
- 单一编译单元(SCU);
- 模块。
行为不定或如何射杀自己
“有些人认为当他们使用溢出或空指针玩游戏时,他们知道C和C ++的行为。 不,他们不知道。 没有人知道。 在这里,不确定行为开始,“不确定”一词意味着我们不能做任何假设或猜测。 根本不可能编写出行为不确定的程序。 考虑一下模糊行为的主题以及导致该问题的一些代码示例,“类似的事情是第11讲的开始,Andrei再次接管了Philip,并重点介绍了该主题的关键点,包括术语:
- 不确定和不确定的行为;
- 出国阵列
- 缺乏虚拟析构函数;
- 删除运算符
- 空指针;
- 班次
- 整数溢出(64位错误);
- 整数溢出(校验和)。
C ++ 20和可预见的未来
我们无法完成有关即将发布的最新C ++ 20标准的故事的演讲。 主要重点放在概念(
Concepts ),范围库(
Ranges ),协程(
Coroutines ),模块(
Modules ),合同(
Contract ),三向比较运算符<=>(
Spaceship operator ),用于测试功能的宏(
Feature test)上宏 ),属性(
Attributes ),
std :: format ,
std :: jthread等...
因此,当解决了所有组织问题后,便意识到了这一想法。
实作
当然,我们将这一阶段称为“期望-现实”,因为正如通常发生的那样,在规划阶段所考虑的一切在实施阶段都会发生100万次变化。 自然地,我们意识到了这一事实,并准备好(
不 )出现问题。 我们面临的主要问题是下面的邻居,他们正在积极维修他们租来的房屋,而在我们的办公室里,有一个打孔时间(无评论),这不但影响了演讲的录制,而且还影响了课堂的录制。 在这方面,该课程的讲座几乎有一半被重新编写,或者录制了部分视频。 如果就安德烈(Andrei)而言,没有什么可重写的,因为他的讲课持续了大约一个小时,而且我们有足够的时间让公司不进行下面的安装工作,那么我们就不得不承受菲利普的讲课的痛苦,因为每次讲堂1.5至2个小时都没有每个程序员都可以生存,而且不是每个工人都能在没有工作的情况下等待那么多。 也许这种情况是最不可预见的,否则就没有严重的问题。
现在让我们谈谈课程的开始。 大约有20名学员报名参加了我们的第一堂课,但实际上有11名学生参加了。 当然,我们知道通过第一个事件进行判断是愚蠢的,因此决定观察接下来会发生什么。 整个课程的学生人数在不断变化:正在增加或减少。 但是,我们喜欢这样一个事实,即在每次讲座中都形成了小组的某个“骨干”。 在专业人士中,您还可以突出显示参与者的活动。 就像在任何一个新小组中一样,起初每个人都感到尴尬并默默地听讲座,但是在大约3-4个讲座的某个地方,这种限制就过去了,并且课堂以更加活跃的形式进行-问题,讨论,讲座后的现场交流-并有案例,当一个人继续与讲师交流40至50分钟时,因为他对该主题非常感兴趣,并且确实希望朝这个方向发展。 这不禁让我们感到高兴,因为我们了解到我们在一定程度上为这一事实做出了贡献(业障+100)。
最持久的被授予证书。
总结
目标有效性是衡量我们合资企业有效性的关键指标。 在社会化和提高专业技能方面,让年轻的专家和团队中的实习生工作变得更容易了吗? 肯定-是的,因为讲座基于我们的程序员在工作中遇到的特定示例。 此外,这种形式的培训有助于加速新员工团队的适应过程。 我们可以在办公室外推广C ++语言吗? 坦白说,我们认为有50/50。 一方面,非常感兴趣的人不仅参加了我们的讲座,而且后来对其进行了修订,搜索了有关特定主题的其他信息,并全副武装准备下一场讲座。 是的,有准备! 有时会下着大雨,一个男人湿透了,以免上课。 我了解这一点-热情! 另一方面,最初希望“从外面”参加我们课程的人比结束时要多。 我至少有以下三个原因:
- CA的基础是学生,也许报名参加该课程的学生对这个主题有一定的想法,但是他们的期望与现实不符,因为尽管该课程涵盖了C / C ++编程的一般方面,很多狭focused的,专门的问题。
- 该课程在夏季的高峰期进行(是的,我们知道今年不是争论的话题,特别是如果您住在俄罗斯中部)。 许多人只是离开了这座城市而无法参加该课程,即使他们对此感兴趣。
- 有些劳动程序员不了解我们的课程就知道一切:)
最后,我想说的是,我们认为创建自己的小型编程课程的想法是成功的,因为这种经验帮助我们的公司优化了一些内部工作流程,并向未来的申请人清晰地展示了我们的标准。
如果您有任何疑问,甚至是建议或想法,请随时发表评论-我们会说:)。 是的,感谢您阅读本文。
链接到报告选择:
Vkontakte和
YouTube的 “现代而有效的C ++”。 如果您在社交网络上分享它们,我们将不胜感激。