Julie has over 20 years of experience building software applications and leading engineering teams for businesses of all sizes. 她是Java方面的专家, JavaScript, C, C++, and Perl, 并且熟悉许多流行的框架. 最近,Julie为沃尔玛设计并实现了一个大规模的Oracle数据库分片解决方案.com.
Mike is a software architect and developer with over 25 years of experience developing large-scale mission-critical systems. 他目前专注于Java和J2EE开发, c++和C开发, 以及物联网的嵌入式系统. 此外,他是国际公认的彩票博彩系统领域的专家. 在过去的16年里,Mike一直在为不同地域的团队提供解决方案.
尼克从事编程工作已有十多年了. 他的专长包括React前端,Node.js back ends, C++, games, graphics, and numerous programming languages. After starting his technology career because he wanted to make games, 从那以后,他拓展到新的领域. 知名客户包括LinkedIn和哈雷戴维森(Harley-Davidson). 尼克喜欢不断学习新事物,不断成长和提高.
Ted is a software developer and programmer with 20 years of professional programming experience and close to 25 years of experience programming in C and C++ and almost as long in Python. He enjoys finding clean solutions and producing high-quality, high-value code. Ted also excels at porting and building maintainable cross-platform software and is skilled as a runtime-performance optimizer. 简而言之,泰德写的软件只是工作而已.
Francisco是一名技术爱好者和开发人员,在嵌入式软件方面拥有20多年的经验, 硬件设计, firmware, 和一般的软件. 他的专长包括一系列语言(c++, Assembly, and C), 工具(Altium Designer), 和库/ api (wxWidgets), STM32Cube). He’s developed microcontroller units for the industrial and automotive fields. Francisco also has delivered several projects as a freelance developer and knows how to work effectively within an international team.
Jakiša拥有超过15年的经验,为一系列操作系统开发各种类型的应用程序. 他的大部分技术专长是c++开发, 但他也很擅长使用JavaScript, C#, and Java. 至于环境, 他知道使用Windows API的细节, 嵌入式编程, 分布式系统 and has a working knowledge of Linux/Unix systems, macOS, 移动平台(Android和iOS).
尤里获得了应用数学学士学位, 重点是金融, and a master's degree in computer science from the Brazilian Federal Universities of Rio de Janeiro and Santa Catarina. He has excellent work experience in designing and verifying protocols, cryptography, 熟练掌握c++语言, 还有扎实的统计学背景, physics, 和数学. Yuri开发了密码格式Formosa和公钥密码系统SRVB.
Abhimanyu is a machine learning expert with 15 years of experience creating predictive solutions for business and scientific applications. 他是一个跨职能的技术领导者, 有组建团队和与c级高管共事的经验. Abhimanyu has a proven technical background in computer science and software engineering with expertise in high-performance computing, big data, algorithms, databases, 分布式系统.
George is a performance-oriented engineering leader with a substantial technology background and business proficiency. He specializes in designing and implementing large-scale distributed systems with a focus on performance and reliability. 在他的职业生涯中, George has consistently identified and managed the technology and operational risks with a strong sense of end-to-end ownership for complex software products.
Darien is an accomplished software engineer with expertise in image processing, 桌面应用程序, 以及系统开发. He worked as a research engineer in the early stages of his career, writing tools to acquire and process large volumes of scientific data. 后来,他开始为医疗设备开发符合FDA标准的软件. Recently, he's been writing application software for a 3D printing company.
c++是一个强大的 general purpose multi-paradigm programming language. 语言的大量特性, 它的整体复杂性, lack of elegant external tooling that other popular languages have, 对低级资源的访问使得它成为最难掌握的编程语言之一. 驯服这头猛兽需要很多经验和智慧.
没有Toptal就不会有Tripcents. Toptal Projects使我们能够与产品经理一起快速发展我们的基金会, lead developer, 高级设计师. 在60多天的时间里,我们从概念到Alpha. The speed, knowledge, expertise, and flexibility is second to none. Toptal团队是tripcents的一部分,就像tripcents的任何内部团队成员一样. They contributed and took ownership of the development just like everyone else. 我们将继续使用Toptal. 作为一家初创公司,它们是我们的秘密武器.
布兰特利·佩斯,首席执行官 & Co-Founder
Tripcents
我对我们与Toptal的合作经验非常满意. 和我一起工作的专业人员在几个小时内就和我通了电话. I knew after discussing my project with him that he was the candidate I wanted. I hired him immediately and he wasted no time in getting to my project, 甚至通过添加一些很棒的设计元素来增加我们的整体外观.
保罗·芬利,局长
K Dunn & Associates
与我合作的开发者都非常出色——聪明、有动力、反应灵敏. 过去很难找到高质量的工程师和顾问. Now it isn't.
瑞安·洛克菲勒首席执行官
Radeeus
Toptal立即理解了我们的项目需求. 我们遇到了一位来自阿根廷的杰出自由职业者, from Day 1, 沉浸在我们的行业中, 与我们的团队无缝融合, 理解我们的愿景, 并产生了一流的结果. Toptal makes connecting with superior developers and programmers very easy.
Jason Kulik,联合创始人
ProHatch
作为一家资源有限的小公司,我们不能犯代价高昂的错误. Toptal provided us with an experienced programmer who was able to hit the ground running and begin contributing immediately. It has been a great experience and one we'd repeat again in a heartbeat.
斯图尔特·波克尼校长
现场专用软件解决方案
我们使用Toptal聘请了一位具有丰富的Amazon Web Services经验的开发人员. 我们面试了四位候选人,其中一位非常符合我们的要求. 这个过程迅速而有效.
Abner Guzmán Rivera,首席技术官和首席科学家
Photo Kharma
Sergio是一个很棒的开发者. 一流,反应迅速,工作效率高.
Dennis Baldwin,首席技术专家和联合创始人
PriceBlink
和Marcin一起工作是一种乐趣. 他很能干。, professional, flexible, and extremely quick to understand what is required and how to implement it.
安德鲁·费舍尔,首席技术官
POSTIFY
We needed a expert engineer who could start on our project immediately. 西马纳斯的工作超出了我们的预期. Not having to interview and chase down an expert developer was an excellent time-saver and made everyone feel more comfortable with our choice to switch platforms to utilize a more robust language. Toptal使这一过程变得简单方便. Toptal现在是我们寻求专家级帮助的首选之地.
我们与Toptal合作非常愉快. 他们为我们的应用程序找到了完美的开发人员,让整个过程变得非常简单. 它也很容易超出最初的时间框架, and we were able to keep the same contractor throughout our project. 我们强烈推荐Toptal,因为它可以快速无缝地找到高素质的人才.
Ryan Morrissey,首席技术官
应用商业技术有限责任公司
我对Toptal印象深刻. Our developer communicates with me every day, and is a very powerful coder. 他是一个真正的专业人士,他的工作非常出色. Toptal 5星.
As a Toptal qualified front-end developer, I also run my own consulting practice. 当客户来找我帮忙填补他们团队中的关键角色时, Toptal是我唯一愿意推荐的地方. Toptal的所有候选人都是精英中的精英. Toptal是我在近5年的专业在线工作中发现的性价比最高的网站.
Toptal为快速发展和规模化的企业提供不妥协的解决方案. Every engineer we've contracted through Toptal has quickly integrated into our team and held their work to the highest standard of quality while maintaining blazing development speed.
Greg Kimball,联合创始人
nifti.com
如何通过Toptal招聘c++开发人员
1
与我们的行业专家交谈
A Toptal director of engineering will work with you to understand your goals, 技术需求, 团队动力.
2
与精心挑选的人才一起工作
Within days, we'll introduce you to the right C++ developer for your project. 平均匹配时间在24小时以下.
3
绝对合适
Work with your new C++ developer for a trial period (pay only if satisfied), 在订婚前确保他们是合适的人选.
At Toptal, 我们对c++开发人员进行了彻底的筛选,以确保我们只为您匹配最优秀的人才. 在200多个中,每年有5000人申请加入Toptal网络, 只有不到3%的人能达标. 你将与工程专家(而不是一般的招聘人员或人力资源代表)一起了解你的目标, 技术需求, 团队动力. 最终的结果是:经过专家审查的人才从我们的网络,定制匹配,以满足您的业务需求.
我可以在48小时内通过Toptal雇佣c++开发人员吗?
取决于可用性和进度, you could start working with a C++ developer within 48 hours of signing up.
Toptal c++开发人员的无风险试用期是什么?
We make sure that each engagement between you and your C++ developer begins with a trial period of up to two weeks. This means that you have time to confirm the engagement will be successful. 如果你对结果完全满意, 我们会给你开时间单的,你愿意多久我们就多久. 如果您不完全满意,我们不会向您收费. From there, 我们要么分道扬镳, 或者我们可以为您提供另一位可能更合适的专家,我们将与他开始第二轮谈判, no-risk trial.
A 伟大的c++开发者 is primarily a 优秀的软件开发人员: someone with a strong problem-solving skillset and abstract thinking, 找到合适的工具和框架的能力, 以及对计算机科学的热情.
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++.
如果候选人也熟悉应用程序开发 其他语言, there’s an opportunity to make the interview process even more fruitful. In that case, 这前三个问题将开启一场关于不同语言哲学的有趣讨论, 它们的基本结构, 以及由此产生的优点和缺点.
Q: What is RAII and how does it relate to the fact that there is no finally c++异常处理中的关键字?
RAII代表“资源获取即初始化”,是一种特定于c++的资源管理技术. It’s based on the fact that C++ has destructors and a guarantee that they’ll be called for an object when it’s going out of scope, 甚至在异常处理中.
We don’t need finally 来处理我们的资源,因为我们可以用RAII包装它们,并确保析构函数将被调用, thanks to 堆栈解除.
const is a contract between the programmer and the compiler—it doesn’t manifest itself in the generated machine code in any way. It’s 优雅的方式 对代码进行文档化,使其更易读,不易出错. 考虑下面的代码片段:
The fact that GetBaseSalary and MonthlyPerformance are const 成员函数告诉我们 employee 在这些调用之后不会改变它的状态. GetDebt takes a const Employee&也就是说,它没有被修改过. The PaySalary 然而,函数需要一个 Employee&这就是我们要深入研究的地方.
在设计类时,应该特别注意const的正确性, 因为它包含给将要使用它的开发人员的消息.
更新的c++标准
C++ has picked up an unprecedented pace of development during the last decade. 自2011年以来,我们每三年就有一个新标准:c++ 11、c++ 14、c++ 17和c++ 20. c++ 14是对c++ 11的一个小更新,但其他所有版本都带来了重要的新特性. 了解这些特征显然是必要的, but it’s also important to know their alternatives for the older standards.
Even though the vast majority of the changes in the newer standards are additions—deprecations and removals are very rare—switching a codebase to a new standard is far from easy. 适当的转换,充分利用新特性,将需要大量的重构.
而且仍然有大量的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函数
This is a new syntax allowing developers to define function objects in-place.
std:: count_if (vec).begin(), vec.end(), [](const int value) { return value < 10; });
移动语义
这允许我们显式地定义一个对象获得另一个对象的所有权意味着什么. 因此,我们得到了只能移动的类型(std:: unique_ptr, std::thread),有效的浅拷贝从临时等. This is a pretty big topic nicely covered by a chapter of Scott Meyers’ Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14.
智能指针
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
Parallel alternatives of much-used STL algorithms are included with C++17—an important feature ever since multi-core processors have become commonplace even on the desktop.
Q: Which feature of C++20 do you think is a nice addition, and why?
对于开发人员来说,c++ 20至少有两个很有前途的特性.
约束和概念
该特性提供了丰富的新语法,使TMP更加结构化,并且其结构可重用. If used properly, it can make code more readable and better-documented.
多态性(源自希腊语 poly,意为“许多”,以及 morph(意思是“形状”)就是这样 AskToPlay 根据对象的类型以不同的方式运行 musician 指向(它可以是a Pianist or a Guitarist). 问题是c++代码必须被编译成一种机器代码,每种代码都有一组固定的指令, 包括,尤其是 AskToPlay function. Those instructions have to choose where to jump (call) at run-time, to Pianist::Play or 吉他手:玩.
编译器最常用和最有效的方法是使用 虚拟表 (or vtables). 虚表是虚函数的地址数组. 每个类都有自己的虚函数表,该类的每个实例都有一个指向它的指针. 在我们的示例中,调用 Play 实际上变成了对一个函数的调用,该函数驻留在写在虚函数表的第一个条目中的地址上 *musician points to. 如果它被实例化为 Pianist,则其指向虚表的指针将被设置为 Pianist我们最终调用了正确的函数.
Another specificity comes from the fact that C++ supports multiple inheritance and there is no formal distinction between an interface and a class. 经典的问题 钻石的问题 这是一个好的开始吗.
作为一种多范式编程语言, c++还支持函数式编程(FP), 在c++ 20标准中引入范围之后,这个问题变得更加重要了. 它使c++更接近另一种语言, more FP-friendly (or FP-focused) languages from the point of view of the expressiveness and readability of the functional code. 一个启动问题的例子是:
问:lambda函数是如何工作的?
编译器生成一个带有 operator() 用lambda的主体, 并使用成员来存储捕获的lambda变量的副本或引用. Here’s an example.
这和另一个关于 虚函数: Either the candidate has looked under the hood and knows exactly how it works, 或者这是一个很好的开始一般性讨论的地方,可以提出一些后续问题,比如 它们通常在什么地方派上用场? and 在lambda函数出现之前,c++编程是什么样的?.
模板元编程是c++支持的另一种范式. 它包含了许多有用的特性, which have been accompanied by better alternatives introduced in newer standards. 新功能包括 constexpr and concept让TMP不那么令人费解,但话说回来,仍然有很多产品代码带有谜题. 一个著名的TMP谜题是:
Containers—implementations of some fundamental data structures, like vector, list, map, and unordered_map
算法——一些基本算法的实现,比如 sort, binary_search, transform, and partition
Iterators—an abstraction of containers for algorithms to work with
函子——一种更加定制算法的方法
STL的设计和理念是独特而广泛的. 任何优秀的c++程序员都必须对STL有很强的了解,但问题是,了解到什么程度? 第一层是所谓的 user level knowledge. 这时应聘者至少知道最流行的容器和算法, 如何以及何时使用它们. 接下来的三个问题是检验这一点的经典问题:
问:两者的区别是什么 list and vector? c++开发者应该如何选择呢?
Both list and vector 顺序容器,但基于不同的数据结构. list 是基于双链表的,而 vector 包含一个原始数组.
优势被他们平分了. vector 连续存储数据的优点是什么, 没有内存开销和固定时间索引访问. In contrast, list 具有恒定时间插入和删除在任何位置,并支持功能,如 splice, merge,以及就地 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 are consecutive in the memory, so erasing an element means shifting all 后面的元素后退一个位置. 这将导致大量额外的复制.
首先,我们申请 remove 在整个范围内,它不会移除 42它只是把其他的移到最开始,而且是最有效的方式. 而不是移动 6 to the left twice by one position (which would happen if we individually erased 42S),它只会移动 6 一次,差两个位置. With erase 然后,我们擦掉最后的“浪费”.
This idiom is nicely covered in Item 32 of Scott Meyers’ legendary 有效的STL:提高你对标准模板库使用的50种具体方法.
问:c++中有哪些不同类型的迭代器? 哪些可以使用 std::sort?
STL迭代器有六类: input, output, forward, bidirectional, random access, and contiguous.
迭代器的类别表示它的功能,这些类别是包含的. 这意味着,说的迭代器 set is bidirectional’实际上意味着它也是 forward but neither random access nor contiguous.
Differences of the categories are due to the data structures of the containers. A vector iterator is a random access 1,意思是,不像a set 迭代器,它可以在常数时间内跳转到任意点. std::sort 要求其参数为 random access iterators.
这些可以说是STL中最受欢迎的部分, 所以任何有至少一年经验的c++程序员都见过他们并和他们一起工作过. 但这还不够. A high-quality C++ developer has to know not only all the STL containers and how to use them but also the abstract data structures behind them, 各有优缺点.
Also, not only should they know most of the algorithms but also their 渐近的复杂性. 这意味着c++开发人员应该理解, in big-O terms, the performance of standard algorithms and the data structures they use, 以及两者背后的理论. 问题可以非常具体:
STL容器基础
而不是详尽地测试这些知识, an audit-style selection of a few facts—more if needed—should make it clear enough whether the candidate is well-versed enough in these commonly-needed details.
一个给定的容器是怎样的.g., vector] implemented?
[给定容器]的迭代器属于哪一类??
一个给定运算的渐近复杂度是多少.g., remove在[给定的容器]上?
vector 使用大小标记将元素存储在基础数组中. When it’s full, a new, 分配更大的存储空间, 元素是从旧存储中复制的, 然后被释放. 它的迭代器是 random access category. ()的渐近复杂度push_back) is 平摊常数时间,索引访问是 constant time, remove is linear.
list implements a doubly linked list, storing pointers to the head and tail nodes. 它的迭代器是 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 哈希表的实现是数据结构吗. Usually, it’s an array of so-called buckets, which are simply linked lists. A bucket is chosen for an element (during the insert or lookup) depending on its hash value and the total number of buckets. When there are so many elements in the container that the average bucket size is greater than an implementation-defined threshold (usually 1.0),则桶的数量增加,并将元素移动到正确的桶中. 这个过程叫做 rehashing,这使得插入变得复杂 平摊常数时间. 查找并删除 constant time complexities.
这些是最基本的容器—必须了解上述细节, 但是否每一个细节都经过测试取决于面试官的直觉.
问:给定算法的渐近复杂度是多少??
一些著名的STL算法的渐近复杂性是:
Algorithm
Complexity
std::sort
O(N log(N))
std:: nth_element
O(N)
std::advance
O(1) for 随机存取迭代器,否则为0 (N)
std:: binary_search
O(log(N)) for 随机存取迭代器,否则为0 (N)
std:: set_intersection
O(N)
或者,用一个简单的问题来解决所有问题:
问:哪些集装箱可以使用 insertion 操作使迭代器失效?
The elegance of this question is that it’s very hard to just remember, and the right answer requires extensive knowledge of underlying data structures of the containers with some logic.
The insertion 操作可能使上的迭代器失效 vector, string, deque, and unordered_set /地图 (在扩展/重新散列的情况下). For list, set, and map但是,由于它们基于节点的数据结构,情况并非如此.
It’s standard in many developer interviews to provide a computational problem and expect the candidate to develop an algorithm to solve it. 有很多优秀的c++编程平台,比如LeetCode、HackerRank等. 充满了这样的问题.
These questions are valuable in that they check a lot of things at once. Most interviewers will start with an intentionally underspecified problem statement to test the candidate’s problem-tackling skills and ability to ask the right questions. Then, 候选人必须解决问题, 编写代码, and, 最重要的是, 做一个复杂性分析.
Being good at the latter and having strong knowledge of data structures is quite enough to make wise decisions when using STL containers and algorithms, 还有写新的. 有些人可能会更进一步,看看实际的实现. 每个人都会在某些时候使用STL代码,要么是偶然的,要么是在调试时,要么是自愿的. If the candidate went there and managed to make sense of that gibberish, 这说明了他们的经历, 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. It starts with the first and switches to heapsort when the length is less than the implementation-defined threshold.
c++:久经考验,但开发团队必须善于避免它的陷阱
本指南中列出的问题涵盖了c++编程的一些基本方面和一些棘手的方面. 但就像它的可能性一样, 语言隐藏的惊喜是无限的, and that makes it difficult to cover everything about C++ in interviews. Therefore, 评估候选人的能力是必要的, skill set, 通过清晰生动地表达自己的想法,对c++有了深刻的理解.
We hope these questions will help you as a guide in your search for a true high-quality C++ expert in either a full-time or part-time role. 这些罕见的精英可能很难得到, 但对于您的c++编程团队来说,它们将明显地从其他包中脱颖而出.