逆向软件设计—网上购书结账系统

news/2025/2/27 22:18:56/文章来源:https://www.cnblogs.com/ccYaxuan/p/18737324

一、作业要求
找一个已有的项目(同学、高年级同学、网络下载),阅读分析,找出软件尚存的缺陷, 改进其软件做二次开发,并将这个过程整理成一份博客。
二、原项目介绍
本次课程设计我逆向开发的软件是一个使用c++编写的网上购书结账系统,原作者是22软工2班的熊知宇学长,学号2252721。

该网上购书结账系统已经包含了必要的注册、登录、购书、查看信息等功能,操作简单,运行效率高,界面设计简洁明了,代码量较少,逻辑清晰,容易定位问题,适合快速原型开发,不需要复杂的设计和架构。
(一)源代码如下:

点击查看代码
#include<iostream>
#include<cmath>
#include<string>
#include<conio.h>
#include<fstream>
#include<vector>using namespace std;//基类buyer
class buyer {
protected:string name;string address;int id;double pay;string usersname;string password;
public:buyer();//默认某个值buyer(string n, string a, int i, double p, string u, string pa);//构造函数string GetName();string GetAddress();string GetUsersname();string GetPassword();int GetId();double GetPay();virtual void display() = 0;//显示对象信息virtual void setpay(double p = 0) = 0;//计算消费
};
buyer::buyer() {name = "";address = "";id = 0;pay = 0;
}
buyer::buyer(string n, string a, int i, double p, string u, string pa) {name = n;address = a;id = i;pay = p;usersname = u;password = pa;
}
string buyer::GetAddress() {return address;
}
string buyer::GetName() {return name;
}
string buyer::GetUsersname() { return usersname; }
string buyer::GetPassword() { return password; }
int buyer::GetId() {return id;
}
double buyer::GetPay() {return pay;
}//普通人类folk
class folk :public buyer {
public:folk(string n, string a, int i, double p, string u, string pa) :buyer(n, a, i, p, u, pa) {}void display();void setpay(double p);
};
void folk::display() {cout << "购书人姓名:" << name << endl;cout << "购书人编号:" << id << endl;cout << "购书人类型:普通用户" << endl;cout << "购书人地址:" << address << endl;cout << "消费金额:" << pay << endl;
}
void folk::setpay(double p) {pay += p;
}//会员类vip
class vip :public buyer {
private:short vip_grade;
public:vip(string n, string a, int i, double p, short g, string u, string pa);void display();void setpay(double p);short GetGrade();
};
vip::vip(string n, string a, int i, double p, short g, string u, string pa) :buyer(n, a, i, p, u, pa) {vip_grade = g;
}
void vip::display() {cout << "购书人姓名:" << name << endl;cout << "购书人编号:" << id << endl;cout << "购书人为" << vip_grade << "级会员" << endl;cout << "购书人地址:" << address << endl;cout << "消费金额:" << pay << endl;
}
void vip::setpay(double p) {if (vip_grade == 1) {pay += p * 0.95;}else if (vip_grade == 2) {pay += p * 0.9;}else if (vip_grade == 3) {pay += p * 0.85;}else if (vip_grade == 4) {pay += p * 0.8;}else if (vip_grade == 5) {pay += p * 0.7;}else {cout << "会员级别有误!" << endl;}
}
short vip::GetGrade() { return vip_grade; }//贵宾类svip
class svip :public buyer {
private:double discount;
public:svip(string n, string a, int i, double p, double d, string u, string pa);void display();void setpay(double p);double GetDiscount();
};
svip::svip(string n, string a, int i, double p, double d, string u, string pa) :buyer(n, a, i, p, u, pa) {discount = d;
}
void svip::display() {cout << "购书人姓名:" << name << endl;cout << "购书人编号:" << id << endl;cout << "购书人为贵宾,折扣率为:" << discount << endl;cout << "购书人地址:" << address << endl;cout << "消费金额:" << pay << endl;
}
void svip::setpay(double p) {pay += p * discount;
}
double svip::GetDiscount() { return discount; }class book {
public:string num, bname;short price;book(string num, string bname, short price) {this->num = num;this->bname = bname;this->price = price;}};class ListNode;
void welcome();
void insert_info(ListNode* head);
void search_info(ListNode* head);
void print_info(ListNode* head);
void buy_book(ListNode* head);
void booklist();
void loadin(ListNode* head);
void addpay(ListNode* head, short p);
void save_info2(vector<book>& books);
void load_info2();
void newbook();
void save_info1(ListNode* head);
void load_info(ListNode* head);
void CheckUsersname(ListNode* head);
void Checkpassword(ListNode* head);// 定义链表节点的类
class ListNode {
public:buyer* data; // 指向buyer类对象的指针ListNode* next; // 指向下一个节点的指针ListNode() {data = nullptr;next = nullptr;}
};class BookNode {
public:book* data;BookNode* next;BookNode() {data = nullptr;next = nullptr;}
};string na, users, pass;
int flag;int main() {// 创建链表的头节点ListNode* head = new ListNode();BookNode* hhead = new BookNode();load_info(head);while (true) {welcome();cout << "请选择功能>> ";short _n;cin >> _n;switch (_n) {case 1:insert_info(head);break;case 2:search_info(head);break;case 3:print_info(head);break;case 4:buy_book(head);break;case 5:cout << "欢迎下次光临!" << endl;exit(0);default:cout << "输入有误,请重新输入!" << endl;break;}}// 释放动态分配的内存ListNode* p = head;while (p != nullptr) {ListNode* tmp = p;p = p->next;delete tmp->data;delete tmp;}return 0;
}void welcome() {cout << "**\t\t" << "网上购书结账系统" << "\t**" << endl;cout << "**\t\t" << "1.注册信息" << "\t\t**" << endl;cout << "**\t\t" << "2.查询个人" << "\t\t**" << endl;cout << "**\t\t" << "3.信息列表" << "\t\t**" << endl;cout << "**\t\t" << "4.购买图书" << "\t\t**" << endl;cout << "**\t\t" << "5.退出系统" << "\t\t**" << endl;
}void booklist() {cout << "图书信息:" << endl;cout << "1.书号:7-301-07854-1\t\t书名:《秒速五厘米》\t\t定价:20元" << endl;cout << "2.书号:7-300-01562-4\t\t书名:《你的名字》\t\t定价:35元" << endl;cout << "3.书号:7-372-01532-5\t\t书名:《言叶之庭》\t\t定价:15元" << endl;cout << "4.书号:7-356-02512-3\t\t书名:《天气之子》\t\t定价:25元" << endl;cout << "5.书号:7-345-09655-7\t\t书名:《铃芽之旅》\t\t定价:25元" << endl;
}void insert_info(ListNode* head) {string name, address;int id;double pay;short vip_grade;double discount;int type;cout << "请输入购书人姓名:";cin >> name;cout << "请输入购书人地址:";cin >> address;cout << "请输入购书人编号:";cin >> id;cout << "请创建您的用户名:";CheckUsersname(head);cout << "请创建您的密码:";Checkpassword(head);pay = 0;cout << "请选择购书人类型(1代表普通用户,2代表会员,3代表贵宾):";cin >> type;if (type == 1) {buyer* b = new folk(name, address, id, pay, users, pass);ListNode* node = new ListNode();node->data = b;// 将节点插入到链表中node->next = head->next;head->next = node;cout << "注册成功!" << endl;}else if (type == 2) {cout << "请输入会员级别(1~5):";cin >> vip_grade;buyer* b = new vip(name, address, id, pay, vip_grade, users, pass);ListNode* node = new ListNode();node->data = b;// 将节点插入到链表中node->next = head->next;head->next = node;cout << "注册成功!" << endl;}else if (type == 3) {cout << "请输入折扣率(0~1):";cin >> discount;buyer* b = new svip(name, address, id, pay, discount, users, pass);ListNode* node = new ListNode();node->data = b;// 将节点插入到链表中node->next = head->next;head->next = node;cout << "注册成功!" << endl;}else {cout << "购书人类型输入有误,请重新输入!" << endl;}save_info1(head);system("pause");system("cls");
}void search_info(ListNode* head) {cout << "请输入要查询的购书人的用户名:";string uname;cin >> uname;ListNode* p = head->next;while (p != nullptr) {if (p->data->GetUsersname() == uname) {p->data->display();system("pause");system("cls");return;}else {p = p->next;}}cout << "没有找到该购书人信息!" << endl;system("pause");system("cls");
}void print_info(ListNode* head) {// 遍历链表,输出所有buyer类对象的信息ListNode* p = head->next;while (p != nullptr) {p->data->display();cout << "---------------------" << endl;p = p->next;}system("pause");system("cls");
}void buy_book(ListNode* head) {loadin(head);if (flag == 1) {booklist();cout << "请选择你想要购买的图书序号:" << endl;short ch;cin >> ch;switch (ch) {case 1:addpay(head, 20);break;case 2:addpay(head, 35);break;case 3:addpay(head, 15);case 4:addpay(head, 25);case 5:addpay(head, 25);}save_info1(head);system("pause");system("cls");}elsesystem("pause");system("cls");
}void addpay(ListNode* head, short p) {ListNode* pmove = head->next;while (pmove != nullptr) {if (pmove->data->GetUsersname() == na) {pmove->data->setpay(p);cout << "您需要支付的费用是:" << pmove->data->GetPay() << "元" << endl;cout << "按任意键自动扣款" << endl;_getch();cout << "自动扣款成功!" << endl;break;}else {pmove = pmove->next;if (pmove->next == nullptr) {cout << "ERROR" << endl;}}}
}void loadin(ListNode* head) {cout << "请先输入用户名:" << endl;string uname, pasw;cin >> uname;ListNode* pmove = head->next;while (pmove != nullptr) {if (pmove->data->GetUsersname() == uname) {cout << "请输入密码" << endl;cin >> pasw;if (pmove->data->GetPassword() != pasw) {cout << "密码错误!" << endl;flag = 0;break;}na = pmove->data->GetUsersname();flag = 1;break;}else {pmove = pmove->next;if (pmove->next == nullptr) {cout << "未查询到信息!" << endl;flag = 0;return;}}}}void save_info1(ListNode* head) {string filename = R"(C:\Users\熊知宇\Desktop\程序期末大作业\buyer.txt)";ofstream fout(filename, ios::trunc);if (!fout.is_open()) {cout << "打开文件失败!" << endl;return;}// 遍历链表,将buyer类对象的信息写入文件ListNode* p = head->next;while (p != nullptr) {fout << p->data->GetName() << " ";fout << p->data->GetAddress() << " ";fout << p->data->GetId() << " ";fout << p->data->GetPay() << " ";if (dynamic_cast<vip*>(p->data)) {fout << "2" << " ";fout << dynamic_cast<vip*>(p->data)->GetGrade() << " ";fout << p->data->GetUsersname() << " ";fout << p->data->GetPassword() << endl;}else if (dynamic_cast<svip*>(p->data)) {fout << "3" << " ";fout << dynamic_cast<svip*>(p->data)->GetDiscount() << " ";fout << p->data->GetUsersname() << " ";fout << p->data->GetPassword() << endl;}else {fout << "0" << " ";fout << "1" << " ";fout << p->data->GetUsersname() << " ";fout << p->data->GetPassword() << endl;}p = p->next;}fout.close();cout << "信息存储成功!" << endl;
}void load_info(ListNode* head) {string filename = R"(C:\Users\熊知宇\Desktop\程序期末大作业\buyer.txt)";ifstream fin;fin.open(filename, ios::in);if (!fin.is_open()) {cout << "打开文件失败!" << endl;return;}string name, address, usersname, password;int id;double pay;short vip_grade;double discount;int type;while (fin >> name >> address >> id >> pay >> type) {if (type == 2) {fin >> vip_grade;fin >> usersname >> password;buyer* b = new vip(name, address, id, pay, vip_grade, usersname, password);ListNode* node = new ListNode();node->data = b;// 将节点插入到链表中node->next = head->next;head->next = node;}else if (type == 3) {fin >> discount;fin >> usersname >> password;buyer* b = new svip(name, address, id, pay, discount, usersname, password);ListNode* node = new ListNode();node->data = b;// 将节点插入到链表中node->next = head->next;head->next = node;}else {fin >> usersname >> password;buyer* b = new folk(name, address, id, pay, usersname, password);ListNode* node = new ListNode();node->data = b;// 将节点插入到链表中node->next = head->next;head->next = node;}}fin.close();cout << "信息读取成功!" << endl;
}void CheckUsersname(ListNode* head) {ListNode* pmove = head->next;string CinUsersname;cin >> CinUsersname;while (pmove != nullptr) {if (pmove->data->GetUsersname() == CinUsersname) {cout << "用户名已存在!\n请重新输入!" << endl;return;}pmove = pmove->next;}users = CinUsersname;
}void Checkpassword(ListNode* head) {ListNode* pmove = head->next;string CinPassword;cin >> CinPassword;while (pmove != nullptr) {if (pmove->data->GetUsersname() == CinPassword) {cout << "密码已存在!\n请重新输入!" << endl;return;}pmove = pmove->next;}pass = CinPassword;
}void save_info2(vector<book>& books) {string filename = R"(C:\Users\熊知宇\Desktop\程序期末大作业\book.txt)";ofstream fout(filename, ios::app);if (!fout.is_open()) {cout << "打开文件失败!" << endl;return;}for (const auto& b : books) {fout << b.num << " ";fout << b.bname << " ";fout << b.price << endl;}fout.close();cout << "信息存储成功!" << endl;
}

(二)改进前运行截图:
客户注册信息:

查询个人信息:

信息列表查询:

购买图书操作:

信息列表查询:

但仍有一些可以优化的地方。以下是一些优化建议:

(三)功能模块图
改进前的功能模块图:

改进后的功能模块图:

(四)代码修改

  1. 主菜单分离管理员和用户登录

原代码:

点击查看代码
void welcome() {
cout << "**\t\t" << "网上购书结账系统" << "\t**" << endl;
cout << "**\t\t" << "1.注册信息" << "\t\t**" << endl;cout << "**\t\t" << "2.查询个人" << "\t\t**" << endl;cout << "**\t\t" << "3.信息列表" << "\t\t**" << endl;cout << "**\t\t" << "4.购买图书" << "\t\t**" << endl;cout << "**\t\t" << "5.退出系统" << "\t\t**" << endl;
}
修改后新代码:
点击查看代码
void Welcome() {cout << "**\t\t" << "网上购书结账系统" << "\t**" << endl;cout << "**\t\t" << "1. 管理员登录" << "\t\t**" << endl;cout << "**\t\t" << "2. 用户登录" << "\t\t**" << endl;cout << "**\t\t" << "3. 退出系统" << "\t\t**" << endl;
}

修改后的好处:

功能分离:将管理员和用户的功能分开,避免功能混杂。
逻辑清晰:用户和管理员的操作路径更加明确,提升了系统的易用性。
2. 增加管理员登录功能
原代码:无管理员登录功能。
新代码:

点击查看代码
void AdminLogin() {string username, password;cout << "请输入管理员用户名:";cin >> username;cout << "请输入管理员密码:";cin >> password;if (username == "admin" && password == "admin123") {cout << "管理员登录成功!" << endl;unique_ptr<ListNode> head = make_unique<ListNode>();vector<Book> books;LoadInfo(head.get());LoadBooks(books);AdminMenu(head.get(), books);} else {cout << "管理员用户名或密码错误!" << endl;}
}
修改后的好处:

权限控制:只有管理员可以管理书籍和用户信息,增强了系统的安全性。
功能扩展:管理员可以录入、查看、删除书籍信息,以及查询用户信息。
3. 增加用户登录功能
原代码:用户登录功能与购书功能混杂在一起。
新代码:

点击查看代码
void UserLogin() {unique_ptr<ListNode> head = make_unique<ListNode>();vector<Book> books;LoadInfo(head.get());LoadBooks(books);string username, password;cout << "请输入用户名:";cin >> username;cout << "请输入密码:";cin >> password;ListNode* current = head->next.get();while (current != nullptr) {if (current->data->GetUsername() == username && current->data->GetPassword() == password) {cout << "用户登录成功!" << endl;UserMenu(head.get(), books);return;}current = current->next.get();}cout << "用户名或密码错误!" << endl;
}

修改后的好处:

功能分离:用户登录后只能进行书籍查询和购买,逻辑更加清晰。
用户体验提升:用户登录后可以直接进入用户菜单,操作更加便捷。
4. 增加管理员菜单
原代码:无管理员菜单。
新代码:

点击查看代码
void AdminMenu(ListNode* head, vector<Book>& books) {while (true) {cout << "**\t\t" << "管理员菜单" << "\t\t**" << endl;cout << "**\t\t" << "1. 录入图书" << "\t\t**" << endl;cout << "**\t\t" << "2. 查看图书" << "\t\t**" << endl;cout << "**\t\t" << "3. 删除图书" << "\t\t**" << endl;cout << "**\t\t" << "4. 查询用户信息" << "\t\t**" << endl;cout << "**\t\t" << "5. 更改用户信息" << "\t\t**" << endl;cout << "**\t\t" << "6. 返回主菜单" << "\t\t**" << endl;cout << "请选择功能>> ";short choice;cin >> choice;switch (choice) {case 1: {string num, name;short price;cout << "请输入书号:";cin >> num;cout << "请输入书名:";cin >> name;cout << "请输入定价:";cin >> price;books.emplace_back(num, name, price);SaveBooks(books);cout << "图书录入成功!" << endl;break;}case 2: {cout << "图书列表:" << endl;for (const auto& book : books) {book.Display();}break;}case 3: {string num;cout << "请输入要删除的书号:";cin >> num;auto it = books.begin();while (it != books.end()) {if (it->num == num) {it = books.erase(it);cout << "图书删除成功!" << endl;SaveBooks(books);break;} else {++it;}}if (it == books.end()) {cout << "未找到该图书!" << endl;}break;}case 4: {string username;cout << "请输入要查询的用户名:";cin >> username;SearchInfo(head);break;}case 5: {string username;cout << "请输入要更改的用户名:";cin >> username;// 更改用户信息逻辑(未实现)cout << "功能未实现!" << endl;break;}case 6: return;default: cout << "输入有误,请重新输入!" << endl; break;}system("pause");system("cls");}
}

修改后的好处:

功能完善:管理员可以录入、查看、删除书籍信息,以及查询用户信息。
灵活性增强:管理员可以动态管理书籍信息,无需修改代码。
5. 增加用户菜单
原代码:用户功能与管理员功能混杂。
新代码:

点击查看代码
void UserMenu(ListNode* head, const vector<Book>& books) {while (true) {cout << "**\t\t" << "用户菜单" << "\t\t**" << endl;cout << "**\t\t" << "1. 查询图书" << "\t\t**" << endl;cout << "**\t\t" << "2. 购买图书" << "\t\t**" << endl;cout << "**\t\t" << "3. 返回主菜单" << "\t\t**" << endl;cout << "请选择功能>> ";short choice;cin >> choice;switch (choice) {case 1: {cout << "图书列表:" << endl;for (const auto& book : books) {book.Display();}break;}case 2: BuyBook(head, books); break;case 3: return;default: cout << "输入有误,请重新输入!" << endl; break;}system("pause");system("cls");}
}

修改后的好处:

功能分离:用户只能查询和购买书籍,逻辑更加清晰。
用户体验提升:用户操作更加简单直观。
6. 书籍信息动态管理
原代码:书籍信息是固定的。
新代码:

点击查看代码
void ManageBooks(vector<Book>& books) {// 书籍录入、查看、删除等功能
}

修改后的好处:

灵活性增强:管理员可以动态管理书籍信息,无需修改代码。
数据持久化:书籍信息存储在文件中,程序重启后不会丢失。
(五)改进后运行截图
主菜单:

管理员登录:

管理员菜单:

录入图书:

查看图书:

删除图书:

返回主菜单:

用户菜单:

用户查询书籍:

用户购买书籍:

返回主菜单:

(六)总结:
通过以上修改,系统实现了以下优化:
1.功能分离:管理员和用户的功能完全分离,逻辑更加清晰。
2.权限控制:管理员可以管理书籍和用户信息,用户只能查询和购买书籍。
3.灵活性增强:管理员可以动态管理书籍信息,用户可以选择更多书籍。
4.用户体验提升:用户和管理员的操作路径更加明确,提升了系统的易用性。
5.数据持久化:用户信息和书籍信息可以长期保存,程序重启后不会丢失。
总之,通过本次对网上购书结账系统的代码修改和优化,我深刻认识到逆向软件设计和开发作为学习软件开发创新的重要手段,具有深远的意义。虽然在日常开发中,纯粹修改他人代码的情况并不多见,但通过逆向分析和优化,我显著提升了阅读和理解他人代码的能力,这对于未来可能面临的团队合作至关重要。
此外,逆向软件设计和开发也在不断锻炼着我的思维。通过分析他人代码中的不足,我能够反思自身在开发中可能存在的类似问题,从而避免重复错误,提升代码质量。这种从他人代码中学习、发现问题并改进的过程,不仅帮助我更好地理解软件设计的核心思想,也为实现软件开发的创新奠定了坚实基础。通过本次实践,我更加明确了模块化设计、数据持久化、输入验证和用户体验优化的重要性,这些经验将为我未来的开发工作提供宝贵的指导。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/890873.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学生管理系统二次开发与优化实践

在软件开发中,对现有项目进行优化和二次开发是一种常见的任务。本次实验中,我选择了一个基于C++开发的学生管理系统作为优化对象。该系统实现了学生信息的增删改查功能,并支持学号排序和模糊查找等功能。通过分析原项目,我发现了几个可以改进的地方,并对系统进行了优化。以…

逆向软件工程

一、来源 本次实验项目来源于c++课程设计:线上图书购买系统 二、运行环境及运行结果 运行环境:vs 2022 Windows 11 运行结果:代码展示: `#include include include "Order.h" include "Book.h" void displayMenu() { std::cout << "1. Ad…

基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真

1.课题概述 基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真。2.系统仿真结果 (完整程序运行后无水印)3.核心程序与模型 版本:MATLAB2022a4.系统原理简介基于最大功率点跟踪(Maximum Power Point Tracking, MPPT)的离网光伏发电系统是利用太阳光直接转换为电能…

[Black Watch 入群题]PWN(栈迁移)

先检查一下保护,32位的分析一下代码,发现buf距离ebp为0x18(24),但是read只溢出0x20(32),也就是只溢出8个字节,刚好覆盖到ret。 第一个read读取0x200到s(.bss段)两个write会打印m1和m2,点击m1,m2查看因为溢出不够,这时候我们可以考虑栈迁移expfrom pwn import * f…

WC Java 实现

一.来源 WC Java 实现(Pramy) https://www.cnblogs.com/pramy/p/9607743.html 二.运行环境及运行结果 运行环境:Visual Studio Code 运行结果截图:* 三.主要问题 1.异常处理不够详细: 在处理文件时,如果文件不存在或无法读取,程序会抛出异常,但没有提供详细的错误信息或…

docker实现的基本原理

Docker 实现容器的基本原理依赖于 Linux 内核的三大核心机制:命名空间(Namespaces)、控制组(cgroups) 和 联合文件系统(UnionFS),也是 Docker 能够出现的最重要原因。 1. 命名空间(Namespaces) 作用:实现资源的隔离,使容器内的进程无法感知或干扰宿主机的其他进程或…

将DeepSeek接入人类大脑会怎样??

昨天在与同事聊起最近大火的DeepSeek, 突然,有一个不切实际的想法,如果DeepSeek或人工智能AI能以某种形式接入人类大脑, 比如,通过芯片不侵入式连接大脑 或者 外带什么眼镜、 隐形眼镜之类的, 能人类有DeepSeek一样的知识量以及响应速度,那得多好,整个世界、人类将会变…

gh-ost工具介绍及使用

💖简介 gh-ost 是一款由GitHub开发的在线DDL(Online Data Definition Language)变更工具,专门用于MySQL数据库。它允许在不锁定表的情况下执行数据库模式变更,从而避免了传统ALTER TABLE命令可能带来的长时间锁表问题,这对于高可用性要求严格的生产环境尤为重要。 它通过…

[算法]KD树

KD树,你看着他好几个维度不明白,但实际上非常简单 \(K\)指维度 因此他可以在二维(多维)平面内进行搜索!!! 1.二维 1.1 建树 对于每一层,我们使用轮转法进行建树 什么意思呢?比如二维,如果\(x\)层为一维(横坐标),则\((x+1)\)层为二维(纵坐标) 确定好维数,接下来…

事务的ACID原则

atomic原子性,事务包含一批读写操作要么都提交,要不都回滚,在并发状态下另一个线程看到的这个线程操作的事务一定是完整的,要不都没看见,要么都看见,不存在看见一半的情况。 consiste一致性,对数字的一组特定的约束条件必须成立,例如转账业务中的进账和出账必须能相抵。…

Python Flask Web应用的二次开发

我选择了一个简单的Python Flask Web应用,它是一个简易的任务管理系统,能实现任务的添加和查看,但存在不少可优化之处。 1.来源 这个简易的任务管理系统是某位学长的开源项目。原作者的目的是提供一个基础的任务管理功能示例,方便开发者学习Flask框架的基本使用。 2.运行环…