C++

Hire the Top 3% of 自由c++开发人员

Toptal是一个面向顶级c++开发人员的市场, engineers, programmers, coders, architects, 和顾问. 顶级公司和初创公司可以雇佣专职(全职), hourly, 或者兼职的c++自由职业者,用于他们的关键任务软件项目.

无风险试用,满意才付款.

Clients Rate c++开发人员总数4.5 / 5.0截至2023年12月19日,平均有434条评论

雇佣自由的c++开发人员和工程师

朱莉·韦瑟比

自由c++开发人员

United StatesToptal Member Since 2015年8月21日

Julie在为各种规模的企业构建软件应用程序和领导工程团队方面拥有超过20年的经验. 她是Java方面的专家, JavaScript, C, C++, and Perl, 并且熟悉许多流行的框架. 最近,Julie为沃尔玛设计并实现了一个大规模的Oracle数据库分片解决方案.com.

Show More

布雷迪波默洛

自由c++开发人员

CanadaToptal Member Since 2022年10月25日

布雷迪有三年的软件工程师经验. 他的经验主要是在C/ c++的嵌入式固件方面. 他在CICD方面也有丰富的经验, GitLab, 用于测试自动化和Python的Docker和脚本. 布雷迪在思科公司有网络方面的经验, Apache中的I型管理程序和全栈开发, Flask, Go, Bootstrap.

Show More

Mike Hutton

自由c++开发人员

United StatesToptal Member Since May 27, 2015

Mike是一名软件架构师和开发人员,拥有超过25年的大型关键任务系统开发经验. 他目前专注于Java和J2EE开发, c++和C开发, 以及物联网的嵌入式系统. 此外,他是国际公认的彩票博彩系统领域的专家. 在过去的16年里,Mike一直在为不同地域的团队提供解决方案.

Show More

Nick Aversano

自由c++开发人员

United StatesToptal Member Since 2020年10月26日

尼克从事编程工作已有十多年了. 他的专长包括React前端,Node.js后端、c++、游戏、图形和许多编程语言. 在开始他的技术生涯后,因为他想做游戏, 从那以后,他拓展到新的领域. 知名客户包括LinkedIn和哈雷戴维森(Harley-Davidson). 尼克喜欢不断学习新事物,不断成长和提高.

Show More

Ted Middleton

自由c++开发人员

CanadaToptal Member Since July 9, 2020

Ted是一名软件开发人员和程序员,拥有20年的专业编程经验,近25年的C和c++编程经验,Python编程经验也差不多. 他喜欢寻找干净的解决方案,并编写高质量、高价值的代码. Ted还擅长移植和构建可维护的跨平台软件,并且擅长运行时性能优化. 简而言之,泰德写的软件只是工作而已.

Show More

旧金山我

自由c++开发人员

SpainToptal Member Since March 1, 2021

Francisco是一名技术爱好者和开发人员,在嵌入式软件方面拥有20多年的经验, 硬件设计, firmware, 和一般的软件. 他的专长包括一系列语言(c++, Assembly, and C), 工具(Altium Designer), 和库/ api (wxWidgets), STM32Cube). 他为工业和汽车领域开发了微控制器单元. 弗朗西斯科还作为自由开发者交付了几个项目,并且知道如何在国际团队中有效地工作.

Show More

Jakiša Tomić

自由c++开发人员

GermanyToptal Member Since 2019年11月13日

Jakiša拥有超过15年的经验,为一系列操作系统开发各种类型的应用程序. 他的大部分技术专长是c++开发, 但他也很擅长使用JavaScript, C#, and Java. 至于环境, 他知道使用Windows API的细节, 嵌入式编程, 和分布式系统,并具有Linux/Unix系统的工作知识, macOS, 移动平台(Android和iOS).

Show More

尤里·达·席尔瓦,维拉斯·博阿斯

自由c++开发人员

ItalyToptal Member Since 2016年10月29日

尤里获得了应用数学学士学位, 重点是金融, 在里约热内卢和圣卡塔琳娜的巴西联邦大学获得计算机科学硕士学位. 他在设计和验证协议方面有出色的工作经验, cryptography, 熟练掌握c++语言, 还有扎实的统计学背景, physics, 和数学. Yuri开发了密码格式Formosa和公钥密码系统SRVB.

Show More

Abhimanyu Veer Aditya

自由c++开发人员

United StatesToptal Member Since May 7, 2019

Abhimanyu是一名机器学习专家,拥有15年为商业和科学应用创建预测解决方案的经验. 他是一个跨职能的技术领导者, 有组建团队和与c级高管共事的经验. Abhimanyu在计算机科学和软件工程方面有着成熟的技术背景,在高性能计算方面拥有专业知识, big data, algorithms, databases, 分布式系统.

Show More

乔治Cristea

自由c++开发人员

United StatesToptal Member Since 2018年3月12日

George是一位以业绩为导向的工程领导者,拥有丰富的技术背景和业务熟练程度. 他擅长设计和实现大型分布式系统,重点关注性能和可靠性. 在他的职业生涯中, George始终以对复杂软件产品的端到端所有权的强烈意识来识别和管理技术和操作风险.

Show More

达里恩·帕迪纳斯·迪亚兹

自由c++开发人员

United StatesToptal Member Since 2018年1月9日

Darien是一位精通图像处理的软件工程师, 桌面应用程序, 以及系统开发. 在他职业生涯的早期,他是一名研究工程师, 用于获取和处理大量科学数据的书写工具. 后来,他开始为医疗设备开发符合FDA标准的软件. 最近,他一直在为一家3D打印公司编写应用软件.

Show More

现在注册以查看更多资料.

Start Hiring
经常成对

获得额外的专业知识

我们的客户经常将这些额外的服务与我们的自由c++开发人员配对.

招聘指南

聘用优秀c++开发人员指南

c++是一种功能强大的通用多范式编程语言. 语言的大量特性, 它的整体复杂性, 缺乏其他流行语言所拥有的优雅的外部工具, 对低级资源的访问使得它成为最难掌握的编程语言之一. 驯服这头猛兽需要很多经验和智慧.

阅读招聘指南

c++招聘资源

雇用c++开发人员的更多资源

工作描述模板面试问题常见的错误Jobs
Trustpilot
总体优势

在无风险试用后,98%的Toptal客户选择雇用我们的人才.

Toptal的筛选和匹配过程确保卓越的人才与您的精确需求相匹配.

Start Hiring
报纸上铺天盖地

... 允许公司快速组建具有特定项目所需技能的团队.

尽管对程序员的需求在不断增加,但Toptal对自己近乎常春藤联盟级别的审查感到自豪.

Our clients
为游戏制作应用程序
Conor Kenney
为游戏制作应用程序
构建一个跨平台的应用程序,在全球范围内使用
蒂埃里Jakicevic
构建一个跨平台的应用程序,在全球范围内使用
引领数字化转型
Elmar Platzer
引领数字化转型
挖掘实时数据将改变行业的游戏规则
挖掘实时数据将改变行业的游戏规则
Testimonials

没有Toptal就不会有Tripcents. Toptal Projects使我们能够与产品经理一起快速发展我们的基金会, 带领开发人员, 高级设计师. 在60多天的时间里,我们从概念到Alpha. 其速度、知识、专业知识和灵活性是首屈一指的. Toptal团队是tripcents的一部分,就像tripcents的任何内部团队成员一样. 他们像其他人一样贡献并拥有开发的所有权. 我们将继续使用Toptal. 作为一家初创公司,它们是我们的秘密武器.

布兰特利·佩斯,首席执行官 & Co-Founder

Tripcents

我对我们与Toptal的合作经验非常满意. 和我一起工作的专业人员在几个小时内就和我通了电话. 在和他讨论了我的项目后,我知道他就是我想要的候选人. 我立即雇用了他,他没有浪费时间就完成了我的项目, 甚至通过添加一些很棒的设计元素来增加我们的整体外观.

保罗·芬利,局长

K Dunn & Associates

与我合作的开发者都非常出色——聪明、有动力、反应灵敏. 过去很难找到高质量的工程师和顾问. Now it isn't.

瑞安·洛克菲勒首席执行官

Radeeus

Toptal立即理解了我们的项目需求. 我们遇到了一位来自阿根廷的杰出自由职业者, from Day 1, 沉浸在我们的行业中, 与我们的团队无缝融合, 理解我们的愿景, 并产生了一流的结果. Toptal使与高级开发人员和程序员的联系变得非常容易.

Jason Kulik,联合创始人

ProHatch

作为一家资源有限的小公司,我们不能犯代价高昂的错误. Toptal为我们提供了一位经验丰富的程序员,他能够立即投入工作并开始做出贡献. 这是一次很棒的经历,我们会马上再来一次.

斯图尔特·波克尼校长

现场专用软件解决方案

我们使用Toptal聘请了一位具有丰富的Amazon Web Services经验的开发人员. 我们面试了四位候选人,其中一位非常符合我们的要求. 这个过程迅速而有效.

Abner Guzmán Rivera,首席技术官和首席科学家

Photo Kharma

Sergio是一个很棒的开发者. 一流,反应迅速,工作效率高.

Dennis Baldwin,首席技术专家和联合创始人

PriceBlink

和Marcin一起工作是一种乐趣. 他很能干。, professional, flexible, 并且非常迅速地理解需要什么以及如何实现它.

安德鲁·费舍尔,首席技术官

POSTIFY

我们需要一位能立即开始我们项目的专业工程师. 西马纳斯的工作超出了我们的预期. 不需要采访和追踪专家开发人员是一种非常节省时间的方法,并且让每个人都对我们选择切换平台以使用更健壮的语言感到更舒服. Toptal使这一过程变得简单方便. Toptal现在是我们寻求专家级帮助的首选之地.

Derek Minor, Web开发高级副总裁

网络传媒集团

Toptal的开发人员和架构师都非常专业,也很容易共事. 他们提供的解决方案价格合理,质量上乘,缩短了我们的发行时间. 再次感谢,Toptal.

首席执行官杰里米·韦塞尔斯

Kognosi

我们与Toptal合作非常愉快. 他们为我们的应用程序找到了完美的开发人员,让整个过程变得非常简单. 它也很容易超出最初的时间框架, 我们可以在整个项目中保持同一个承包商. 我们强烈推荐Toptal,因为它可以快速无缝地找到高素质的人才.

Ryan Morrissey,首席技术官

应用商业技术有限责任公司

我对Toptal印象深刻. 我们的开发人员每天都和我交流,他是一个非常强大的程序员. 他是一个真正的专业人士,他的工作非常出色. Toptal 5星.

首席执行官彼得罗·卡索

浪人娱乐有限公司

与Toptal合作是一次很棒的经历. 在使用它们之前, 我花了相当多的时间面试其他自由职业者,但没有找到我需要的. 在与Toptal合作后,他们在几天内就为我找到了合适的开发者. 与我一起工作的开发人员不仅提供高质量的代码, 但他也提出了一些我没有想到的建议. 我很清楚,阿莫里知道自己在做什么. 强烈推荐!

行政总裁郑志刚

Bulavard, Inc.

作为一名Toptal合格的前端开发人员,我还经营着自己的咨询业务. 当客户来找我帮忙填补他们团队中的关键角色时, Toptal是我唯一愿意推荐的地方. Toptal的所有候选人都是精英中的精英. Toptal是我在近5年的专业在线工作中发现的性价比最高的网站.

伊桑·布鲁克斯,首席技术官

Langlotz专利 & 商标工程公司.

在希格尔的早期, 我们需要一流的开发者, 以可承受的价格, 及时地. Toptal交付!

Lara Aldag,首席执行官

Higgle

Toptal能让你轻松找到合适的人选,让你放心,因为他们有能力. 我肯定会向任何寻找高技能开发人员的人推荐他们的服务.

Michael Gluckman,数据经理

Mxit

Toptal将我们的项目与最优秀的开发人员快速匹配的能力非常出色. 开发人员已经成为我们团队的一部分, 我对他们每个人所表现出的敬业精神感到惊讶. 对于那些希望与最好的工程师远程工作的人来说,没有比Toptal更好的了.

劳伦特·阿里,创始人

Livepress

Toptal让寻找合格的工程师变得轻而易举. 我们需要一个有经验的ASP.. NET MVC架构来指导我们的启动应用程序的开发, Toptal在不到一周的时间里为我们找到了三位优秀的候选人. 在做出我们的选择后,工程师立即在线并开始工作. 这比我们自己发现和审查候选人要快得多,也容易得多.

Jeff Kelly,联合创始人

协同解决方案

我们需要一些Scala的短期工作,Toptal在24小时内为我们找到了一位优秀的开发人员. 这在其他平台上是不可能实现的.

Franco Arda,联合创始人

WhatAdsWork.com

Toptal为快速发展和规模化的企业提供不妥协的解决方案. 我们通过Toptal签约的每一位工程师都迅速融入了我们的团队,并在保持惊人的开发速度的同时,将他们的工作保持在最高的质量标准.

Greg Kimball,联合创始人

nifti.com

如何通过Toptal招聘c++开发人员

1

与我们的行业专家交谈

Toptal的工程总监将与您一起了解您的目标, 技术需求, 团队动力.
2

与精心挑选的人才一起工作

在几天内,我们将为您的项目介绍合适的c++开发人员. 平均匹配时间在24小时以下.
3

绝对合适

与您的新c++开发人员一起试用一段时间(只在满意的情况下支付报酬), 在订婚前确保他们是合适的人选.

寻找拥有相关技能的专家

在我们的人才网络中访问大量熟练的开发人员,并在48小时内雇用最优秀的3%.

FAQs

  • Toptal c++开发人员有何不同?

    At Toptal, 我们对c++开发人员进行了彻底的筛选,以确保我们只为您匹配最优秀的人才. 在200多个中,每年有5000人申请加入Toptal网络, 只有不到3%的人能达标. 你将与工程专家(而不是一般的招聘人员或人力资源代表)一起了解你的目标, 技术需求, 团队动力. 最终的结果是:经过专家审查的人才从我们的网络,定制匹配,以满足您的业务需求.

  • 我可以在48小时内通过Toptal雇佣c++开发人员吗?

    取决于可用性和进度, 您可以在注册后48小时内开始与c++开发人员合作.

  • Toptal c++开发人员的无风险试用期是什么?

    我们确保您和您的c++开发人员之间的每次约定都以长达两周的试用期开始. 这意味着你有时间确认订婚是否成功. 如果你对结果完全满意, 我们会给你开时间单的,你愿意多久我们就多久. 如果您不完全满意,我们不会向您收费. From there, 我们要么分道扬镳, 或者我们可以为您提供另一位可能更合适的专家,我们将与他开始第二轮谈判, no-risk trial.

Share
C++

如何聘请优秀的c++开发人员

c++是一个强大的, 用于从后端到嵌入式开发的所有内容的通用编程语言, 到桌面应用程序, 到它们运行的操作系统. 它是少数几种经受住时间考验的语言之一, 因此,它当之无愧地受到欢迎和尊重. 但是,尽管ISO c++标准委员会和社区努力使其对程序员更友好, 它仍然可以说是最难掌握的语言之一.

c++的特别之处?

A 伟大的c++开发者 is primarily a 优秀的软件开发人员具有很强的解决问题能力和抽象思维能力的人, 找到合适的工具和框架的能力, 以及对计算机科学的热情.

There are plenty of interview questions that are language independent and designed to check the engineering prowess of the candidate; on a more basic level, the FizzBuzz问题 在过滤一般编码能力方面是出了名的有效. 但我们目前的重点将非常具体地针对c++.

如果候选人也熟悉应用程序开发 其他语言,你就有机会让面试过程更有成效. In that case, 这前三个问题将开启一场关于不同语言哲学的有趣讨论, 它们的基本结构, 以及由此产生的优点和缺点.

问:什么是RAII ?它与没有RAII的事实有什么关系 finally c++异常处理中的关键字?

RAII代表“资源获取即初始化”,是一种特定于c++的资源管理技术. 这是基于这样一个事实:c++有析构函数,并且保证当对象超出作用域时将调用它们, 甚至在异常处理中.

We don’t need finally 来处理我们的资源,因为我们可以用RAII包装它们,并确保析构函数将被调用, thanks to 堆栈解除.

问:什么是常量正确性? 目的(价值)是什么??

const正确性是将变量和成员函数指定为 const 如果它们不打算被修改,则分别修改对象的状态. 最佳实践是使用 const 只要有可能.

const 程序员和编译器之间是否存在契约——它不会以任何方式在生成的机器代码中表现出来. It’s an elegant way 对代码进行文档化,使其更易读,不易出错. 考虑下面的代码片段:

void PaySalary(const员工Id employee_id)
{
    Employee& 雇员=公司.FindEmployee (employee_id);
    自动base_salary = employee.GetBaseSalary ();
    Const auto performance_rating = employee.MonthlyPerformance ();
    汽车债务=公司.GetDebt(员工);
    const auto total_pay = CalculateSalary(base_salary, performance_rating, debt);
    company.PaySalary(员工,total_pay);
}

在这个函数中,我们获取一个对象的引用并执行一些进一步的操作. 有人可能想知道这个对象发生了什么——特别是,它可能在什么时候被修改?

The fact that GetBaseSalary and MonthlyPerformance are const 成员函数告诉我们 employee 在这些调用之后不会改变它的状态. GetDebt takes a const员工&也就是说,它没有被修改过. The PaySalary 然而,函数需要一个 Employee&这就是我们要深入研究的地方.

在设计类时,应该特别注意const的正确性, 因为它包含给将要使用它的开发人员的消息.

更新的c++标准

在过去十年中,c++以前所未有的速度发展. 自2011年以来,我们每三年就有一个新标准:c++ 11、c++ 14、c++ 17和c++ 20. c++ 14是对c++ 11的一个小更新,但其他所有版本都带来了重要的新特性. 了解这些特征显然是必要的, 但了解他们对旧标准的替代方案也很重要.

尽管新标准中的绝大多数更改都是添加的——弃用和删除的情况非常罕见——但将代码库切换到新标准远非易事. 适当的转换,充分利用新特性,将需要大量的重构.

而且仍然有大量的c++ 98和c++ 03代码需要持续的关注和关注. c++ 11和c++ 14也是如此. 除了了解 constexpr if (c++ 17自带), 一个优秀的c++程序员也应该知道如何在使用旧标准的情况下获得同样的结果.

一个有趣的开始讨论的方法是问候选人他们最喜欢的特性是什么。. 强有力的候选人应该能够列出给定标准的最重要的特性, 选择一个最喜欢的, 并给出他们选择的理由. Of course, 没有正确或错误的答案, 但它很快就揭示了候选人对语言的感觉.

问:c++ 11/14引入了几个重要的特性. 你认为哪一个带来了最大的改善,为什么?

The auto 关键词:基于范围 for Loops

The auto 关键字使我们不必在编译器能够推断变量类型时显式地指定它. 这将产生更清晰、更易读和更通用的代码. 基于范围的 for 循环是最常见用例的语法糖.

// c++ 11之前
for (std::vector::const_iterator it = vec.begin(); it != vec.end(); ++it) {

// after C++11
For (const auto .& val : vec) {

Lambda函数

这是一种允许开发人员就地定义函数对象的新语法.

std:: count_if (vec).begin(), vec.end(), [](const int value) { return value < 10; });

Move Semantics

这允许我们显式地定义一个对象获得另一个对象的所有权意味着什么. 因此,我们得到了只能移动的类型(std:: unique_ptr, std::thread),有效的浅拷贝从临时等. 这是一个很大的话题在斯科特·迈耶斯的 有效的现代c++:提高c++ 11和c++ 14使用的42种具体方法.

智能指针

c++ 11引入了新的智能指针: unique_ptr, shared_ptr, and weak_ptr. unique_ptr 有效地使 auto_ptr obsolete.

对线程的内置支持

无需纠结于os原生和c风格的库.

问:你觉得c++ 17的哪个特性最有用?为什么?

结构化的绑定

这个特性增加了可读性.

// c++之前
For (const auto .& Name_and_id: name_to_id) {
    const auto& Name = name_and_id.first;
    const auto& Id = name_and_id.second;
 
// after C++17
For (const auto .& [name, id]: name_to_id) {

Compile-time if

With if constexpr,我们可以根据编译时条件启用代码的不同部分. 这使得模板元编程(TMP) enable_if 魔术更容易和更好地实现.

内置文件系统库

就像c++ 11中的线程支持一样, 这个内置库继续减少c++开发人员编写特定于操作系统的代码的需要. 它提供了一个接口来处理文件本身(而不是其内容)和目录, 让开发者复制它们, remove them, 递归地迭代它们, and so on.

Parallel STL

c++ 17包含了大量使用的STL算法的并行替代方案,这是一个重要的特性,因为多核处理器甚至在桌面上也变得很常见.

问:你认为c++ 20的哪个特性是一个很好的补充,为什么?

对于开发人员来说,c++ 20至少有两个很有前途的特性.

约束和概念

该特性提供了丰富的新语法,使TMP更加结构化,并且其结构可重用. 如果使用得当,它可以使代码更具可读性和更好的文档化.

Ranges

背后的c++程序员 ranges-v3图书馆 提倡将其包含在c++ 20中. 使用Unix类管道语法, 可组合结构, 惰性范围组合子, 还有其他特点, 这个库的目的是给c++一个现代的, 功能看.

std::vector numbers = …;
对于自动号码:号码
                视图| std::::变换(abs)
                | std::views::filter(is_prime)) {
    …
}
 
//不带范围的选项
For (auto orig_number: numbers) {
    自动编号= abs(orig_number);
    if (!is_prime(数量)){
        continue;
    }
    …
}

在上面的示例中, transform and filter 操作在运行时执行,不影响原容器的内容.


Initially, 内定, c++的创造者, 把它命名为“带类的C”,,其动机是支持面向对象编程(OOP). 对OOP概念和设计模式的一般理解是在语言之外的, 因此,在大多数情况下,检查c++程序员的OOP知识并不需要是特定于c++的. 然而,有一些小的特殊性. 一个很常见的面试问题是:

问:动态多态(虚函数)在c++中是如何工作的?

在c++中,动态多态是通过虚函数实现的.

class Musician
{
public:
    虚拟void Play() = 0;
};

钢琴家:公共音乐家
{
public:
    虚拟void Play() override {
        //钢琴演奏逻辑
    }
};

class吉他手:公共音乐家
{
public:
    void Play() override {
        //吉他演奏逻辑
    }
};

void AskToPlay(音乐人*音乐人)
{
    musician->Play();
}

多态性(源自希腊语 poly,意为“许多”,以及 morph(意思是“形状”)就是这样 AskToPlay 根据对象的类型以不同的方式运行 musician 指向(它可以是a Pianist or a Guitarist). 问题是c++代码必须被编译成一种机器代码,每种代码都有一组固定的指令, 包括,尤其是 AskToPlay function. 这些指令必须选择在运行时跳转(调用)到哪里 Pianist::Play or 吉他手:玩.

编译器最常用和最有效的方法是使用 虚拟表 (or vtables). 虚表是虚函数的地址数组. 每个类都有自己的虚函数表,该类的每个实例都有一个指向它的指针. 在我们的示例中,调用 Play 实际上变成了对一个函数的调用,该函数驻留在写在虚函数表的第一个条目中的地址上 *musician points to. 如果它被实例化为 Pianist,则其指向虚表的指针将被设置为 Pianist我们最终调用了正确的函数.


另一个特性来自于c++支持多重继承的事实,并且两者之间没有正式的区别 interface and a class. 经典的问题 钻石的问题 这是一个好的开始吗.

作为一种多范式编程语言, c++还支持函数式编程(FP), 在c++ 20标准中引入范围之后,这个问题变得更加重要了. 它使c++更接近另一种语言, 从功能代码的表达性和可读性的角度来看,更多的fp友好(或关注fp)语言. 一个启动问题的例子是:

问:lambda函数是如何工作的?

编译器生成一个带有 operator() 用lambda的主体, 并使用成员来存储捕获的lambda变量的副本或引用. Here’s an example.

这和另一个关于 虚函数要么候选人已经深入了解了内部,知道它是如何运作的, 或者这是一个很好的开始一般性讨论的地方,可以提出一些后续问题,比如 它们通常在什么地方派上用场? and 在lambda函数出现之前,c++编程是什么样的?.


模板元编程是c++支持的另一种范式. 它包含了许多有用的特性, 哪些已经在新标准中引入了更好的替代方案. 新功能包括 constexpr and concept让TMP不那么令人费解,但话说回来,仍然有很多产品代码带有谜题. 一个著名的TMP谜题是:

问:如何在编译时计算斐波那契数?

对于较新的标准,它就像拥有一个 constexpr 说明符在递归实现的开头.

conexpr int fibo(int n)
{
    if (n <= 1) {
        return n;
    }
    返回fibo(n - 1) + fibo(n - 2);
}

如果没有这个,它将是:

template 
struct Fibo
{
    static const int value = Fibo::value + Fibo::value;
};

template <>
struct Fibo<1>
{
    Static const int value = 1;
};

template <>
struct Fibo<0>
{
    静态常量int值= 0;
};

STL,数据结构和算法

标准模板库(STL)是一个内置在c++中的库. 它在c++中已经存在了很长时间,以至于很难将它从核心语言中分离出来. STL为c++开发人员带来了四种特性:

  • 容器——一些基本数据结构的实现,比如 vector, list, map, and unordered_map
  • 算法——一些基本算法的实现,比如 sort, binary_search, transform, and partition
  • 迭代器——用于处理算法的容器的抽象
  • 函子——一种更加定制算法的方法

STL的设计和理念是独特而广泛的. 任何优秀的c++程序员都必须对STL有很强的了解,但问题是,了解到什么程度? 第一层是所谓的 user level knowledge. 这时应聘者至少知道最流行的容器和算法, 如何以及何时使用它们. 接下来的三个问题是检验这一点的经典问题:

问:两者的区别是什么 list and vector? c++开发者应该如何选择呢?

Both list and vector 顺序容器,但基于不同的数据结构. list 是基于双链表的,而 vector 包含一个原始数组.

优势被他们平分了. vector 连续存储数据的优点是什么, 没有内存开销和固定时间索引访问. In contrast, list 具有恒定时间插入和删除在任何位置,并支持功能,如 splice, merge, and in-place sort and reverse.

As a result, vector 是更受欢迎,大多数时候是正确的选择. list 在某些极端情况下会是更好的选择吗, 就像处理重拷贝对象一样, 这样开发人员就可以让它们保持有序, 或者通过操纵节点连接从一个容器移动到另一个容器.

问:如何从a中移除所有的_42_s vector? What about a list?

最简单的方法是遍历容器并使用 erase 成员函数,这两个容器都有. 这在a的情况下是完全有效的 list; in fact, its remove 成员函数做的差不多.

但这是有原因的 vector 没有这样的 member function. 这种方法效率很低,因为 vector底层数据结构. 的元素 vector 在内存中是连续的,所以删除一个元素意味着移动 all 后面的元素后退一个位置. 这将导致大量额外的复制.

最好的方法是 erase-remove idiom:

vec.擦除(std::删除(vec).begin(), vec.End (), 42).end());
//初始化- {1,2,42,3,4,42,5,6}
//删除后- {1,2,3,4,5,6, ?, ?, }
//擦除后- {1,2,3,4,5,6}

首先,我们申请 remove 在整个范围内,它不会移除 42它只是把其他的移到最开始,而且是最有效的方式. 而不是移动 6 向左移动两个位置(如果我们单独擦除就会发生这种情况 42S),它只会移动 6 一次,差两个位置. With erase 然后,我们擦掉最后的“浪费”.

这个习语在Scott Meyers的传奇故事第32条中有很好的体现 有效的STL:提高你对标准模板库使用的50种具体方法.

问:c++中有哪些不同类型的迭代器? 哪些可以使用 std::sort?

STL迭代器有六类: input, output, forward, bidirectional, random access, and contiguous.

迭代器的类别表示它的功能,这些类别是包含的. 这意味着,说的迭代器 set is bidirectional’实际上意味着它也是 forward but neither random access nor contiguous.

STL迭代器类别的维恩图,带有每个类别的属性和示例.

类别的差异是由容器的数据结构造成的. A vector iterator is a random access 1,意思是,不像a set 迭代器,它可以在常数时间内跳转到任意点. std::sort 要求其参数为 random access iterators.


这些可以说是STL中最受欢迎的部分, 所以任何有至少一年经验的c++程序员都见过他们并和他们一起工作过. 但这还不够. 一个高质量的c++开发人员不仅要知道所有的STL容器以及如何使用它们,还要知道它们背后的抽象数据结构, 各有优缺点.

而且,他们不仅要知道大部分的算法,还要知道他们的 渐近的复杂性. 这意味着c++开发人员应该理解, in big-O terms, 标准算法的性能和它们使用的数据结构, 以及两者背后的理论. 问题可以非常具体:

STL容器基础

而不是详尽地测试这些知识, 对一些事实进行审计式的选择——如果需要的话还可以选择更多——应该足以表明候选人是否对这些普遍需要的细节有足够的了解.

  • 一个给定的容器是怎样的.g., vector] implemented?
  • [给定容器]的迭代器属于哪一类??
  • 一个给定运算的渐近复杂度是多少.g., remove在[给定的容器]上?

vector 使用大小标记将元素存储在基础数组中. When it’s full, a new, 分配更大的存储空间, 元素是从旧存储中复制的, 然后被释放. 它的迭代器是 random access category. ()的渐近复杂度push_back) is 平摊常数时间,索引访问是 constant time, remove is linear.

list 实现一个双重链表,存储指向头节点和尾节点的指针. 它的迭代器是 bidirectional. insert()的复杂度push_back and push_front) and remove (pop_back and pop_front) are constant time,而索引访问是 linear.

set and map 是否在平衡二叉搜索树上实现, 更具体地说,是红黑树, 这样就保持了元素的排序. 它们的迭代器是 bidirectional as well. 插入、查找(查找)和删除的复杂性是 logarithmic. 使用迭代器删除元素(erase 成员函数)有 平摊常数时间 complexity.

unordered_set and unordered_map 哈希表的实现是数据结构吗. 通常,它是一个所谓桶的数组,桶就是简单的链表. 为一个元素选择一个桶(在插入或查找期间)取决于它的哈希值和桶的总数. 当容器中的元素太多,平均桶大小大于实现定义的阈值(通常为1.0),则桶的数量增加,并将元素移动到正确的桶中. 这个过程叫做 rehashing,这使得插入变得复杂 平摊常数时间. 查找并删除 constant time complexities.

这些是最基本的容器—必须了解上述细节, 但是否每一个细节都经过测试取决于面试官的直觉.

问:给定算法的渐近复杂度是多少??

一些著名的STL算法的渐近复杂性是:

AlgorithmComplexity
std::sortO(N log(N))
std:: nth_elementO(N)
std::advanceO(1) for 随机存取迭代器,否则为0 (N)
std:: binary_searchO(log(N)) for 随机存取迭代器,否则为0 (N)
std:: set_intersectionO(N)

或者,用一个简单的问题来解决所有问题:

问:哪些集装箱可以使用 insertion 操作使迭代器失效?

这个问题的巧妙之处在于它很难被记住, 正确的答案需要对容器的底层数据结构和一些逻辑有广泛的了解.

The insertion 操作可能使上的迭代器失效 vector, string, deque, and unordered_set /地图 (在扩展/重新散列的情况下). For list, set, and map但是,由于它们基于节点的数据结构,情况并非如此.


在许多开发人员面试中,提供一个计算问题并期望候选人开发一种算法来解决它是标准的. 有很多优秀的c++编程平台,比如LeetCode、HackerRank等. 充满了这样的问题.

这些问题很有价值,因为它们可以一次检查很多事情. 大多数面试官会故意从一个不明确的问题陈述开始,以测试候选人解决问题的技巧和提出正确问题的能力. Then, 候选人必须解决问题, write the code, and, 最重要的是, 做一个复杂性分析.

在使用STL容器和算法时,擅长后者并拥有强大的数据结构知识足以做出明智的决策, 还有写新的. 有些人可能会更进一步,看看实际的实现. 每个人都会在某些时候使用STL代码,要么是偶然的,要么是在调试时,要么是自愿的. 如果候选人去了那里,并设法弄明白了那些胡言乱语, 这说明了他们的经历, curiosity, 和毅力. For example:

问:哪种排序算法可以 std::sort implement?

The ISO C++ standard doesn’t specify the algorithm; it only sets the requirement of 渐近的复杂性. 然后,选择取决于实现(例如.e.微软vs .微软. GNU.)

它们中的大多数不会只用一个算法来解决,比如 mergesort or quicksort. 一种常见的方法是将它们混合使用,或者根据大小选择一种. 例如,GCC实现了 introsort,这是一个混合的 quicksort and heapsort. 它从第一个开始,并在长度小于实现定义的阈值时切换到堆排序.

c++:久经考验,但开发团队必须善于避免它的陷阱

本指南中列出的问题涵盖了c++编程的一些基本方面和一些棘手的方面. 但就像它的可能性一样, 语言隐藏的惊喜是无限的, 这使得在面试中很难涵盖所有关于c++的内容. Therefore, 评估候选人的能力是必要的, skill set, 通过清晰生动地表达自己的想法,对c++有了深刻的理解.

我们希望这些问题能在你寻找全职或兼职的真正高质量的c++专家时起到指导作用. 这些罕见的精英可能很难得到, 但对于您的c++编程团队来说,它们将明显地从其他包中脱颖而出.

顶级c++开发人员需求量很大.

Start Hiring