ARST打卡第210周[210/521]
Algorithm
2441_与对应负数同时存在的最大正整数
直接用 unordered_set hash数组保存过往的数字,然后每次查一下以前是否有相反数,然后维护最大绝对值即可
题解还有排序+双指针和暴力枚举的做法就不多介绍了
|
|
Review
【TED演讲】如何有目的生活
珍惜自己手上拥有的东西(才能,资源等),然后用这些东西去让世界变得更加美好
人的价值不在于拥有多少,而在于给世界创造了多少
Tips-如何阅读源代码(耗子叔的思路)
首先是阅读代码之前,最好先有以下了解:
- 基础知识:相关的语言和基础技术的知识;
- 软件功能:需要知道这个软件是做什么的、有哪些特性、哪些配置项,最好能够读一遍用户手册,然后让软件跑起来,自己先用一下感受一下;
- 相关文档:读一下相关的内部文档;
- 代码的组织结构:先简单看下源码的组织结构。
接下来,就是详细地看代码的实现,这里耗子叔分享了一个源代码阅读的经验:
- 接口抽象定义:任何代码都会有很多接口或抽象定义,其描述了代码需要处理的数据结构或者业务实体,以及它们之间的关系,理清楚这些关系是非常重要的;
- 模块粘合层:我们的代码有很多都是用来粘合代码的,比如中间件(middleware)、Promises 模式、回调(Callback)、代理委托、依赖注入等。这些代码模块间的粘合技术是非常重要的,因为它们会把本来平铺直述的代码给分裂开来,让你不容易看明白它们的关系;
- 业务流程:这是代码运行的过程。一开始,我们不要进入细节,但需要在高层搞清楚整个业务的流程是什么样的,在这个流程中,数据是怎么被传递和处理的。一般来说,我们需要画程序流程图或者时序处理图;
- 具体实现:了解上述的三个方面的内容,相信你对整个代码的框架和逻辑已经有了总体认识。这个时候,你就可以深入细节,开始阅读具体实现的代码了。对于代码的具体实现,一般来说,你需要知道下面一些事实,这样有助于你在阅读代码时找到重点。
- 代码逻辑:代码有两种逻辑,一种是业务逻辑,这种逻辑是真正的业务处理逻辑;另一种是控制逻辑,这种逻辑只是用控制程序流转的,不是业务逻辑。比如:flag 之类的控制变量,多线程处理的代码,异步控制的代码,远程通讯的代码,对象序列化反序列化的代码等。这两种逻辑你要分开,很多代码之所以混乱就是把这两种逻辑混在一起了;
- 出错处理:根据 2:8 原则,20% 的代码是正常的逻辑,80% 的代码是在处理各种错误,所以,你在读代码的时候,完全可以把处理错误的代码全部删除掉,这样就会留下比较干净和简单的正常逻辑的代码。排除干扰因素,可以更高效地读代码;
- 数据处理:只要你认真观察,就会发现,我们好多代码就是在那里倒腾数据。比如 DAO、DTO,比如 JSON、XML,这些代码冗长无聊,不是主要逻辑,可以不理;
- 重要的算法:一般来说,我们的代码里会有很多重要的算法,我说的并不一定是什么排序或是搜索算法,可能会是一些其它的核心算法,比如一些索引表的算法,全局唯一 ID 的算法,信息推荐的算法、统计算法、通读算法(如 Gossip)等。这些比较核心的算法可能会非常难读,但它们往往是最有技术含量的部分;
- 底层交互:有一些代码是和底层系统的交互,一般来说是和操作系统或是 JVM 的交互。因此,读这些代码通常需要一定的底层技术知识,不然,很难读懂;
- 运行时调试:很多时候,代码只有运行起来了,才能知道具体发生了什么事,所以,我们让代码运行进来,然后用日志也好,debug 设置断点跟踪也好。实际看一下代码的运行过程,是了解代码的一种很好的方式。
总结一下,阅读代码的方法如下。
- 一般采用自顶向下,从总体到细节的【剥洋葱皮】的读法;
- 画图是必要的,程序流程图,调用时序图,模块组织图;
- 代码逻辑归一下类,排除杂音,主要逻辑才会更清楚;
- debug 跟踪一下代码是了解代码在执行中发生了什么的最好方式。
另外这里也有个其他见解 https://www.codedump.info/post/20200605-how-to-read-code-v2020/ 兼听则明
转载自: https://wanghenshui.github.io/2021/05/28/code-review.html
Share-C++编程中的工厂模式
在C++编程中,工厂模式(Factory Pattern)是一种创建对象的设计模式。它提供了一种将对象的创建与使用代码解耦的方式,使得代码更具灵活性和可维护性。工厂模式通常包括以下几个关键组件:
- 抽象产品(Abstract Product):定义产品的共同接口或抽象基类。抽象产品可以是一个纯虚类,只声明了接口而没有实现。
- 具体产品(Concrete Product):实现抽象产品接口的具体类。每个具体产品对应工厂模式中的一个产品类型。
- 抽象工厂(Abstract Factory):定义了创建抽象产品的接口。它可以是一个纯虚类或者接口类,提供了创建产品的方法。
- 具体工厂(Concrete Factory):实现抽象工厂接口,负责创建具体产品的实例。
使用工厂模式的一般步骤如下:
- 定义抽象产品接口:创建一个抽象产品类或接口,声明产品的公共方法。
- 实现具体产品:针对每个具体产品类型,创建一个具体产品类,实现抽象产品接口的方法。
- 定义抽象工厂接口:创建一个抽象工厂类或接口,声明用于创建产品的方法。
- 实现具体工厂:针对每个具体产品类型,创建一个具体工厂类,实现抽象工厂接口的方法。在每个方法中,根据需要创建对应的具体产品实例,并返回抽象产品接口。
通过使用工厂模式,客户端代码可以通过与抽象工厂和抽象产品进行交互,而无需直接与具体产品进行耦合。这样可以使得代码更加灵活,可以轻松地替换具体产品的实现或者扩展产品的种类,而无需修改客户端代码。
工厂模式还有一些变体,如简单工厂模式、工厂方法模式和抽象工厂模式,它们在实现方式和应用场景上有所不同,但都遵循了工厂模式的基本原则。根据具体的需求和设计目标,选择适合的工厂模式变体来实现对象的创建和管理。
以下是一个简单的工厂模式的例子:
|
|
在上述示例中,我们定义了一个抽象产品 Product
,具有一个纯虚函数 use()
。然后,我们定义了两个具体产品 ConcreteProductA
和 ConcreteProductB
,它们分别实现了 Product
接口。
接下来,我们定义了抽象工厂 Factory
,具有一个纯虚函数 createProduct()
,用于创建产品对象。然后,我们创建了两个具体工厂 ConcreteFactoryA
和 ConcreteFactoryB
,它们分别实现了 Factory
接口,并在其 createProduct()
方法中创建了对应的具体产品对象。
最后,在 main()
函数中,我们使用具体工厂 ConcreteFactoryA
和 ConcreteFactoryB
创建了具体产品 ConcreteProductA
和 ConcreteProductB
的实例,并调用了它们的 use()
方法进行使用。
通过工厂模式,客户端代码与具体产品的创建过程解耦,只与抽象工厂和抽象产品进行交互。这样,如果需要替换产品的实现或者扩展产品的种类,只需要修改工厂的具体实现,而不需要修改客户端代码。
|
|