五一避开了人群,选择宅家休息,假期过了后准备出门玩玩。周末跑不了太远的地方,这次就先去舟山吧。
我们周六早上十点半左右才出发的,还是不想太特种兵,悠哉一点好了。开车一路上没怎么休息,花了几小时直接开到了舟山。在朱家尖海峡大桥上就看到了黄黄的海水,到底靠近长江入海口,海底泥浆翻涌。
五一避开了人群,选择宅家休息,假期过了后准备出门玩玩。周末跑不了太远的地方,这次就先去舟山吧。
我们周六早上十点半左右才出发的,还是不想太特种兵,悠哉一点好了。开车一路上没怎么休息,花了几小时直接开到了舟山。在朱家尖海峡大桥上就看到了黄黄的海水,到底靠近长江入海口,海底泥浆翻涌。
一个原本普通的下午,却随着同事 A 突然开始整理工位而打破了平静。没想到今年还有第二次。年初时公司范围内就有过一次小规模的裁员,各个组都领到指标,请走了一两位同事。但这次更像是针对性的优化,老员工离开,并且后续计划补充新鲜血液。
伴随着年后毫无征兆的裁员,领导层又陆续推出了一些新花样。All hands 上老板提出一些新的守则,指导员工们要勤勤恳恳做好工作,同时提升自我。换句话也可以说是让牛马们卷起来,别暗戳戳想着自己可以混日子养老了。同时也提出了配套的 KPI。以前公司虽然也强调快速迭代让大家都卷起来,其实还是略有余地的,这次又继续上了强度。
通常我们会认为 c++ 程序中,类的虚函数总是严格按照类中的声明顺序排列,但最近我在查看一个虚函数的调用时却发现并不如此。如果虚函数有候选的重载,那它的顺序实际可能和声明的顺序不一样。
比如下面一个简单的类
公司前段时间做了个功能,本地客户端会启动一个 webview 窗口,并通过它和本机浏览器上的一个页面建立 WebRTC 通信,然后互相交换数据。本地的 webview 会借助客户端的通信能力,和浏览器上的网页各自接收服务器的消息,满足条件后就可以借助服务器交换 icecandidate 和 sdp,随后建立连接。
但是我们在使用过程中发现了问题,Mac 机器的 WebRTC 无法成功建立。因为公司的机器上安装了 Zscaler,它是个网络流量监控和代理的工具,所以很快怀疑到它身上,测试一下发现把它退了后就能成功连接了。另外 windows 系统并没有受到它影响,退不退 Zscaler 都可以连接。
想着记录一下平时分析过的 crash dump,作为一个总结和参考。不过因为涉及到公司代码,所以一些细节没法描述太明白,crash 堆栈和对应的源代码也不方便贴出来了。这里先整理了几个比较有代表性的,其他一眼就能看出问题的就不写到这里了。
当用户开启计算机锁屏时自动切断 channel 的策略并触发了锁屏行为后,UI 会调用 api 切断所有 channel,并且立即清理上层保存的数据,但问题就在这个清理上。
原本调用触发切断的 api 后会有一个回调通知,上层是在回调里做清理动作的。但是现在代码中主动调用了一个 channel_mgr.Clear();,这个 Clear() 函数里清理的不完全,相比之下另一个成员函数 Delete(channel_id) 才是做到了彻底清理。同时回调函数里还做了许多额外的清理操作,这里一个 Clear() 把其他操作也都忽略掉了。
其实究其原因就是外部保存了 ChannelItem 的裸指针,但是又存在这样一个 corner case 没有将它清理掉,等 ChannelItem 实例析构后这个指针就野了。关键在于怎么发现这个代码路径。
因为 framework 层在释放前总是会通过回调函数通知 UI 清理,费好大劲排除 framework 没有漏掉的地方后把目标放到了 UI 上。来来回回翻代码后才发现这个地方。
之前公司项目中一直没有方便好用的异步编程框架,在开发过程中会遇到一些问题。比如多线程编码时开发需要自己管理线程,并在两侧同步数据。一些操作也会被直接放在主线程中,就算单个操作的耗时并不明显,长此以往也会积少成多,最终拖慢了 UI 的速度。
但好在公司的代码库已经支持 C++11,我们基于 C++11 开发了一个仅使用标准库的框架。这样既能简化业务开发时的代码工作量,也可以提高代码的可读性,而且使用 std 组件实现也方便支持所有平台。更进一步的话还可以给框架加入其他支持,如:
阿德勒心理学中提出了几个反直觉的观点,通过它们也许可以缓解我们的思维定势,帮助解决内心的矛盾。
因为有些软件不支持主动设置代理,所以有时候还得开个透明代理,在实际买设备前先用虚拟机安装 OpenWrt 实验一把。
一开始想着去找那些有一键设置的工具或脚本,结果来回折腾花了不少时间,最后还是参考这里的教程搞定了。
*.img
,记为 op.img
dd if=/dev/zero bs=1M count=2048 >> op.img
,将镜像扩容到 2G构建系统描述了如何使用构建工具从项目的源代码构建项目的可执行文件和库,从而自动执行该过程。例如,构建系统可以是用于命令行 make 工具的 Makefile 或用于集成开发环境的项目文件。为了避免维护多个这样的构建系统,项目可以使用以 CMake 语言编写的文件抽象地指定其构建系统。从这些文件中,CMake 通过称为生成器的后端为每个使用者在本地生成一个首选的构建系统。
另外,在 c++ 代码的跨平台使用中,包括增减文件在内,任何其他涉及项目工程的改动都要各个平台的开发同步处理各自平台的工程。而一旦某个平台没有及时更新项目文件就可能会导致 CI/CD 自动化流程失败,非常影响工作效率。
为避免费时费力地维护多个这样的构建系统,可以选择用 CMake 对其进行抽象。这样我们只需要维护一个 CMakeLists.txt,它就可以为你生成指定的 vcxproj 文件或者 makefile 文件。然后调用 MSBuild 或者 make 进行编译就可以。
Copyright © 2025 Re: Memory. Powered by love.