項目代碼優化(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? 如果對精確度要求不高,就不使用事物。否則就需要事物來控制準確度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/42774.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/42774.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/42774.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu 22.04 LTS 上安裝 MySQL8.0.23(在線安裝)

目錄 在線安裝MySQL 步驟1:更新軟件包列表 步驟2:安裝MySQL服務器 步驟3:啟動MySQL服務 步驟4:檢查MySQL狀態 步驟5:修改密碼、權限 在線安裝MySQL 步驟1:更新軟件包列表 在進行任何軟件安裝之前&a…

p9函數(1)

int Add(int x,int y) { int z0; zxy; return z; } int main() { int a10; int b20; int sumAdd(a,b); printf("%d\n",sum); return 0; } 字符串求長度 int main() { char arr1[]"bit"; char arr2[20]"###…

移動UI: 什么特征會被認為是簡潔風格,用案例告訴你

什么是簡潔風格,恐怕一百個人有一百個是理解,本文通過理論分析案例的方式進行探討。 移動 UI 中的簡潔風格通常具有以下幾個特征: 1. 平面化設計: 簡潔風格的移動 UI 善于運用平面化設計,即去除過多的陰影、漸變和立…

水冷液冷負載系統的六種基本類型

您可以選擇六種基本類型的冷卻系統,以滿足負載的冷卻需求。每個人都有其優點和缺點。本文旨在識別不同類型的冷卻系統并確定它們的優缺點,以便您可以根據自己的需求做出明智的選擇。 液體冷卻系統有六種基本類型: 1.液對液 2.閉環干燥系統…

聚類標簽的藝術:SKlearn中的數據聚類標簽分配策略

聚類標簽的藝術:SKlearn中的數據聚類標簽分配策略 在機器學習領域,聚類是一種無監督學習方法,旨在將數據集中的樣本劃分為若干個簇,使得同一簇內的樣本相似度高,而不同簇之間的樣本相似度低。聚類標簽分配是聚類過程中…

深度講解 UUID/GUID 的結構、原理以及生成機制

目錄 一. 前言 二. 被廣泛使用 三. UUID 的結構 3.1. 必須了解的 3.2. 十六進制數字字符(hexDigit) 3.3. UUID 基本結構 3.4. 類型(變體)和保留位 3.5. 版本(子類型) 3.6. 時間戳 3.7. 時鐘序列 …

管理《歐盟數字服務法》交易者要求

《數字服務法》合規性 根據《數字服務法》(DSA) 的要求,對于在歐盟地區 (EU) 通過 App Store 分發 App 的所有交易商,Apple 需要驗證并顯示其聯系信息。請指明你是否將以交易商或非交易商的身份在歐盟地區分發任何內容。進一步了解你是否應為交易商。 …

[激光原理與應用-101]:南京科耐激光-激光焊接-焊中檢測-智能制程監測系統IPM介紹 - 5 - 3C行業應用 - 電子布局類型

目錄 前言: 一、激光在3C行業的應用概述 1.1 概述 1.2 激光焊接在3C-電子行業應用 二、3C電子行業中激光焊接 2.1 紐扣電池 2.2 均溫板 2.3 指紋識別器 2.4 攝像頭模組 2.5 IC芯片切割 三、3C行業中激光切割 四、激光在3C行業中的其他應用 4.1 涂層去除…

Golang | Leetcode Golang題解之第222題完全二叉樹的節點個數

題目&#xff1a; 題解&#xff1a; func countNodes(root *TreeNode) int {if root nil {return 0}level : 0for node : root; node.Left ! nil; node node.Left {level}return sort.Search(1<<(level1), func(k int) bool {if k < 1<<level {return false}…

包裝工程期刊

《包裝工程》&#xff08;Packaging Engineering&#xff09;創刊于1980年&#xff0c;原刊名為《防腐包裝》&#xff0c;由聶榮臻元帥親筆題寫。主管單位為中國兵器裝備集團有限公司&#xff0c;主辦單位為西南技術工程研究所&#xff0c;出版單位為《包裝工程》編輯部。目前期…

【CSS】縮寫屬性gap

在CSS Grid Layout&#xff08;網格布局&#xff09;和Flexbox&#xff08;彈性盒布局&#xff09;中&#xff0c;gap 是一個縮寫屬性&#xff0c;用于同時設置行間隙&#xff08;gutter&#xff09;和列間隙&#xff08;在Flexbox中通常稱為“交叉軸間隙”&#xff09;的大小。…

Linux 網絡抓包工具tcpdump編譯

tcpdump 的編譯步驟 1. 下載源代碼 訪問 tcpdump 的官方網站&#xff08;如&#xff1a;http://www.tcpdump.org/&#xff09;下載最新的源代碼壓縮包&#xff0c;如tcpdump-4.9.2.tar.gz&#xff08;注意版本號可能會有所不同&#xff09;。 2. 解壓縮源代碼 使用 tar 命令…

ubuntu22.04+pytorch2.3安裝PyG圖神經網絡庫

ubuntu下安裝torch-geometric庫&#xff0c;圖神經網絡 開發環境 ubuntu22.04 conda 24.5.0 python 3.9 pytorch 2.0.1 cuda 11.8 pyg的安裝網上教程流傳著許多安裝方式&#xff0c;這些安裝方式主要是&#xff1a;預先安裝好pyg的依賴庫&#xff0c;這些依賴庫需要對應上pyth…

貝葉斯優化包的基礎介紹

以下為該學習地址的學習筆記 學習地址&#xff1a;Basic tour of the Bayesian Optimization package — Bayesian Optimization documentation 貝葉斯優化簡介 貝葉斯優化是一種基于貝葉斯推斷和高斯過程的全局優化方法&#xff0c;它試圖在盡可能少的迭代次數內找到一個未…

【Dison夏令營 Day 12】如何用 Python 構建數獨游戲

通過本綜合教程&#xff0c;學習如何使用 Pygame 在 Python 中創建自己的數獨游戲。本指南涵蓋安裝、游戲邏輯、用戶界面和計時器功能&#xff0c;是希望創建功能性和可擴展性數獨益智游戲的愛好者的理想之選。 數獨是一種經典的數字謎題&#xff0c;多年來一直吸引著謎題愛好…

實例方法與靜態方法的區別與使用場景

實例方法與靜態方法的區別與使用場景 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 實例方法與靜態方法的區別 在面向對象編程中&#xff0c;方法可以分為實…

昇思MindSpore25天學習Day19:CycleGAN圖像風格遷移互換

(TOC)[CycleGAN圖像風格遷移呼喚] 模型介紹 模型簡介 CycleGAN(Cycle Generative Adversaial Network)即循環對抗生成網絡&#xff0c;來自論文Link:Unpaired lmage-to-mage Translation using Cycle-Consistent AdvesairalNetworks該模型實現了—種在沒有配對示例的情況下學…

從nginx返回404來看http1.0和http1.1的區別

序言 什么樣的人可以稱之為有智慧的人呢&#xff1f;如果下一個定義&#xff0c;你會如何來定義&#xff1f; 所謂智慧&#xff0c;就是能區分自己能改變的部分&#xff0c;自己無法改變的部分&#xff0c;努力去做自己能改變的&#xff0c;而不要天天想著那些無法改變的東西&a…

解析Java中的反射機制及其應用場景

解析Java中的反射機制及其應用場景 大家好&#xff0c;我是微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; Java的反射機制是指在運行時可以動態地獲取類的信息&#xff08;如類名、方法、字段等&#xff09;&#xff0c;并…

麒麟桌面操作系統上網絡設置界面消失的解決方法

原文鏈接&#xff1a;麒麟桌面操作系統上網絡設置界面消失的解決方法 Hello&#xff0c;大家好啊&#xff01;今天給大家帶來一篇關于麒麟桌面操作系統上網絡設置界面消失解決方法的文章。在使用麒麟桌面操作系統時&#xff0c;可能會遇到網絡設置界面突然消失的情況&#xff…