
读书笔记
dr.xun
迭代
展开
-
现有系统中安全的添加特性的方法
测试驱动开发(TDD)算法:(1)编写一个失败测试用例。(2)让它通过编译。(3)让测试通过。(4)消除重复。(5)重复上述步骤。价值:我们可以在同一时间只关注于一件事情。要么是在编码,要么是在重构;永远也不会在同一时刻做两件事情。差异式编程借助于类的继承,我们可以在不直接改动一个类的前提下引入新的特性。在添加完特性之后,我们便可以弄清楚到底想要如何添加新特性。【注】由于继承的缺陷,当前已很少使用。Liskov置换原则子类对象应当能够用于替换代码中出现的它们的父类的对象,不管后者原创 2022-05-01 13:38:14 · 162 阅读 · 0 评论 -
依赖是修改代码得到快速反馈的拦路虎
理解代码只要我们尚不熟悉相关代码的上下文, 就没法很快知道如何进行修改。时滞从做出修改到得到反馈所经历的时间。需要快速反馈。阻碍快速反馈的是代码间的依赖。解依赖1、弄清哪些依赖会成为拦路石方法:试着在测试用具中使用该类,所遇到的几乎所有问题都会源于某个依赖。依赖倒置原则...原创 2022-04-30 23:02:56 · 304 阅读 · 0 评论 -
时间紧迫下,代码修改的技能
新生方法思想:当需要往一个系统中添加特性且这个特性可以用全新的代码来编写时,建议你将这些代码放在一个新的方法中,并在需要用到这个新功能的地方调用这一方法。你可能没法很容易地将这些调用点置于测试之下,但至少可以为新编写的那部分代码进行测试。实施步骤:(1)确定修改点。(2)如果修改可以在一个方法中的一处地方以单块连续的语句序列出现,那么在修改点插入一个方法调用,而被调用的就是我们下面要编写的、用于完成有关工作的新方法。(3)确定需要原方法中的哪些局部变量,并将它们作为实参传给新方法调用(4)确定原创 2022-04-30 22:44:06 · 337 阅读 · 0 评论 -
带着反馈工作,构建安全体系
前言常用的改动系统的方式:编辑并祈祷,先理解系统,仔细制定修改计划,修改局部,然后修改系统,最后验证修改的正确性覆盖并修改,先建立修改前的安全防护(构建全面的测试覆盖),确保糟糕的改动不会泄漏出去并感染到软件的其他部分,防护建立后,可以安心的修改,并能快速的检测出修改的好坏。通过测试验证正确性通过测试检测变化软件夹钳:固定住目标软件的大部分行为,只改动那些你真正想要改动的地方。单元测试由一组独立的测试构成,其中每个测试针对一个单独的软件组件。这里组件是一个系统的最为“原子”的行为原创 2022-04-24 22:50:57 · 271 阅读 · 0 评论 -
软件修改不可避免
修改代码的起因四种:(1)添加新特性;新需求需要实现(添加新的功能或者添加新功能并替换之前的功能)(2)修正bug;(3)改善设计;(4)优化资源使用。添加新特性与修正bug对于程序员来说,可以统一看成是改变软件的行为。行为:行为对于软件来说是最重要的一样东西。软件的用户要依赖于软件的行为。用户喜欢我们添加行为(前提是新的行为确实是他们所需要的),然而如果我们改变或移除了他们原本所依赖的行为(引入bug),那么他们就不会再相信我们。行为与功能:行为包含功能、性能、可维护性等功能,更原创 2022-04-24 21:28:56 · 350 阅读 · 0 评论 -
C++编译器解析operator->机制及自锁定技术实现
机制说明编译器可以一个->表达式多次应用operator->,直到找到原始指针。例子好用的RAII手法template<typename T>struct LockingProxy{ LockingProxy(T* pObj) : pointee_ (pObj ) { pointee_->lock(); } ~LockingProxy() { pointee_->unlock(); } T* operator->() c原创 2022-04-19 23:12:04 · 688 阅读 · 0 评论 -
智能指针设计思想
简介smart pointers是一种C++对象,它提供operator->和 unary operator*,藉以模拟一般指针的行为。template<typename T>class SmartPtr{public: explicit SmartPtr(T* pointee) : pointee_(pointee); SmartPtr& operator=(const SmartPtr& other); ~SmartPtr(); T& op原创 2022-04-16 22:40:04 · 738 阅读 · 0 评论 -
C++单例实现实践
简介保证一个class只有一个实体,并为它提供一个全局访问点。种经过改进的全局变量。懒汉模式版本一class Singleton {public : static Singleton* instance() { if (!pInstance_) pInstance = new Singleton(); return pInstance_; }private : Singleton(); Singleton(const Singleton&); ~原创 2022-04-15 22:56:49 · 640 阅读 · 0 评论 -
内存管理——小型对象分配器实践输出
【注】此实践的基本思路来自《Modern C++ Design》四层结构实现Chunkstruct Chunk{ Chunk() : pData(nullptr), firstAvailableBlock_(0), blocksAvailable_(0) { } Chunk(size_t blockSize, unsigned char blocks) { pData = new unsigned char[blockSize * blocks]; firstAvailab原创 2022-04-12 22:55:56 · 1416 阅读 · 0 评论 -
C/C++通用内存分配器原理解析
C/C++分配器存在的问题1、分配速度慢,通常用于为大型对象(数百个或数千个bytes)分配内存2、存在一个管理内存的记忆池,常会耗用一部分内存资源,对于new分得得每一块内存,都会对其进行登记,而登记所需内存达4~32个bytes,对于分配小型对象,用于登记所需内存占比大,不适合用于分配小型对象的内存。内存分配器的工作方式内存分配器管理一个由raw bytes所组成的内存池,能够从池中分配任意大小的内存区块。管理内存需要的簿记结构,内存控制块:struct MemControlBlock {原创 2022-04-09 22:02:21 · 1468 阅读 · 0 评论 -
架构演进简介
1、命令查询职责分离模式(Command Query Responsibility Segregation,CQRS)读与写分离2、六边形架构分层:内部和外部3、洋葱架构(Onion Architecture)分离:基础设施;业务应用 外层依赖内层。 内层对外层无感知。4、COLA架构(面向对象分层架构)左边:分层架构右边:COLA分层架构 规则设计:“一个应用至少要有3个组件:应用层、领域层和基础实施层。”...原创 2022-04-01 23:43:13 · 182 阅读 · 0 评论 -
利用模板别名using实现TypeList
实现TypeListtemplate<typename T, typename U>struct TypeList{ using Head = T; using Tail = U;};背后的机制template参数可以是任何型别,包含该template的其他具现体。作用TypeList 内部没有任何数值:它们的实体是空的,不含任何状态,也未定义任何函数。执行期间t不带任何数值。它存在的理由只是为了携带型别信息。使用例子:using CharList = TypeLis原创 2022-03-26 23:38:05 · 712 阅读 · 0 评论 -
模板技术之编译期识别类型转换和继承性
问题如何识别两个模板参数T和U是否有继承关系?原理sizeof的威力sizeof可以用于任何表达式,在编译期评估表达式类型的大小。因此,sizeof可以感知重载、模板实例化、转换规则,或任何可发生于C++表达式身上的机制。识别类型转换能力机制运用sizeof和重载函数。1、函数重载提供选择分支提供两个重载函数:一个接受目标类型U——1号函数,另一个接受其它任何类型——2号函数。用户用类型T来调用这些函数,用户想知道T是否可以转换成U。如果1号函数被调用,说明T可以转换成U,否则无法转换成U。原创 2022-03-23 23:05:59 · 1191 阅读 · 0 评论 -
模板技术之型别转换实现Tag
型别映射问题:C++中不存在函数模板偏特化有时我们期待型别转换,输入一种数据类型,输出另一种数据类型,如下代码所示。template<typename T, typename U>T* Create(const U& arg){ return new T(arg);}有时,系统中存在旧代码,如Widget,需要两个参数才能构建出对象,第二个参数固定为-1,它的派生类则没有这种问题。由于函数模板特性限制,我们如下代码不符合规则。//非法代码template<t原创 2022-03-22 23:43:19 · 1144 阅读 · 0 评论 -
软件开发的本质
#软件开发的本质软件开发过程就是问题空间到解决方案空间的一个映射转化。“问题空间”就是系统要解决的“领域”问题”“可以简单理解为一个领域就对应一个问题空间,是一个特定范围边界内的业务需求的总和。”“领域模型”就是“解决方案空间”,是针对特定领域里的关键事物及其关系的可视化表现,是为了准确定义需要解决问题而构造的抽象模型,是业务功能场景在软件系统里的映射转化,其目标是为软件系统的构建统一的认知。领域模型的作用:1、帮助分析理解复杂业务领域问题,描述业务中涉及的实体及其相互之间的关系,是需求分析原创 2022-03-20 23:06:16 · 1050 阅读 · 0 评论 -
template技术之数字型别化实现编译期分派工作
数字型别化template<int v>struct Int2Type{ enum { value = v };};作用: 根据引数所得的不同数值来产生不同型别。eg: Int2Type<1>与Int2Type<2>是不同的数据类型,通过它可以在编译期选择不同数据类型,即编译期的条件判断。使用场景需满足以下两个条件:1、有必要根据某个编译期常数调用一个或数个不同的函数。2、有必要在编译期实施“分派”( dispatch) 。例子选择函数temp原创 2022-03-20 00:03:21 · 117 阅读 · 0 评论 -
C++局部类的一种使用场景
局部类局部类的限制local class不能定义static成员变量,也不能访问non-static局部变量。使用场景例子:适配器class Interface{public: virtual void fun () = 0;};template <class T, class P>Interface* MakeAdapter(const T& obj, const P& arg ){ class Local : public Interface {原创 2022-03-19 23:39:24 · 560 阅读 · 0 评论 -
技术之编译器检查
编译器检查特点:静态类型检查可定制类型错误消息例子:实现安全转型的函数,并确保较大型别不能转换成较小型别。迭代一template <typename To, typename From>To safe_reinterpret_cast(From sfrom){ assert(sizeof(From) < sizeof(To)); return reinterpret_cast<To>(from) ;}上述代码,会在执行期进行断言。迭代二 期待编译原创 2022-03-18 23:41:17 · 794 阅读 · 0 评论 -
template应用之Policies和Policy Classes
Policies和Policy Classes什么是Policy?Policy定义一个class或class template的接口,该接口由内隐型别定义( inner type definition) 、成员函数和成员变量之一或全部组成。例子声明Policy:policy_Create()可以理解为一种语法约束:要有Create()接口Create()返回值必须是T*template<typename Policy>struct Creator{ explicit Cr原创 2022-03-14 23:06:38 · 894 阅读 · 0 评论 -
多重继承与template结合增强设计
多重继承优点有助于产生更富弹性的设计,扩展性好具备封装性缺点缺乏技术(Mechanics ),仅仅只是将被组合的base classes结合在一起并建立一组用来访问其成员的简单规则缺乏型别信息(Type infornation),Based classes并没有足够的型别信息来继续完成它们的工作缺乏弹性的数据处理,base classes实作之各种行为必须操作相同的数据。这意味着他们必须虚继承一个持有该数据的base class。由于总是由user classes继承librar原创 2022-03-13 12:42:25 · 396 阅读 · 0 评论 -
对设计的一些理解
软件设计所谓软件设计就是解域空间( solution space)中的一道选择题。设计没有唯一性专业软件设计师知道什么可以有效运作,什么不可以。任何设计结构上的问题,都有许多合适的解法,然而它们各有不同规格并且各有优缺点。对眼前有益的问题可能适合也可能不适合。白板上可接受的方案,不一定真有实用价值。如何灵活组合?组合,富有弹性的组合系统架构基本原则主要基本原则是:以“设计”实现某些“原则”( axioms),例如你不能产生两个 Singleton对象或产生一个"disjoin原创 2022-03-12 23:23:58 · 403 阅读 · 0 评论 -
2021年阅读清单
用普通的话来说,这个咒语就是——阿巴拉卡达巴拉,芝麻开门,而且还有另外的东西——在一个故事里的咒语在另一故事里就不灵了。真正的魔力在于知道哪个咒语有用,在什么时候。用于做什么。其诀窍就在于学会有关的诀窍。 而这些咒语也是用我们的字母表里的字母拼出来的,这个字母表中不过是几十个可以用笔画出来的弯弯曲线。这就是最关键的!而那些珍宝也是如此,如果我们能将它们拿到手中的话!这就像是说,就像通向珍宝的钥匙就是珍宝! ...原创 2022-02-12 22:02:55 · 361 阅读 · 0 评论 -
计算机程序的构造和解释第一章
原创 2021-10-10 20:58:42 · 188 阅读 · 0 评论 -
线程间共享数据笔记
原创 2021-10-06 14:26:19 · 105 阅读 · 0 评论 -
计算机程序的构造和解释-序(读书笔记)
计算机程序的构造和解释-序原创 2021-09-25 15:52:19 · 200 阅读 · 0 评论 -
C++智能指针
原创 2021-06-20 16:14:24 · 133 阅读 · 0 评论 -
C++类型推导
原创 2021-06-20 16:11:50 · 194 阅读 · 0 评论 -
API之应用编程体验(APX)
一、APIAPI,英文全称Application Programming Interface,翻译为“应用程序编程接口”。是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。我们不妨把API的诞生过程用一个小故事展示出来:研发人员A开发了软件A,研发人员B正在研发软件B。有一天,研发人员B想要调用软件A的部分功能来用,但是他又不想从头看一遍软件A的源码和功能实现过程,怎么办呢?研发人员A想了一个好主意:我把软件A里你需要原创 2021-06-14 17:51:20 · 661 阅读 · 0 评论 -
物理地址(MAC)
一、特性一种标识符,用来标记网络中的每个设备。 只在当前局域网有效。原创 2021-06-05 20:34:23 · 490 阅读 · 0 评论 -
C++零初始化(Zero Initialization)
下面的语句定义了一个初始值为0的整型变量:int counter {0}; // counter starts at zero我们可以忽略这里带括号的初始化式中的0,效果是一样的。定义counter的语句可以这样写:int counter {}; // counter starts at zero说明:空花括号有点像数字0,这使得这个语法很容易记住。零初始化适用于任何基本类型。例如,对于所有基本的数字类型,总是假定带括号的空初始化式包含数字零。摘自:beginning-c20-.原创 2021-05-15 19:08:25 · 1296 阅读 · 0 评论 -
大道至简——软件工程实践者的思想知识导图
这本书主要是从工程角度、实现产品的角度看问题。原创 2021-04-05 16:31:58 · 231 阅读 · 0 评论 -
软件工程
只有大的需要协调进度的项目才需要软件工程。原创 2021-04-04 22:50:41 · 99 阅读 · 0 评论 -
语言只是工具
时时提醒自己。原创 2021-04-04 22:36:26 · 112 阅读 · 0 评论 -
关于问题的定义
《你的灯亮着吗?》-- 温伯格说:问题其实就是你期望的东西,和你体验的东西之间的差别。周爱民一语道破本质,“你认为这是个问题,它就是个问题”。原创 2021-04-04 22:25:21 · 722 阅读 · 0 评论 -
瀑布模型
原创 2021-04-04 21:12:34 · 99 阅读 · 0 评论 -
正交设计(收集大牛的文章)
变化驱动:正交设计,跳转链接:https://www.jianshu.com/p/d127b8afc8cb原创 2021-03-28 23:30:27 · 136 阅读 · 0 评论 -
C++引用坍缩规则
在传统 C++ 中,我们不能够对一个引用类型继续进行引用,但 C++ 由于右值引用的出现而放宽了这一做法,从而产生了引用坍缩规则,允许我们对引用进行引用,既能左引用,又能右引用。但是却遵循如下规则:因此,模板函数中使用 T&& 不一定能进行右值引用,当传入左值时,此函数的引用将被推导为左值。更准确的讲, 无论模板参数是什么类型的引用,当且仅当实参类型为右引用时,模板参数才能被推导为右引用类型。...原创 2021-03-13 21:29:49 · 1505 阅读 · 0 评论 -
现代C++变长参数模板
一、变长参数模板定义自C++11后,C++开始支持变长参数模板,允许任意个数、任意类别的模板参数,不需要在定义时将参数的个数固定。其形式定义如下:template<typename... Ts> class Variadic;其模板实例化:1. 0个参数的模板类 Variadic<> zero;2. 多个参数的模板类 Variadic<int, double, std::string, std::list<int>> sample;.原创 2021-03-13 20:59:01 · 779 阅读 · 0 评论 -
代码评价坐标图
原创 2021-03-13 09:12:00 · 379 阅读 · 0 评论 -
什么是可重入(Reentrant)?
一、什么是重入?函数在执行时,由于外部原因或内部调用,又一次进入该函数执行。二、重入发生场景多个线程同时执行该函数 函数自身调用自身三、什么是可重入在相同的输入下,函数每次被调用产生的结果相同。栗子:int add(int a, int b){ return a + b;}每次调用add(1, 2),得到的结果都是3.四、可重入的函数必须具备哪些特点不使用任何静态或全局的非const对象 不返回任何静态或全局的非const对象的指针 只依赖于调用方提原创 2021-01-10 21:36:45 · 8938 阅读 · 0 评论