项目代码优化(1)——下单逻辑
给一个电商开发的系统排查,发现漏洞很多。很多经验不够的开发者很容易忽视的逻辑错误陷阱。在给一个项目做二次开发时候,检测到的相关经典案例。这里整理支付和产品相关的逻辑,方便后续查看。,这里进行一些简单的逻辑漏洞梳理与修复。
这里基本可以看出经验少的程序员和有经验的程序员的差距,这种差距与算法能力无关,只与类似的系统设计经验有关,所以如果不是算法岗,盲目追逐算法,并不是最佳解。如果仅仅是以完成功能和对外展示流程走通为核心目标,代码逻辑质量看不出来,但是到真正运行的时候,有经验和无经验写的代码差距巨大。
1.原来逻辑与想法::
根据优惠券id,读取根据id状态下未使用的优惠券,进入下一步逻辑。
查询条件 id = $coupon_id + status = 0 读取一个未使用的优惠券。因为优惠券id是唯一的,再读取未使用的优惠券,俩个状态都符合,肯定表示该优惠券是可以使用的。
诊断风险:,读取优惠券之前,必须加上身份限定user_id 也就是需要三方条件成立,这张查询条件才是有效的。虽然大部分正常情况下,俩者查询结果一致,但是如果有恶意攻击者,从A账户,获取到了B账户的优惠券,这样就可以根据B的优惠券id 放入A账户使用。很显然,id = $coupon_id and user_id and status =0 查询安全性上明显高一截,当然另外的写法是全部读取出来,然后用业务代码判断,这会增加业务逻辑代码复杂度。
2.原始写这个系统人代码逻辑:
读取一个product_id 然后进行一次检查,又读取另外一个package_id 又进行一次检查,如果没有检测到相关信息,报错。每次读取一个参数,判断一次,不行,退出报错,没有问题。方便理解。
代码风险: 不是统一先验证必填参数的空参,就直接先读取数据库,如果后面又必填的参数是空参,会导致前面的查询都是浪费。成熟的写法,都是先对所有的必填参数进行验证,出现必填的空参,直接报错,让客户端传递完整参数。可以节约性能。
3.原始写法:API接口直接完成全部逻辑,就是一个接口逻辑从头写到尾,除了使用了内部Model封装的CRUD小方法,其他逻辑全部堆积到一个主方法里面,导致下单方法长度超过300行。
诊断风险: 大方法里面包含 优惠券使用逻辑,拼单逻辑,产品判断逻辑,下单的判断逻辑,产品的规则逻辑,要测试里面任意逻辑,都只能跑全部的方法,导致修改调试逻辑,只能跑整个方法,而整个方法,又因为参数过多,导致调试的效率大幅度降低。
改进方法: 将优惠券逻辑 结算逻辑 产品判断逻辑,规则逻辑 ,权限判断逻辑,全部拆开到model里面或者子方法里面,调试的时候,只需要填入我们要调试的基础逻辑即可,不需要跑其他已经正确的逻辑。
4.API 没有任何防刷,面对并发没有任何防御措施。一旦出现需要连续快速下单的情况,会造成用户可以使用俩次优惠券。查询的接口对防刷没有太高要求,但是对于数据有改动,账户金额有变动/优惠券有数量限制的 ,没有并发,基本就会被灰产使用。写该方法的人,应该没有被灰产攻击的经验,没有代码上有这种防御接口。
改进方法:其实主要还是防止用户网络不畅,连续点了俩次的情况出现。新增一个订单锁,确定该订单下单逻辑全部走完之后,才能下第二单。也就是增加一个流程锁,每个用户在一个时间只能下一单,防止用户的优惠和余额关键信息被同时改动,导致数据失效。一般普通流程锁,使用redis的set即可完成,如果是存在更高级的并发的,需要使用到setnx 。流程锁需要注意的问题是,在执行完成全部逻辑后,需要进行对应解锁。所以最好的执行方法就是,controllerl里面只操作参数判断+锁流程+主流程,而流程放到logic层或者model层。
5.当前的写法:没有产品和店铺的salesnum字段,需要的时候,直接采用 count的方法读取数据库,简单方便,实时读取数据库。很多新手设计表的时候,特别喜欢使用count来替代统计功能,方便好用,也容易理解。
风险警示:一旦遇到诸如需要后台统计每个产品的销量还有,每个店铺的销售量的时候,只能循环使用count,对系统的性能是噩梦,特别是当订单数量达到一百万的时候,会发现刷下后台,就会导致整个系统卡死。
改进方法:对全部需要统计的东西,尽量额外增加一个count_num字段,在进行改动的时候对该字段进行+1 或者-1 如果对精确度要求不高,就不使用事物。否则就需要事物来控制准确度。

相关文章:
项目代码优化(1)——下单逻辑
给一个电商开发的系统排查,发现漏洞很多。很多经验不够的开发者很容易忽视的逻辑错误陷阱。在给一个项目做二次开发时候,检测到的相关经典案例。这里整理支付和产品相关的逻辑,方便后续查看。,这里进行一些简单的逻辑漏洞梳理与修…...
探索 WebKit 的缓存迷宫:深入理解其高效缓存机制
探索 WebKit 的缓存迷宫:深入理解其高效缓存机制 在当今快速变化的网络世界中,WebKit 作为领先的浏览器引擎之一,其缓存机制对于提升网页加载速度、减少服务器负载以及改善用户体验起着至关重要的作用。本文将深入探讨 WebKit 的缓存机制&am…...
JVM:介绍
文章目录 一、什么是JVM二、JVM的功能1、解释和运行2、内存管理3、即时编译 三、常见的JVM四、Java虚拟机规范五、HotSpot发展历程 一、什么是JVM JVM的全称为Java Virtual Machine,Java虚拟机。本质上是一个运行在计算机上的程序,职责是运行Java字节码…...
和鲸“101”计划领航!和鲸科技携手北中医,共话医学+AI 实验室建设及创新人才培养
为进一步加强医学院校大数据管理与应用、信息管理与信息系统,医学信息工程等专业建设,交流实验室建设、专业发展与人才培养经验,6 月 22 日,由北京中医药大学(简称“北中医”)主办,上海和今信息…...
Linux 网络抓包工具tcpdump编译
tcpdump 的编译步骤 1. 下载源代码 访问 tcpdump 的官方网站(如:http://www.tcpdump.org/)下载最新的源代码压缩包,如tcpdump-4.9.2.tar.gz(注意版本号可能会有所不同)。 2. 解压缩源代码 使用 tar 命令…...
『C++成长记』string模拟实现
🔥博客主页:小王又困了 📚系列专栏:C 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、存储结构 二、默认成员函数 📒2.1构造函数 📒2.…...
【c++】C++ IO流
本专栏内容为:C学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C 🚚代码仓库:小小unicorn的代码仓库&…...
解密智慧校园基础数据的学年管理功能
在智慧校园平台中,学年管理模块构成了教育活动有序运行的基石,它精心设计来适应多样化的学术日程,确保学校的各项事务都能在清晰规划的学年框架内顺利推进。这一核心功能不仅关乎时间的界定,更深层次地融入了教育管理的每一个细微…...
Python酷库之旅-第三方库Pandas(009)
目录 一、用法精讲 19、pandas.read_xml函数 19-1、语法 19-2、参数 19-3、功能 19-4、返回值 19-5、说明 19-6、用法 19-6-1、数据准备 19-6-2、代码示例 19-6-3、结果输出 20、pandas.DataFrame.to_xml函数 20-1、语法 20-2、参数 20-3、功能 20-4、返回值 …...
VPN 的入门介绍
VPN(虚拟专用网络) 简介 虚拟专用网络,简称虚拟专网(VPN),其主要功能是在公用网络上建立专用网络,进行加密通讯。在企业网络中有广泛应用。VPN网关通过对数据包的加密和数据包目标地址的转换实…...
移动UI: 什么特征会被认为是简洁风格,用案例告诉你
什么是简洁风格,恐怕一百个人有一百个是理解,本文通过理论分析案例的方式进行探讨。 移动 UI 中的简洁风格通常具有以下几个特征: 1. 平面化设计: 简洁风格的移动 UI 善于运用平面化设计,即去除过多的阴影、渐变和立…...
除了伦敦外,英国还有这些热门留学城市
在同学们选择出国留学时,首先要考虑到的便是择校的问题。除了排名、专业、录取要求之外,城市因素也占据了很大比重。 抛开学校自身的优势外,一座城市的氛围、成本、环境都是需要考虑的因素。下面就我们来盘点一下英国热门的留学城市。 爱丁…...
2390. 从字符串中移除星号
2390. 从字符串中移除星号 题目链接:2390. 从字符串中移除星号 代码如下: class Solution { public:string removeStars(string s) {vector<char> sta;for(int i0;i<s.size();i){if(s[i]*) {sta.pop_back();}else {sta.push_back(s[i])…...
UNION、UNION ALL、INTERSECT、MINUS
UNION、UNION ALL、INTERSECT、MINUS? 说明 UNION:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;IUNION ALL:对两个结果集进行并集操作,包括重复行,不进行排序&am…...
Perl 语言开发(九):深入探索Perl语言的文件处理
目录 1. 文件打开与关闭 1.1 打开文件 1.2 关闭文件 2. 读取文件内容 2.1 逐行读取 2.2 一次性读取整个文件 3. 写入文件内容 3.1 覆盖写入 3.2 追加写入 4. 文件测试操作 4.1 文件测试运算符 5. 文件路径操作 5.1 文件路径处理模块 5.2 获取文件路径信息 6. 文…...
稀疏之美:在Mojo模型中实现特征的稀疏表示
稀疏之美:在Mojo模型中实现特征的稀疏表示 在机器学习领域,特征的稀疏表示是一种高效的数据编码方式,尤其适用于具有大量特征和缺失值的数据集。稀疏表示使用特殊的数据结构来存储和处理数据,从而减少内存占用和提高计算效率。Mo…...
如何大幅减少 Vue.js 中的包大小和加载时间,提升用户体验!
大家好,我是CodeQi! 一位热衷于技术分享的码仔。 你知道吗,根据Google 的一项研究,如果网站加载时间超过 3 秒,53% 的移动用户会离开该网站? 性能优化是一个经常讨论的话题,但很多开发人员并不关心提高应用的速度。 在前端开发中,优化包大小和加载时间对于提升用户体…...
性能测试相关理解---性能测试流程(二)
六、性能测试流程(如何做性能测试?) 根据学习全栈测试博主的课程做的笔记 1、前期准备– 项目初期就开始,业务需求评审时尽量参与,对业务更深刻的认识(确定哪些是核心业务、哪些可能存在并发请求、确定什么地方会出现瓶颈,方便后…...
GD32 MCU ADC采样率如何计算?
大家在使用ADC采样的时候是否计算过ADC的采样率,这个问题非常关键! 以下为GD32F303系列MCU中有关ADC的参数,其中ADC时钟最大值为40MHz,12位分辨率下最大采样率为2.86MSPS.如果ADC时钟超频的话,可能会造成ADC采样异常&…...
.mkp勒索病毒:深度解析与防范
引言: 在数字化时代,网络安全问题日益严峻,其中勒索病毒作为一种极具破坏性的恶意软件,严重威胁着个人用户和企业机构的数据安全。在众多勒索病毒家族中,.mkp勒索病毒以其强大的加密能力和广泛的传播方式,成…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
