态度和能力谁轻谁重?

前言

在现在这个社会中,有许多的问题一直在困扰着我们,在这些问题面前,有太多的因素影响,态度,能力,经验,人脉,我们从一开始的不以为然,到现在的慢慢麻木。早以分不清,什么是什么了,每一个人或多或少的都会犯下一些可大可小的错误,然后通过这些错误逐渐成熟,回过头才发现之前的错误那么的可笑。好吧,回到主题,在信息爆炸的如今,对于很多问题的原因,有人的个人的观点是热情和态度。

命名啰嗦,不规范

禁止这类写法,因为在一个func里跟到最后我们可能完全不知道a是个什么东西,又得跳回看

var a = 1

类型名要表达的意思要和实际大致一样,减少维护心智负担

userId
userInfo
orderHistory

函数命名更要讲究英文和中文的准确对应,比如下面这两种,想要表达的意思是处理数据,但是handle和deal似乎在英文中和数据不是很搭配,而且一般来讲,函数对数据无非是做一个中间处理,不会产生什么终态效应。所以可以改为formatData()

func handleData() {}
func dealData() {}

魔法数字

万恶之源,现代项目应该从一开始就着手配置相关开发, config driven development

updateState(1)
updateState(stateConfig.UP)

配置分类

配置做到了,但是还有一个比较头疼的问题,配置爆炸,把所有的配置信息都放在一个conf文件,或者常量类…解决方法就是分业务逻辑,比如订单类的就放到订单下,用户类就…

go项目的话其实不推荐使用传统的MVC架构,所以根据业务逻辑层来进行配置切分更加方便。

分类的粒度

如果配置切分过于细化,反而会影响后期维护,这点主要是难以检索等问题,个人感觉倒不是细化本身是错的

解决方案:

  • 从一开始掌握好粒度要求,比如就细分到某个业务逻辑层,不在某个业务逻辑层下再细分用户,订单…这个看项目和团队的设计
  • 相关的配置写好comment和doc,这样检索很方便,一个配置文件名在清晰也可能会导致别人语义的理解错误还有不同模块可能细化程度不一会导致重复。(但是comment这东西在代码中就尽量要注意不要造成注释灾难,个人看老外的项目注释比较多,但是看一些软件设计相关的书籍,其实并不推荐过多的使用comment,因为本能的comment使用会导致自己并不会对代码有较高的要求,而是寄希望于comment来理解。)
  • 模块切分,同时配置互不影响。

函数写太长

最近看的《软件设计哲学》中倒是对这个观点并不完全赞同,其主要原因是很多人把小函数当成了一个死记硬背的东西,不管什么只要超过了n行就拆出一个小函数,这其实无形之中反而增加了维护成本,同时也打破了一个时间顺序

所以拆分要注意不要将状态分离出去,时序不要改变

func ABCDE() {
  A
  B
  C
  D
  E
}

=>

func main() {
  A()
  B()
  C()
  D()
  E()
}

再具体一些

func createOrder(userInfo UserInfo, products []Product) {
  checkUserValid(userInfo);
  checkProducts(products);
  checkUserAndProducts(userInfo, products);
  var order = insertOrder(userInfo, products);
  var createFlag = createOrderDetail(order, products);
  return createFlag;
}

滥用回调,增加复杂性

回调在业务场景很常见,比如增加一条数据回调一个log,回调一个状态更新…其实完全可以同步来代替,回调反而在直观时序上不那么明确。

实际例子

这里有一个用户的评论系统,评论系统会对服务你的商家进行一些tag勾选和内容填空。

对于评论系统本身,只需要简单记录被打tag和被评论的对象到mysql即可。

但后面有信用系统、用户画像系统、客服系统依赖于这些评论的数据,所以需要把这些评论tag和内容同步给其它的几个系统,或者甚至是跨部门的系统。

一个提交,回调函数n个,关键是回调函数根本不是直接的逻辑,自己根本不知道写了这段逻辑产生的真正影响,所以出了问题可能又得查到别人那里,如果对方离职又是一个难题

解决方案:时序解耦,消息队列

event A happend
then {
    call sys A1();
    call sys A2();
    call sys A3();
    call sys A4();
    call sys A5();
    call sys A6();
    call sys A7();
    call sys A8();
    ...
}

=>

event A happend
then {
    push msg to msg queue
}

A1~AN subscribe topic A in msg queue

这里就是将问题转移出去,即使出了问题,你的函数的最终作用是发送消息给消息队列,这样你只需要确认你的问题就ok了,不像之前那样n个回调都耦合在一起。再进一步将push打上log,这样监控也更方便了,当然分布式的一致性会不如之前,而且不仅要做到预警还要做好恢复方案,出了问题可快速恢复

分层但是分层没有明确的界线

比如在某一层里,有些只是在内存操作,比如返回一个result array,但是有些直接返回一个status state给用户,直接持久化…

公共接口本身只能用一次

换个说法就是可重入不可重入。

比如你的func内引用了一个全局静态变量,而且没有加锁,那这就属于不可重入,因为几个线程一起调用不久乱了。

所以不要吝惜你的锁!尽量拒绝使用全局变量!

性能问题?你的业务真的需要考虑吗?又要搬出“过早优化是万恶之源”

设计模式滥用

设计模式并非银弹,如果做Java开发,其实现代framework做的已经蛮好了。

查询数据库不做批量

这个根据id查没问题,但是如果商品是n+个,那就意味着执行一次这个func要进行n+次数据库连接,即使有连接池,这似乎也不合理,这种要做到批量查询

func getProductList(xxxx) {
   var products []Product
   for product := range products {
      categoryName := getCategoryName(product.getCategoryId())
      product.setCategoryName()
   }
}

if else嵌套

这个在写golang不是很常见,因为写久了就会有一种错误及时处理的概念

同一张数据库表的查询,每换一种查询方式就写一个函数

public interface CategoryMapper xxxx {
    @Select("select * from category where name = #{name}")
    public List<Category> findByName(@Param("name") String name);
    
    @Select("select * from category where id = #{id}")
    public List<Category> findById(@Param("id") Long id);

    @Select("select * from category where parentId = #{parentId}")
    public List<Category> findByParentId(@Param("parentId") Long parentId);

    @Select("select * from category where status = #{status}")
    public List<Category> findByStatus(@Param("status") Integer status);

    //以下略
}

解决方案:使用sql builder等类似开源工具

工作流update不考虑修改前的state

其实就是状态机,一种状态要满足一些条件才能转移到另一种状态,但是转移前我们要确定前置状态,尤其是现在的程序大多数都是多线程环境下运行。

很常见的一种update sql,其实这问题可大了,不合理的处理方案是在其他地方对某个前置状态再查一次,的确这样可以避免前端上的错误反馈,但是问题是已经持久化了,难道还要包在一个事务里?

update xxx set status = yyy where id = zzz;

解决方案:比如我们在上面这种update时多加一个,解决方案很多,大致就是“订单流状态机乐观锁”这种关键字搜索就好了

where status = ?

open资源不关闭

套接字,文件描述符,连接池~~~

golang就好多了,记住defer close()

抱怨!

抱怨前要有证据,如果你说是因为自身之外的原因导致的bug或者性能问题,请拿出证据,否则只能给人一种甩锅,态度问题。

学习自曹大blog

xargin.com/rookie-prog…

文 章 源 地 址 : h t t p s : / / j u e j i n . c n / p o s t / 6903888368535339022 文章源地址:https://juejin.cn/post/6903888368535339022 https://juejin.cn/post/6903888368535339022

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
,发送类别,概率,以及物体在相机坐标系下的xyz.zip目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值