今天面试阿里后端开发,

● 面试官提问:谈谈你对 const 理解

● 我这样回答的: const 仅仅表示变量不能修改,太简答了,我早就知道了。

● 面试官回复:你觉得 这样能面过 P7 ,百万年薪岗位吗。

痛定思痛,今天,聊聊比较重要性能优化的思路:

● 编译期优化

● 从 cpu 角度理解 编译期优化

一. 在项目中带来什么收益,why

1.1 编译期计算

● 所有比较在编译期完成,零运行时开销。

● 例如 if constexpr std::is_same_v (先别走看,不同特性,有着同样原理)

● 更多阅读 CppCon 2014

CppCon 2014: Walter E. Brown "Modern Template Metaprogramming: A Compendium, Part I

1.2 为什么能带来这样收益,第一性原理或者核心实现原理 是什么?

std::is_same_v 是 C++17 引入的编译期类型比较工具,

用于判断两个类型是否严格相同。

if T and U name the same type (taking into account const/volatile qualifications),

provides the member constant value equal to true. Otherwise value is false.

● 具备内部实现先不考虑

● is_same_v 是 is_same<T, U>::value 的简写:

template <typename T, typename U>

inline constexpr bool is_same_v = is_same<T, U>::value;

其底层基于模板元编程中的偏特化机制实现:

与 typeid 的对比

特性 std::is_same_v typeid

比较阶段 编译期 运行时

多态类型 静态类型 动态类型(可能派发到派生类)

性能影响 零开销 RTTI 开销

适用场景 模板元编程、静态检查 运行时类型识别、调试

typeid 运算符

// expre_typeid_Operator.cpp

// compile with: /GR /EHsc

include

include

class Base {

public:

virtual void vvfunc() {}

};

class Derived : public Base {};

using namespace std;

//typeid 运算符允许在运行时确定对象的类型。

int main() {

Derived* pd = new Derived;

Base* pb = pd;

cout << typeid( pb ).name() << endl; //prints "class Base *"

cout << typeid( *pb ).name() << endl; //prints "class Derived"

cout << typeid( pd ).name() << endl; //prints "class Derived *"

cout << typeid( *pd ).name() << endl; //prints "class Derived"

delete pd;

}

if constexpr

● 在普通代码中用 if constexpr 基本没有实际用途。

● if constexpr 是 C++17 引入的编译期条件判断语句。

它在编译时判断条件,如果条件为假,则不会对分支内的代码进行实例化

与模板的关系 在模板中,if constexpr 可以根据模板参数的类型或值,在编译期选择不同的代码路径

● 核心原理:编译时分支决策 编译时条件求值

if constexpr 的条件必须是编译时常量表达式(如 std::is_same_v<T, int>)。编译器在模板实例化或代码生成阶段直接计算条件值,而非运行时

● 分支代码选择性编译

○ 条件为 true:仅编译 if 分支的代码,else 分支(若有)被完全丢弃,不进行语法检查。

○ 条件为 false:仅编译 else 分支,if 分支代码被丢弃

特性 if constexpr 普通 if

条件求值时机 编译时 运行时

分支代码处理 仅编译匹配分支,丢弃其余 编译所有分支,运行时选择执行

语法检查范围 仅检查匹配分支 检查所有分支的语法合法性

适用场景 模板元编程、类型分发 运行时条件判断

无效代码安全性 丢弃分支可包含无效代码 所有分支必须语法合法

1.3 预计多大收益:CPU的分支预测是如何影响程序运行

● 性能优化利器之constexpr

● 消除分支预测失败开销

● 原理:传统 if 在运行时进行分支预测,失败时需清空流水线(约 10~20 周期开销)2。

● if constexpr 优势:在编译时丢弃未匹配分支,生成无分支跳转的代码,彻底避免预测失败17。

● 案例:在 LLVM 编译器中,模板元编程改用 if constexpr 后,解析器的吞吐量提升 12%~15%(测试数据基于 SPEC CPU 2017)

● 实际性能测试对比

测试场景 传统 if

/ SFINAE if constexpr 提升幅度

类型分发(百万次调用) 42 ms 29 ms 31%

JSON 解析(大文件) 78 MB/s 吞吐量 92 MB/s 吞吐量 18%

网络协议处理(小包) 4.2 μs/包 3.5 μs/包 17%

二、举例说明

把字符串变成整数

该函数利用模板和 if constexpr,实现了“根据目标类型自动选择合适的字符串转数值函数”。

只有支持的类型(int、long、long long、double)会被实例化

include

include

include <type_traits>

using namespace std;

template

T str_to_num(const std::string& s)

{

if constexpr (is_same_v<T, int>) {

return std::stoi(s);//如果转换成功的话,stoi函数将会把转换后的得到数字以int类型返回

} else if constexpr (is_same_v<T, long>) {

return std::stol(s);

} else if constexpr (is_same_v<T, long long>) {

return std::stoll(s); //long long stoll

} else if constexpr (is_same_v<T, double>) {

return std::stod(s);

}

}

//g++ 3_if.cpp -std=c++17

int main() {

std::string s4 = "3.14159";

double d = str_to_num(s4);

std::cout << "double: " << d << std::endl;

return 0;

}

2.2 序列化 不存在的字段对应类构造

案例:从谷歌事故报告看技术透明度:我们差的不是SRE,是承认问题的勇气 。配置一个空策略导致解析 null 这几张

业务人员:清楚 什么字段 对应什么类型。

template

bool JSONDecoder::decode_json(const char *name, T& val, JSONObj *obj, bool mandatory)

{

JSONObjIter iter = obj->find_first(name);

if (iter.end()) {

if (mandatory) {

std::string s = "missing mandatory field " + std::string(name);

throw err(s);

}

if constexpr (std::is_default_constructible_v) {

val = T();

}

// 如果条件为 true,那么 {} 里面的代码 val = T(); 就会被编译。

return false;

}

保证了代码的健壮性:

它确保了即使 JSON 中缺少了某个可选字段,

你的变量也能被初始化为一个合理、确定的"空"状态,

而不是未定义的值。

在大型分布式系统如 Ceph、GlusterFS、分布式 KV 引擎(如 RocksDB)开发过程中,我们常常需要根据类型 T 的特性(是否可构造、可拷贝、可移动)来决定容器行为、初始化策略、内存对齐方式甚至 IO 缓冲区创建方式。

std::is_default_constructible 是 C++ 类型萃取(Type Traits)体系的一部分,它提供了一种在编译期判断类型是否支持默认构造的机制

template< class T >

inline constexpr bool is_default_constructible_v = is_default_constructible::value;

三、CPU眼里的C/C++

使用到工具

https://godbolt.org/

● 或者 gdb

3.1 编译期计算 什么含义

● const 与 constexpr 同样效果效果

int main() {

const int val = 1 + 2; //明确一数值

return 0;

}

上述代码汇编结果如下:

main:

push rbp

mov rbp, rsp

mov DWORD PTR [rbp-4], 3

mov eax, 0

pop rbp

ret

从上述汇编结果可以看出,在编译阶段就将val赋值成3,也就是说在编译阶段完成了求值操作

相反 普通的函数 求值过程将会延后至运行时候

constexpr int val = 1 + 2;//性能优化利器之constexpr

3.2 if constexpr 和 if 区别

三个 if 判断,最后编译代码后只有 1 个

基础回顾:c++代码生成的汇编代码

步骤 命令 等价命令 输出文件

预处理 cpp gcc -E .i, .ii

编译 cc1, cc1plus gcc -S .s

汇编 as gcc -c .o, .obj

链接 ld gcc 可执行文件

1 GCC编译C/C++的四个过程

gcc 是 GUN Compiler Collection的缩写。

预处理(pre-processing),E:插入头文件,替换宏,展开宏

gcc -E main.c -o main.i

编译(Compiling)S:编译成汇编

gcc -S main.i –o main.s

汇编(Assembling) c:编译成目标文件

gcc –c main.s –o main.o

链接 (Linking):链接到库中,变成可执行文件

gcc main.o –o main

./main

也可以一次性完成:

gcc main.c –o main

g++ test.cpp -o test

objdump -d tes

最动人的作品,为自己而写,刚刚好打动别人

我在寻找一位积极上进的小伙伴,

一起参与神奇早起 30 天改变人生计划,发展个人事业,不妨 试试

1️⃣关注公众号:后端开发成长指南(回复面经获取)获取过去我全部面试录音和大厂面试复盘攻略

2️⃣ 感兴趣的读者可以通过公众号获取老王的联系方式。

加入我的技术交流群Offer 来碗里 (回复“面经”获取),一起抱团取暖

----------------我是黄金分割线-----------------------------

抬头看天:走暗路、耕瘦田、进窄门、见微光,

● 我要通过技术拿到百万年薪P7职务,别人投入时间完成任务,别人采取措施解决问题了,不要不贪别人功劳,

● 但是不要给自己这样假设:别人完成就等着自己完成了,大家一个集团,一个公司,分工不同,不,这个懒惰表现,这个逃避问题表现,

● 别人不这么假设,至少kpi上不会写成自己的,至少晋升不是你,裁员淘汰是,你的整个公司ceo,整个部门总裁,整个领导不帮助一下的,他们不这么想 ,你什么没做,战略是别人10年一点带你研究的多难,项目拆分别人10年完成多少问题,项目实现10年安排组织一点点完成多少bug,多少代码,是不要给自己这样假设:你等了看了观察10年什么做 ,0 贡献,

● 但是不要给自己这样假设,别人全部市场,别人全部市场,别人占据全部客户,一切重要无比,你太差,太才,思考不行,沟通不行,认知不行,去tmd,给别人丢脸。这个方面我无法控制,在这方面经历任何问题应该的。

● 我控制 的事情是 我必须亲自了解行业遇到难题,了解有什么需求,行业解决方案,我可以从三万英尺看问题,像周围人学习,像免费公开英文资料学习,从模仿开始。然后免费公开。我要通过技术拿到百万年薪P7职务,我必须糊涂混沌中走出来

● 目标:拿百万年 想进入一线大厂,但在C++学习和应用上存在瓶颈,渴望跨越最后一道坎。

● 现状:缺乏实战,渴望提升动手能力公司的项目不会重构,没有重新设计的机会,导致难以深入理解需求。

● 成为优秀完成任务,成为团队、公司都认可的核心骨干。优秀地完成任务= 高效能 + 高质量 + 可持续 + 可度量

低头走路:

● 一次专注做好一个小事。

● 不扫一屋 何以扫天下,让自己早睡,早起,锻炼身体,刷牙保持个人卫生,多喝水 ,表达清楚 基本事情做好。

● 我控制 的事情是 我通过写自己代码拿到百万收益。代码就是杠杆,我必须创造可以运行在2c2g云主机小而美产品出来(服务普通人),而不是运行构建至少10台64cpu 300g内存物理机大而全项目(领航者,超越其他产品,出货全球N1,这个还是有停留有限斗争游戏,为top 10人企业服务)我必须糊涂混沌中走出来

阿里P7,竟问这么简单的题目?的更多相关文章

  1. 面阿里P7,竟问这么简单的题目?

    关于作者:程序猿石头(ID: tangleithu),来自十八县贫困农村(查看我的逆袭之路),BAT某厂P7,是前大疆(无人机)技术主管,曾经也在创业公司待过,有着丰富的经验. 本文首发于微信公众号, ...

  2. 阿里P7岗位面试,面试官问我:为什么HashMap底层树化标准的元素个数是8

    前言 先声明一下,本文有点标题党了,像我这样的菜鸡何德何能去面试阿里的P7岗啊,不过,这确实是阿里p7级岗位的面试题,当然,参加面试的人不是我,而是我部门的一个大佬.他把自己的面试经验分享给了我,也让 ...

  3. 转头条:阿里p7架构师:三年经验应该具备什么样的技能?

    问:工作中,有时候实现一个功能,会去看有没有现成的轮子可用.对于重复造轮子与改造轮子有什么看法? 答:一定会的,其实这也是一个提高技术能力的方法,比如今天想做个日期转换的功能,JDK8有日期的新特性就 ...

  4. 跟着阿里p7一起学java高并发 - 第18天:玩转java线程池,这一篇就够了

    java中的线程池,这一篇就够了 java高并发系列第18篇文章. 本文主要内容 什么是线程池 线程池实现原理 线程池中常见的各种队列 自定义线程创建的工厂 常见的饱和策略 自定义饱和策略 线程池中两 ...

  5. 阿里P7终于讲完了JDK+Spring+mybatis+Dubbo+SpringMvc+Netty源码

    前言 这里普及一下,每个公司都有职别定级系统,阿里也是,技术岗以 P 定级,一般校招 P5, 社招 P6 起.其实阅读源码也是有很多诀窍的,这里分享几点心得: 首先要会用.你要知道这个库是干什么的,掌 ...

  6. grep查询文本:问一个简单shell问题,将grep的输出赋值给一个变量

    问一个简单shell问题,将grep的输出赋值给一个变量 用grep命令得到的输出赋值给一个变量不成功. grep命令如下: 代码: $ grep -c '^abc' file.txt 输出为22,表 ...

  7. 阿里云api调用做简单的cmdb

    阿里云api调用做简单的cmdb 1 步骤 事实上就是调用阿里api.获取可用区,比方cn-hangzhou啊等等.然后在每一个区调用api 取ecs的状态信息,最好写到一个excel里面去.方便排序 ...

  8. 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术

    这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...

  9. 分享一套主流框架源码资料,征服阿里 P7 面试必备!

    2019年已经过完一半了, 我在这里为大家准备了一份资料,征服阿里 P7 面试必备! 希望这些资料可以帮助到大家,从一个码农进阶为一个优秀的程序员,也可以帮大家提升系统实战能力. 这些资料包括: 讲解 ...

  10. 身边好几个技术一般的程序员都面上了,阿里P7门槛降低?

    经常在网上的论坛里看到讨论程序员的级别,尤其在跳槽类的信息里可以看到对标阿里P7,百度T6,腾讯3.1等字眼,似乎大厂的级别俨然可以成为业内的通用货币,类似于高考分数一样,哪一档就对应着什么样的待遇. ...

随机推荐

  1. 密码加密|jsencrypt|md5|加密解密的两种方式

    一.md5 npm install md5 二.JSEncrypt 2.1 介绍 JSEncrypt属于RSA加密,RSA加密算法是一种非对称加密算法: 2.2 使用 安装: npm install ...

  2. Momentum Contrast for Unsupervised Visual Representation Learning论文精读

    目录 Birth of MoCo Supervised Learning Contrastive Learning MoCo Dictionary Limits of the early learni ...

  3. [T.4] 团队项目:团队代码管理准备

    团队的代码仓库地址 [GitHub - Meng-XuanYu/JayJay-TeamVersionControl: A public repo for BUAASE2025 course homew ...

  4. nodejs新进程子进程

    获取进程相关的基本信息 #!/bin/env node console.log (process.execPath) console.log (process.cwd()) console.log ( ...

  5. 基于AST实现国际化文本提取

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:霜序 前言 在阅读本文之前,需要读者有一些 babel 的 ...

  6. 使用Python+SymPy求解微分方程

    引言 在学习微积分或者物理.工程相关的学科时,微分方程常常是我们需要解决的一个重要问题.微分方程是包含未知函数及其导数的方程,广泛应用于描述变化过程中的规律,如物理中的运动方程.化学中的反应速率.经济 ...

  7. 一个用原生JavaScript实现的日历小工具,开箱即用

    ---------------- 用原生JavaScript实现的一个日历小工具,开箱即用,可用于做签到记录.日程等显示控件,具体自己发挥啦 效果如下图,可以自行美化  >>点击体验< ...

  8. 一、C语言概述

    声明 本文内容大多取自<高级语言程序设计一书>,为本人学习笔记记录,切勿用于商业用途. 第一节 计算机发展 电子计算机已经历的四个发展时代: 第一代:20 世纪 50 年代,主要采用真空电 ...

  9. 鸿蒙 NEXT (一)初识鸿蒙

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  10. VMware workstation 部署微软MDT系统

    一.环境准备 1. VMware Workstation 虚拟机配置 新建虚拟机 类型:Microsoft Windows Server 2022 Standard 内存:4GB+ 硬盘:100GB( ...