当前位置: 首页 > news >正文

【Java学习笔记】72 - 满汉楼 - 餐饮管理系统

项目代码

https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter26

一、需求说明

满汉楼项目功能多,界面复杂,涉及到复杂的awt和swing技术和事件编程,做如下调整: 

1.去掉界面和事件处理(工作中使用很少),使用控制台界面

2.完成满汉楼项目的登录、订座、点餐和结账、查看账单等功能.

3.在实际工作中,独立完成项目新功能非常重要,这是锻炼编程能力和思想的重要途径

1.用户登录

2.显示餐桌的状态

3.预定

4.显示菜品

5.点餐

6.查看账单

7.结账

 二、项目设计

三、功能实现

1.显示主菜单、二级菜单和退出系统功能

public void mainMenu(){while (loop){System.out.println("==============满汉楼===============");System.out.println("\t\t1.登录满汉楼");System.out.println("\t\t2.退出满汉楼");System.out.println("请输入你的选择");key = Utility.readString(1);switch (key){case "1":System.out.println("输入员工号:");String id = Utility.readString(50);System.out.println("输入密 码");String pwd = Utility.readString(50);//到数据库去判断if("123".equals(pwd)){System.out.println("===========登录成功===========");while(loop){System.out.println("=========满汉楼(二级菜单)==========");System.out.println("\t\t1 显示餐桌状态");System.out.println("\t\t2 预定餐桌状态");System.out.println("\t\t3 显示所有菜品");System.out.println("\t\t4 点餐服务");System.out.println("\t\t5 查看账单");System.out.println("\t\t6 结账");System.out.println("\t\t9 退出满汉楼");key = Utility.readString(1);switch (key){case "1":System.out.println("显示餐桌状态");break;case "2":System.out.println("预定餐桌");break;case "3":System.out.println("显示所有菜品");break;case "4":System.out.println("点餐服务");break;case "5":System.out.println("查看账单");break;case "6":System.out.println("结账");break;case "9":loop = false;break;default:System.out.println("你的输入有误 请重新输入");}}}else{System.out.println("===========登录失败===========");}break;case "2":System.out.println("2.退出满汉楼");loop = false;break;default:System.out.println("输入错误错误");}}System.out.println("退出满汉楼");}

2.用户登录

CREATE DATABASE mhl
#用户表
CREATE TABLE employee (id INT PRIMARY KEY AUTO_INCREMENT, #自增empId VARCHAR(50) UNIQUE NOT NULL DEFAULT '',#员工号pwd CHAR(32) NOT NULL DEFAULT '',#密码md5NAME VARCHAR(50) NOT NULL DEFAULT '',#姓名job VARCHAR(50) NOT NULL DEFAULT '' #岗位
)CHARSET=utf8; DROP TABLE employee
#添加测试数据
INSERT INTO employee VALUES(NULL, '6668612', MD5('123456'), '张三丰', '经理');
INSERT INTO employee VALUES(NULL, '6668622', MD5('123456'),'小龙女', '服务员');
INSERT INTO employee VALUES(NULL, '6668633', MD5('123456'), '张无忌', '收银员');
INSERT INTO employee VALUES(NULL, '666666', MD5('123456'), '老韩', '经理');
SELECT * FROM employee

/*** @author 银小海* @version 1.0* @email yinhai14@qq.com* 该类调用EmployeeDAO对象完成对表的各种操作*/
public class EmployeeService {//定义一个EmployeeDAO属性private EmployeeDAO employeeDAO = new EmployeeDAO();//方法 根据empId和pwd返回一个Employee对象public Employee getEmployeeByIdAndPwd(String empId,String pwd){return employeeDAO.querySingle("select * from employee where empId=? and pwd=md5(?)", Employee.class, empId, pwd);}
}

 该服务并不直接修改数据库,而是通过DAO调用JDBCDruid修改数据库

             if(employee != null){System.out.println("===========登录成功(" + employee.getName() + ")===========");while(loop){

3.显示餐桌状态 

1.创建新的餐位表

2.domain里设计一个类对应该表

3.DAO类对表crud

4.service调用DAO修改

-- 创建diningTable 表(id, state , orderName, orderTel ....)CREATE TABLE diningTable (id INT PRIMARY KEY AUTO_INCREMENT, #自增, 表示餐桌编号state VARCHAR(20) NOT NULL DEFAULT '',#餐桌的状态orderName VARCHAR(50) NOT NULL DEFAULT '',#预订人的名字orderTel VARCHAR(20) NOT NULL DEFAULT ''
)CHARSET=utf8; 
#测试数据
INSERT INTO diningTable VALUES(NULL, '空','','');
INSERT INTO diningTable VALUES(NULL, '空','','');
INSERT INTO diningTable VALUES(NULL, '空','','');
SELECT * FROM diningTable

2.设计一个类对应 该表 

/*** @author 银小海* @version 1.0* @email yinhai14@qq.com* 一个javabean 和diningTable表对应* 	id INT PRIMARY KEY AUTO_INCREMENT, #自增, 表示餐桌编号* 	state VARCHAR(20) NOT NULL DEFAULT '',#餐桌的状态* 	orderName VARCHAR(50) NOT NULL DEFAULT '',#预订人的名字* 	orderTel VARCHAR(20) NOT NULL DEFAULT ''*/public class DiningTable {private Integer id;private String state;private String orderName;private String orderTel;public DiningTable() {}public DiningTable(Integer id, String state, String orderName, String orderTel) {this.id = id;this.state = state;this.orderName = orderName;this.orderTel = orderTel;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getState() {return state;}public void setState(String state) {this.state = state;}public String getOrderName() {return orderName;}public void setOrderName(String orderName) {this.orderName = orderName;}public String getOrderTel() {return orderTel;}public void setOrderTel(String orderTel) {this.orderTel = orderTel;}@Overridepublic String toString() {return id + "\t\t\t" + state;}
}

4.

public class DiningTableService {//定义一个DiningTableDAO对象private DiningTableDAO diningTableDAO = new DiningTableDAO();//返回所有餐桌的信息public List<DiningTable> list(){return diningTableDAO.queryMulti("select id,state from diningTable", DiningTable.class);}
}

4.订座

功能说明如果该餐桌处于已经预定或者就餐状态,给出提示

1.在DiningTableService内添加对应方法

//根据id 查询对应的DiningTable对象 如果返回null 表示id编号对应餐桌不存在public DiningTable getDiningTableById(int id){//把sql语句放到查询分析器去测试一下return diningTableDAO.querySingle("select * from diningTable where id = ?",DiningTable.class,id);}//如果餐桌可以预定 调用方法对其状态进行更新public boolean orderDiningTable(int id,String orderName,String orderTel) {int dml =diningTableDAO.dml("update diningTable set state = '已经" +"预定',orderName = ?,orderTel=? where id = ?", orderName, orderTel, id);return dml > 0;}

 2.在view内添加判断用户输入方法,并在对应阶段调用该方法即可

//预定餐桌public void orderDiningTable(){System.out.println("=========预定餐桌==========");System.out.println("请选择要预定的餐桌的编号(-1退出)");int orderId = Utility.readInt();if(orderId == -1){return;}DiningTable diningTable = diningTableService.getDiningTableById(orderId);if(diningTable == null){ //说明不存在System.out.println("==========该餐桌不存在=========");return;}char key = Utility.readConfirmSelection();//输入Y/Nif (key == 'Y'){//要预定就调用方法 如果为null该对象不存在if(!("空".equals(diningTable.getState()))){System.out.println("==========该餐桌已被预定或就餐中=========");return;}System.out.println("预订人的名字:");String orderName = Utility.readString(50);System.out.println("预订人的电话:");String orderTel = Utility.readString(50);if(diningTableService.orderDiningTable(orderId,orderName,orderTel)){System.out.println("预定餐桌成功");}else{System.out.println("预定餐桌失败");}//过关斩将}else{System.out.println("=========取消预定餐桌==========");}}

5.显示菜品

1.需要创建一个新的菜单表

2.需要在java内建立domain类

3.需要创建菜单的DAO类

4.需要service组织sql并调用DAO

-- 创建menu表(id, name, type, price)
#菜谱
CREATE TABLE menu (id INT PRIMARY KEY AUTO_INCREMENT, #自增主键,作为菜谱编号(唯一)NAME VARCHAR(50) NOT NULL DEFAULT '',#菜品名称TYPE VARCHAR(50) NOT NULL DEFAULT '', #菜品种类price DOUBLE NOT NULL DEFAULT 0#价格
)CHARSET=utf8; 
#测试数据
INSERT INTO menu VALUES(NULL, '八宝饭', '主食', 10);
INSERT INTO menu VALUES(NULL, '叉烧包', '主食', 20);
INSERT INTO menu VALUES(NULL, '宫保鸡丁', '热菜', 30);
INSERT INTO menu VALUES(NULL, '山药拨鱼', '凉菜', 14);
INSERT INTO menu VALUES(NULL, '银丝卷', '甜食', 9);
INSERT INTO menu VALUES(NULL, '水煮鱼', '热菜', 26);
INSERT INTO menu VALUES(NULL, '甲鱼汤', '汤类', 100);
INSERT INTO menu VALUES(NULL, '鸡蛋汤', '汤类', 16);

2.在java内创建domain的Menu类 对应表的对象

/*** @author 银小海* @version 1.0* @email yinhai14@qq.com* 该javabean和 menu 表对应*  id INT PRIMARY KEY AUTO_INCREMENT, #自增, 表示餐桌编号* 	state VARCHAR(20) NOT NULL DEFAULT '',#餐桌的状态* 	orderName VARCHAR(50) NOT NULL DEFAULT '',#预订人的名字* 	orderTel VARCHAR(20) NOT NULL DEFAULT ''*/
public class Menu {private Integer id;private String name;private String type;private Double price;public Menu(){//无参构造器}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getType() {return type;}public void setType(String type) {this.type = type;}public Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}public Menu(Integer id, String name, String type, Double price) {this.id = id;this.name = name;this.type = type;this.price = price;}
}

3.DAO继承BasicDAO

4.service类 组织sql调用DAO

public class MenuService {private MenuDAO menuDAO = new MenuDAO();//返回所有的菜品public List<Menu> list(){return menuDAO.queryMulti("select * from menu",Menu.class);}}

在view内编写方法调用service类的方法

public void listMenu(){List<Menu> list = menuService.list();System.out.println("\n菜品编号\t\t菜品名\t\t类别\t\t价格");for (Menu menu : list) {System.out.println(menu);}System.out.println("=========显示完毕==========");
}

6.点餐

功能说明要求对餐桌号,菜品编号,做合理性校验,如果不合理,给出提示信息

餐桌号 菜品号 检验是否合理,点餐成功,需要修改餐桌状态,生成账单

1.需要创建一个新的账单表

2.需要在java内建立domain类

3.需要创建菜单的DAO类

4.需要service组织sql并调用DAO

1.新建账单表


#增加表 bill 账单表(id, billId, menuId, nums, billDate, money, state, diningTableId )
#账单流水, 考虑可以分开结账, 并考虑将来分别统计各个不同菜品的销售情况
CREATE TABLE bill (id INT PRIMARY KEY AUTO_INCREMENT, #自增主键billId VARCHAR(50) NOT NULL DEFAULT '',#账单号可以按照自己规则生成 UUIDmenuId INT NOT NULL DEFAULT 0,#菜品的编号, 也可以使用外键nums INT NOT NULL DEFAULT 0,#份数money DOUBLE NOT NULL DEFAULT 0, #金额diningTableId INT NOT NULL DEFAULT 0, #餐桌billDate DATETIME NOT NULL ,#订单日期state VARCHAR(50) NOT NULL DEFAULT '' # 状态 '未结账' , '已经结账', '挂单','现金','支付宝','坏账'
)CHARSET=utf8;SELECT * FROM bill;

2.创建domain类 javabean

/*** @author 银小海* @version 1.0* @email yinhai14@qq.com* 	id INT PRIMARY KEY AUTO_INCREMENT, #自增主键* 	billId VARCHAR(50) NOT NULL DEFAULT '',#账单号可以按照自己规则生成 UUID* 	menuId INT NOT NULL DEFAULT 0,#菜品的编号, 也可以使用外键* 	nums INT NOT NULL DEFAULT 0,#份数* 	money DOUBLE NOT NULL DEFAULT 0, #金额* 	diningTableId INT NOT NULL DEFAULT 0, #餐桌* 	billDate DATETIME NOT NULL ,#订单日期* 	state VARCHAR(50) NOT NULL DEFAULT '' # 状态 '未结账' , '已经结账', '挂单','现*/
public class Bill {private Integer id;private String billId;private Integer menuId;private Integer nums;private Double money;private Integer diningTableId;private Date billDate;private String state;public Bill() {}public Bill(Integer id, String billId, Integer menuId, Integer nums, Double money, Integer diningTableId, Date billDate, String state) {this.id = id;this.billId = billId;this.menuId = menuId;this.nums = nums;this.money = money;this.diningTableId = diningTableId;this.billDate = billDate;this.state = state;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getBillId() {return billId;}public void setBillId(String billId) {this.billId = billId;}public Integer getMenuId() {return menuId;}public void setMenuId(Integer menuId) {this.menuId = menuId;}public Integer getNums() {return nums;}public void setNums(Integer nums) {this.nums = nums;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}public Integer getDiningTableId() {return diningTableId;}public void setDiningTableId(Integer diningTableId) {this.diningTableId = diningTableId;}public Date getBillDate() {return billDate;}public void setBillDate(Date billDate) {this.billDate = billDate;}public String getState() {return state;}public void setState(String state) {this.state = state;}@Overridepublic String toString() {return  id +"\t\t" + menuId +"\t\t\t" + nums +"\t\t\t" + money +"\t" + diningTableId +"\t\t" + billDate +"\t\t" + state ;}
}

3.编写账单服务类 该方法还需要其他服务类辅助 因此也需要再其他服务类内增加方法

public class BillService {//定义BillDAO属性private BillDAO billDAO = new BillDAO();//需要定义另一个service获得菜单用来计算金额private MenuService menuService = new MenuService();//需要定义另一个service更改餐桌的状态private DiningTableService diningTableService = new DiningTableService();//编写点餐的方法//1.生成账单 2. 需要更新对应餐桌状态 3.如果成功返回true 否则返回falsepublic boolean orderMenu(int menuId,int nums,int diningTableId){//生成一个账单号UUIDString billUUID = UUID.randomUUID().toString();//将这个账单生成到bill表 要直接计算账单的金额 也就是获得menu对象int dml = billDAO.dml("insert into bill values" +"(null,?,?,?,?,?,now(),'未结账')", billUUID, menuId, nums, menuService.getMenuId(menuId).getPrice() * nums, diningTableId);if(dml <= 0){return false;}//需要更新餐桌状态return diningTableService.updateDiningTableState(diningTableId,"就餐中");}
}

4.在view调用该服务类

 //完成点餐public void orderMenu() {System.out.println("==============点餐服务============");System.out.print("请输入点餐的桌号(-1退出): ");int orderDiningTableId = Utility.readInt();if (orderDiningTableId == -1) {System.out.println("==============取消点餐============");return;}System.out.print("请输入点餐的菜品号(-1退出): ");int orderMenuId = Utility.readInt();if (orderMenuId == -1) {System.out.println("==============取消点餐============");return;}System.out.print("请输入点餐的菜品量(-1退出): ");int orderNums = Utility.readInt();if (orderNums == -1) {System.out.println("==============取消点餐============");return;}//验证餐桌号是否存在.DiningTable diningTable = diningTableService.getDiningTableById(orderDiningTableId);if (diningTable == null) {System.out.println("==============餐桌号不存在============");return;}//验证菜品编号Menu menu = menuService.getMenuId(orderMenuId);if (menu == null) {System.out.println("==============菜品号不存在============");return;}//点餐if (billService.orderMenu(orderMenuId, orderNums, orderDiningTableId)) {System.out.println("==============点餐成功============");} else {System.out.println("==============点餐失败============");}}

7.查看账单

1.billDao获得bill对象

2.service编写方法调用billDAO获得bill对象

3.view调用该service方法

2.service调用DAO获得list数组

public List<Bill> list(){return billDAO.queryMulti("select * from bill",Bill.class);}

3.view显示账单

public void listBill() {List<Bill> bills = billService.list();System.out.println("\n编号\t\t菜品号\t\t菜品量\t\t金额\t\t桌号\t\t日期\t\t\t\t\t\t\t状态");for (Bill bill : bills) {System.out.println(bill);}System.out.println("==============显示完毕============");}

 8.结账

(1)对餐桌号进行校验        (2)修改bill表的state        (3)修改diningTable信息        (4)不需要增加表和类

1.在 service类内查看是否有未结账 或者餐桌是否存在 (校验)

//查看某个产值是否有未结账的账单public boolean hasPayBillByDiningTableId(int diningTableId) {Bill bill =billDAO.querySingle("SELECT * FROM bill WHERE diningTableId=? AND state = '未结账' LIMIT 0, 1", Bill.class, diningTableId);return bill != null;}//完成结账[如果餐桌存在,并且该餐桌有未结账的账单]//如果成功,返回true, 失败返回 falsepublic boolean payBill(int diningTableId, String payMode) {//如果这里使用事务的话,需要用ThreadLocal来解决 , 框架中比如mybatis 提供了事务支持//1. 修改bill表int update = billDAO.dml("update bill set state=? where diningTableId=? and state='未结账'", payMode, diningTableId);if(update <= 0) { //如果更新没有成功,则表示失败...return false;}//2. 修改diningTable表//注意:不要直接在这里操作,而应该调用DiningTableService 方法,完成更新,体现各司其职if(!diningTableService.updateDiningTableToFree(diningTableId, "空")) {return false;}return true;}

2.修改diningTable为空闲

//需要提供一个更新餐桌状态为空闲的方法public boolean updateDiningTableToFree(int id,String state){int dml = diningTableDAO.dml("update diningTable set state=?,orderName = '',orderTel = '' where id=?", state, id);return dml > 0;}

 3.在view内定义方法调用service方法

//完成结账public void payBill() {System.out.println("==============结账服务============");System.out.print("请选择要结账的餐桌编号(-1退出): ");int diningTableId = Utility.readInt();if (diningTableId == -1) {System.out.println("=============取消结账============");return;}//验证餐桌是否存在DiningTable diningTable = diningTableService.getDiningTableById(diningTableId);if (diningTable == null) {System.out.println("=============结账的餐桌不存在============");return;}//验证餐桌是否有需要结账的账单if (!billService.hasPayBillByDiningTableId(diningTableId)) {System.out.println("=============该餐位没有未结账账单============");return;}System.out.print("结账方式(现金/支付宝/微信)回车表示退出: ");String payMode = Utility.readString(20, "");//说明如果回车,就是返回 ""if ("".equals(payMode)) {System.out.println("=============取消结账============");return;}char key = Utility.readConfirmSelection();if (key == 'Y') { //结账//调用我们写的方法if (billService.payBill(diningTableId, payMode)) {System.out.println("=============完成结账============");} else {System.out.println("=============结账失败============");}} else {System.out.println("=============取消结账============");}}

四、进行代码拓展 

1.多表查询的需求

我们可以再增加一个MultableBean,跟多张表进行映射,所以要有一个MultableBeanDAO,然后调用该DAO

另一个方案

DBUtils数据库连接池多表连接查询_利用数据池连接数据库多个表-CSDN博客

1.创建bean表

public class MultiTableBean {private Integer id;private String billId;private Integer menuId;private Integer nums;private Double money;private Integer diningTableId;private Date billDate;private String state;//增加一个来自menu表的列 name//思考 这里的属性名是否一定要和表的列名保持一致.//答: 可以不一致,但是需要sql做相应的修改, 规范需要保持一致.private String name;//增加来自menu表的列 priceprivate Double price;//默认值 nulllpublic MultiTableBean() {System.out.println("反射调用....");}//    public MultiTableBean(Integer id, String billId, Integer menuId, Integer nums, Double money, Integer diningTableId, Date billDate, String state, String name, Double price) {
//        this.id = id;
//        this.billId = billId;
//        this.menuId = menuId;
//        this.nums = nums;
//        this.money = money;
//        this.diningTableId = diningTableId;
//        this.billDate = billDate;
//        this.state = state;
//        this.name = name;
//        this.price = price;
//    }//给price生成setter 和 getterpublic Double getPrice() {return price;}public void setPrice(Double price) {this.price = price;}//给name生成setter 和 getterpublic String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getBillId() {return billId;}public void setBillId(String billId) {this.billId = billId;}public Integer getMenuId() {return menuId;}public void setMenuId(Integer menuId) {this.menuId = menuId;}public Integer getNums() {return nums;}public void setNums(Integer nums) {this.nums = nums;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}public Integer getDiningTableId() {return diningTableId;}public void setDiningTableId(Integer diningTableId) {this.diningTableId = diningTableId;}public Date getBillDate() {return billDate;}public void setBillDate(Date billDate) {this.billDate = billDate;}public String getState() {return state;}public void setState(String state) {this.state = state;}@Overridepublic String toString() {return  id +"\t\t" + menuId +"\t\t\t" + nums +"\t\t\t" + money +"\t" + diningTableId +"\t\t" + billDate +"\t\t" + state +"\t\t" + name +"\t\t" + price;}
}

2.创建dao类

3. view中调用

 public void listBill() {/*//单表查询List<Bill> bills = billService.list();System.out.println("\n编号\t\t菜品号\t\t菜品量\t\t金额\t\t桌号\t\t日期\t\t\t\t\t\t\t状态");for (Bill bill : bills) {System.out.println(bill);}System.out.println("==============显示完毕============");*///多表查询List<MultiTableBean> multiTableBeans = billService.list2();System.out.println("\n编号\t\t菜品号\t\t菜品量\t\t金额\t\t桌号\t\t日期\t\t\t\t\t\t\t状态\t\t菜品名\t\t价格");for (MultiTableBean bill : multiTableBeans) {System.out.println(bill);}System.out.println("==============显示完毕============");}

 根据需要增加需要的字段

当将来的多表查询次数越来越多可以考虑拆分

2.javaBean和表的参数名一致性的问题

//增加一个来自menu表的列 name

//思考 这里的属性名是否一定要和表的列名保持一致.

//答: 可以不一致,但是需要sql做相应的修改(例如 name as name2), 规范需要保持一致.

3.对于员工多字段的设置

4.完成更多功能 

可以完成登录管理和人事管理

 

相关文章:

【Java学习笔记】72 - 满汉楼 - 餐饮管理系统

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter26 一、需求说明 满汉楼项目功能多&#xff0c;界面复杂&#xff0c;涉及到复杂的awt和swing技术和事件编程&#xff0c;做如下调整: 1.去掉界面和事件处理(工作中使用很少)&#xff0c;使…...

【我的创作纪念日】

机缘 大家好&#xff0c;我是圥忈ゼ&#xff0c; 2023 年 07 月 20 日&#xff0c;我撰写了第 1 篇技术博客&#xff1a;《我的编程未来规划》&#xff0c;也是由于我高考后的专业选择&#xff0c;和就业方向的选择&#xff0c;加上想立志成为一名专业 IT 作者&#xff0c;我结…...

车载通信架构 —— 传统车内通信网络MOST总线(光纤传输、专精多媒体)

车载通信架构 —— 传统车内通信网络MOST总线(光纤传输、专精多媒体) 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都…...

使用Pytorch从零开始构建Energy-based Model

知识回顾: [1] 生成式建模概述 [2] Transformer I&#xff0c;Transformer II [3] 变分自编码器 [4] 生成对抗网络&#xff0c;高级生成对抗网络 I&#xff0c;高级生成对抗网络 II [5] 自回归模型 [6] 归一化流模型 [7] 基于能量的模型 [8] 扩散模型 I, 扩散模型 II 在本教程中…...

基于C#实现梳排序

为什么取名为梳&#xff0c;可能每个梳都有自己的 gap 吧&#xff0c;大梳子 gap 大一点&#xff0c;小梳子 gap 小一点。上一篇我们看到鸡尾酒排序是在冒泡排序上做了一些优化&#xff0c;将单向的比较变成了双向&#xff0c;同样这里的梳排序也是在冒泡排序上做了一些优化。 …...

盘点72个Android系统源码安卓爱好者不容错过

盘点72个Android系统源码安卓爱好者不容错过 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1qiWeLjF2i4dlgmTYgPPSvw?pwd8888 提取码&#xff1a;8888 项目名称 A keyboardlisten…...

nodejs+vue+elementui足球篮球联赛系统

系统主要是以后台管理员管理为主。管理员需要先登录系统然后才可以使用本系统&#xff0c;管理员可以对个人中心、用户管理、赛事信息管理、球队信息管理、球员信息管理、比赛分值板管理、系统管理等进行添加、查询、修改、删除&#xff0c;以保障足球联赛管理系统的正常运行。…...

18.Oracle的过程和函数

oracle11g的过程和函数 一、过程&#xff08;Procedure&#xff09;1、子程序2、过程的相关语法 二、函数&#xff08;Function&#xff09;1、函数的概念2、函数的创建3、 案例 在Oracle数据库中&#xff0c;过程和函数都是用来封装一系列SQL语句和逻辑操作的数据库对象&#…...

A JSONObject text must begin with ‘{‘ at 1 [character 2 line 1]

今天调用一个接口&#xff0c;返回的是json数据&#xff0c;但是拿到数据进行转换的报错&#xff0c; JSONObject resultJson new JSONObject(resuStr);报错信息是&#xff1a; Exception in thread "main" org.json.JSONException: A JSONObject text must begin …...

C#中openFileDialog控件的使用方法

目录 一、OpenFileDialog基本属性 二、使用 OpenFile 从筛选的选择中打开文件 1.示例源码 2.生成效果 3. 其它示例 三、使用 StreamReader 以流的形式读取文件 1.示例源码 2.生成效果 四、一种新颖的Windows窗体应用文件设计方法 在C#中&#xff0c;OpenFileDialog控件…...

多线程04 死锁,线程可见性

前言 前面我们讲到了简单的线程安全问题以及简单的解决策略 其根本原因是cpu底层对线程的抢占式调度策略,随机调度 其他还有一些场景的问题如下 1.多个线程同时修改一个变量问题 2.执行的操作指令本身不是原子的 比如自增操作就分为三步,加载,自增,保存 3.内存可见性问题 4.指令…...

java中文转拼音(去除音调)

一、jar包 <dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version></dependency> 二、代码 /*** 中文转换拼音*/ public class PinyinConvert {/**** param str 钱多多* r…...

[Android]常见的数据传递方式

Demo:https://github.com/Gamin-fzym/DataTransferDemo 1.Intent 发送页面 A 到页面 B 的 Intent 时&#xff0c;可以通过 Intent 的 putExtra() 方法将数据附加到 Intent 上。 在页面 B 中&#xff0c;通过 Intent 的 getXXXExtra() 方法获取传递的数据。 1).在A页面发送 …...

<蓝桥杯软件赛>零基础备赛20周--第7周--栈和二叉树

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…...

探究Kafka原理-7.exactly once semantics 和 性能测试

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…...

【密码学引论】序列密码

第五章 序列密码 1、序列密码 定义&#xff1a; 加密过程&#xff1a;把明文与密钥序列进行异或运算得到密文解密过程&#xff1a;把密文与密钥序列进行异或运算得到明文以字/字节为单位加解密密钥&#xff1a;采用一个比特流发生器随机产生二进制比特流 2、序列密码和分组密…...

知识变现的未来:解析知识付费系统的核心

随着数字时代的发展&#xff0c;知识付费系统作为一种新兴的学习和知识分享模式&#xff0c;正逐渐引领着知识变现的未来。本文将深入解析知识付费系统的核心技术&#xff0c;揭示其在知识经济时代的重要性和潜力。 1. 知识付费系统的基本架构 知识付费系统的核心在于其灵活…...

【Linux基础】Linux常见指令总结及周边小知识

前言 Linux系统编程的学习我们将要开始了&#xff0c;学习它我们不得不谈谈它的版本发布是怎样的&#xff0c;谈它的版本发布就不得不说说unix。下面是unix发展史是我在百度百科了解的 Unix发展史 UNIX系统是一个分时系统。最早的UNIX系统于1970年问世。此前&#xff0c;只有…...

【Android知识笔记】性能优化专题(五)

App瘦身优化 随着业务迭代,apk体积逐渐变大。项目中积累的无用资源,未压缩的图片资源等,都为apk带来了不必要的体积增加。而APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。 瘦身优势: 最主要是转换率:下载转换率头部 App 都有 Lite 版渠道合作商要求了解 …...

Java基础之泛型

Java基础之泛型 一、泛型应用范围二、使用泛型方法三、泛型类 一、泛型应用范围 泛型提供了编译时类型安全检测机制&#xff0c;该机制允许程序员在编译时检测到非法的类型。 使用 Java 泛型的概念&#xff0c;我们可以写一个泛型方法来对一个对象数组排序。然后&#xff0c;调…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...