来源: 使用uniapp创建项目,并使用uni-ui,引入uView及遇到的一些问题_全局使用uni-ui-CSDN博客
百万商品查询,性能提升了10倍 - 苏三说技术 - 博客园
来源: 百万商品查询,性能提升了10倍 – 苏三说技术 – 博客园
前言
最近在我的知识星球中,有个小伙伴问了这样一个问题:百万商品分页查询接口,如何保证接口的性能?
这就需要对该分页查询接口做优化了。
这篇文章从9个方面跟大家一起聊聊分页查询接口优化的一些小技巧,希望对你会有所帮助。
1 增加默认条件
对于分页查询接口,如果没有特殊要求,我们可以在输入参数中,给一些默认值。
这样可以缩小数据范围,避免每次都count所有数据的情况。
对于商品查询,这种业务场景,我们可以默认查询当天上架状态的商品列表。
例如:
select * from product
where edit_date>='2023-02-20' and edit_date<'2023-02-21' and status=1
如果每天有变更的商品数量不多,通过这两个默认条件,就能过滤掉绝大部分数据,让分页查询接口的性能提升不少。
温馨提醒一下:记得给
时间
和状态
字段增加一个联合索引
。
2 减少每页大小
分页查询接口通常情况下,需要接收两个参数:pageNo
(即:页码)和pageSize
(即:每页大小)。
如果分页查询接口的调用端,没有传pageNo默认值是1,如果没有传pageSize也可以给一个默认值10或者20。
不太建议pageSize传入过大的值,会直接影响接口性能。
在前端有个下拉控件,可以选择每页的大小,选择范围是:10、20、50、100。
前端默认选择的每页大小为10
。
不过在实际业务场景中,要根据产品需求而且,这里只是一个参考值。
3 减少join表的数量
有时候,我们的分页查询接口的查询结果,需要join多张表才能查出数据。
比如在查询商品信息时,需要根据商品名称、单位、品牌、分类等信息查询数据。
这时候写一条SQL可以查出想要的数据,比如下面这样的:
select
p.id,
p.product_name,
u.unit_name,
b.brand_name,
c.category_name
from product p
inner join unit u on p.unit_id = u.id
inner join brand b on p.brand_id = b.id
inner join category c on p.category_id = c.id
where p.name='测试商品'
limit 0,20;
使用product表去join
了unit、brand和category这三张表。
其实product表中有unit_id、brand_id和category_id三个字段。
我们可以先查出这三个字段,获取分页的数据缩小范围,之后再通过主键id集合去查询额外的数据。
我们可以把SQL改成这样:
select
p.id,
p.product_id,
u.unit_id,
b.brand_id,
c.category_id
from product
where name='测试商品'
limit 0,20;
这个例子中,分页查询之后,我们获取到的商品列表其实只要20条数据。
再根据20条数据中的id集合,获取其他的名称,例如:
select id,name
from unit
where id in (1,2,3);
然后在程序中填充其他名称。
伪代码如下:
List<Product> productList = productMapper.search(searchEntity);
List<Long> unitIdList = productList.stream().map(Product::getUnitId).distinct().collect(Collectors.toList());
List<Unit> unitList = UnitMapper.queryUnitByIdList(unitIdList);
for(Product product: productList) {
Optional<Unit> optional = unitList.stream().filter(x->x.getId().equals(product.getId())).findAny();
if(optional.isPersent()) {
product.setUnitName(optional.get().getName());
}
}
这样就能有效的减少join表的数量,可以一定的程度上优化查询接口的性能。
4 优化索引
分页查询接口性能出现了问题,最直接最快速的优化办法是:优化索引
。
因为优化索引不需要修改代码,只需回归测试一下就行,改动成本是最小的。
我们需要使用explain
关键字,查询一下生产环境分页查询接口的执行计划
。
看看有没有创建索引,创建的索引是否合理,或者索引失效了没。
索引不是创建越多越好,也不是创建越少越好,我们需要根据实际情况,到生产环境测试一下sql的耗时情况,然后决定如何创建或优化索引。
建议优先创建联合索引
。
如果你对explain关键字的用法比较感兴趣,可以看看我的这篇文章《explain | 索引优化的这把绝世好剑,你真的会用吗?》。
如果你对索引失效的问题比较感兴趣,可以看看我的这篇文章《聊聊索引失效的10种场景,太坑了》。
5 用straight_join
有时候我们的业务场景很复杂,有很多查询sql,需要创建多个索引。
在分页查询接口中根据不同的输入参数,最终的查询sql语句,MySQL根据一定的抽样算法,却选择了不同的索引。
不知道你有没有遇到过,某个查询接口,原本性能是没问题的,但一旦输入某些参数,接口响应时间就非常长。
这时候如果你此时用explain
关键字,查看该查询sql执行计划,会发现现在走的索引,跟之前不一样,并且驱动表也不一样。
之前一直都是用表a驱动表b,走的索引c。
此时用的表b驱动表a,走的索引d。
为了解决Mysql选错索引的问题,最常见的手段是使用force_index
关键字,在代码中指定走的索引名称。
但如果在代码中硬编码了,后面一旦索引名称修改了,或者索引被删除了,程序可能会直接报错。
这时该怎么办呢?
答:我们可以使用straight_join
代替inner join
。
straight_join会告诉Mysql用左边的表驱动右边的表,能改表优化器对于联表查询的执行顺序。
之前的查询sql如下:
select p.id from product p
inner join warehouse w on p.id=w.product_id;
...
我们用它将之前的查询sql进行优化:
select p.id from product p
straight_join warehouse w on p.id=w.product_id;
...
6 数据归档
随着时间的推移,我们的系统用户越来越多,产生的数据也越来越多。
单表已经到达了几千万。
这时候分页查询接口性能急剧下降,我们不能不做分表处理了。
做简单的分表策略是将历史数据归档,比如:在主表
中只保留最近三个月的数据,三个月前的数据,保证到历史表
中。
我们的分页查询接口,默认从主表中查询数据,可以将数据范围缩小很多。
如果有特殊的需求,再从历史表中查询数据,最近三个月的数据,是用户关注度最高的数据。
7 使用count(*)
在分页查询接口中,需要在sql中使用count
关键字查询总记录数
。
目前count有下面几种用法:
-
count(1) -
count(id) -
count(普通索引列) -
count(未加索引列)
那么它们有什么区别呢?
-
count(*) :它会获取所有行的数据,不做任何处理,行数加1。 -
count(1):它会获取所有行的数据,每行固定值1,也是行数加1。 -
count(id):id代表主键,它需要从所有行的数据中解析出id字段,其中id肯定都不为NULL,行数加1。 -
count(普通索引列):它需要从所有行的数据中解析出普通索引列,然后判断是否为NULL,如果不是NULL,则行数+1。 -
count(未加索引列):它会全表扫描获取所有数据,解析中未加索引列,然后判断是否为NULL,如果不是NULL,则行数+1。
由此,最后count的性能从高到低是:
count(*) ≈ count(1) > count(id) > count(普通索引列) > count(未加索引列)
所以,其实count(*)
是最快的。
我们在使用count统计总记录数时,一定要记得使用count(*)。
8 从ClickHouse查询
有些时候,join的表实在太多,没法去掉多余的join,该怎么办呢?
答:可以将数据保存到ClickHouse
。
ClickHouse是基于列存储
的数据库,不支持事务,查询性能非常高,号称查询十几亿的数据,能够秒级返回。
为了避免对业务代码的嵌入性,可以使用Canal
监听Mysql
的binlog
日志。当product表有数据新增时,需要同时查询出单位、品牌和分类的数据,生成一个新的结果集,保存到ClickHouse当中。
查询数据时,从ClickHouse当中查询,这样使用count(*)的查询效率能够提升N倍。
需要特别提醒一下:使用ClickHouse时,新增数据不要太频繁,尽量批量插入数据。
其实如果查询条件非常多,使用ClickHouse也不是特别合适,这时候可以改成ElasticSearch
,不过它跟Mysql一样,存在深分页
问题。
9 数据库读写分离
有时候,分页查询接口性能差,是因为用户并发量上来了。
在系统的初期,还没有多少用户量,读数据请求和写数据请求,都是访问的同一个数据库,该方式实现起来简单、成本低。
刚开始分页查询接口性能没啥问题。
但随着用户量的增长,用户的读数据请求和写数据请求都明显增多。
我们都知道数据库连接有限,一般是配置的空闲连接数是100-1000之间。如果多余1000的请求,就只能等待,就可能会出现接口超时的情况。
因此,我们有必要做数据库的读写分离
。写数据请求访问主库
,读数据请求访问从库
,从库的数据通过binlog从主库同步过来。
根据不同的用户量,可以做一主一从,一主两从,或一主多从。
数据库读写分离之后,能够提升查询接口的性能。
如果你对性能优化比较感兴趣,可以看看《性能优化35讲》,里面有更多干货内容。
最后说一句(求关注,别白嫖我)
如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描下发二维码关注一下,您的支持是我坚持写作最大的动力。
求一键三连:点赞、转发、在看。
关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。
怎么在横向li很多的情况下自动适应ul宽度换行_前端-CSDN问答
来源: 怎么在横向li很多的情况下自动适应ul宽度换行_前端-CSDN问答
以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:
要实现<ul>
标签中的<li>
元素在达到<ul>
的宽度限制时自动换行,你可以使用CSS的display: flex
属性和flex-wrap: wrap
属性。以下是具体的CSS代码实现:
-
ul {
-
display: flex; /* 设置ul为flex容器 */
-
flex-wrap: wrap; /* 允许子元素换行 */
-
width: 100%; /* 或者设置一个固定的宽度,根据需要调整 */
-
list-style: none; /* 可选,去掉列表项的默认样式 */
-
padding: 0; /* 可选,去掉内边距 */
-
margin: 0; /* 可选,去掉外边距 */
-
}
-
-
li {
-
flex: 0 1 auto; /* 允许li元素自动调整大小 */
-
margin: 5px; /* 可选,设置li元素之间的间隔 */
-
}
这段代码会使得<ul>
内的<li>
元素在达到<ul>
的宽度限制时自动换行。flex: 0 1 auto;
表示<li>
元素不会强制占据固定空间,而是根据内容自动调整大小,并在需要时换行。
参考资料:
- CSS Flexible Box Layout Module Level 1 – W3C
- Flexbox Froggy – A game for learning CSS flexbox
- CSS-Tricks – A Complete Guide to Flexbox
这些参考资料将帮助你更深入地了解Flexbox的工作原理和使用方法。
高版本数据库附加到低版本解决办法 - 党鹏飞 - 博客园
来源: 高版本数据库附加到低版本解决办法 – 党鹏飞 – 博客园
在我们使用别人导出的数据库的时候,有时候我们会通过附加数据库的方法,把别人导出的数据库附加到我们的电脑中,这时,或许你会遇到这种问题,附加时,提示版本为XXX,无法打开,支持AAA版本。
这是怎么回事呢?
原来,版本号是指SQL Server的版本号,例如版本号661是SQL Server 2008 R2,版本号655是SQL Server 2008 等。它拥有向上兼容的特点。由此可见,标题的意思就是说,你要附加的数据库,只能在SQL Server 2008 R2及更高版本上运行,不能在SQL Server 2008 上运行,那么,我们该怎么处理这个问题呢?
处理这种问题,有很多种方法,下面我就说一个我查到并使用的方法,仅供参考,如果有更好的方法,欢迎沟通。
1.把这个数据库附加到装有SQL Server 2008 R2的数据上。
2.打开Management Studio,登录到服务器,在数据库中选择要转移的数据库,右键--“任务(T)”--“生成脚本(E)…”。
3.在“生成和发布脚本”窗口中,点击“下一步”
4.“选择要编写脚本的数据库对象”,可以不做设置,点击“下一步”
5.点击[保存到文件]右边的“高级”按钮,在对话框中,设置“为服务器版本编写脚本”为“SQL Server 2008”,设置“要编写脚本的数据的类型”为“架构和数据”。选择保存脚本的位置
6.下一步,再下一步。导出完成
把导出完成的程序,在放到SQL Server 2008 中,按下面步骤:
1.打开Management Studio,登录到服务器
2.选择菜单“文件”——“打开”——“文件”,选择.sql脚本文件,点击工具栏中的“执行”按钮
3.在左侧的“对象资源管理器”中右键“数据库”——“刷新”
到此为止,“版本号661,无法打开,支持655版本及其以下版本……”这个错误就算是解决了。当然,如果你直接把数据库卸载,在装SQL Server 2008R2 , 也是可以完美解决这个问题的。
版本655指的是SQL2008, 版本611指的是SQL2005, (还有一个版本539指的是SQL2000)
楼主的情况属于典型的从高版本降低至低版本使用的情景.
按微软的官方说法, 是不支持从高版本附加到低版本的.
如果一定要这么做, 那怎么办呢? 有办法.
首先, 找一台装有SQL Server 2008的电脑, 将你的数据库文件附加到这台电脑里.
附加成功后, 在SSMS的对象资源管理器窗口右键单击刚刚附加的数据库,依次选”任务>生成脚本…”, 此时会弹出脚本向导对话框.
点”下一步”.
在”选择数据库”对话框选中刚刚附加的数据库, 同时将底部的”为所选数据库中的所有对象编写脚本”打勾. 点下一步.
在”选择脚本选项”对话框中,还需要修改以下几个选项:
1).”编写数据的脚本”,设为”True”; (SQL2005没有这个选项,所以才要找一台装有SQL2008的电脑嘛,多省事啊,省去了数据导入导出的麻烦)
2).”编写触发器脚本”,设为”True”;
3).”编写创建数据库的脚本”,设为”True”;
4).”为服务器版本编写脚本”,选”SQL Server 2005″;(如果是要用的SQL2000中,那就选SQL Server 2000)
以上4个选项是非常建议这样设置的,其他的选项就自己看着办,其他的一般也不用改. 点下一步.
在”输出选项”对话框中,选”将脚本保存到文件”,其他默认,点下一步.
点完成.
点关闭.
layui table更新一行数据_layui更新table行信息-CSDN博客
来源: layui table更新一行数据_layui更新table行信息-CSDN博客
需求
点击一行数据后面的处理,只刷新这行数据的内容,不全部刷新页面
update
layui 给我们提供了update方法,可以用来修改当前行数据
//工具条事件
table.on(‘tool(test)’, function(obj){ //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter=”对应的值”
var data = obj.data; //获得当前行数据
var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
var tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)
if(layEvent === ‘detail’){ //查看
//do somehing
} else if(layEvent === ‘del’){ //删除
layer.confirm(‘真的删除行么’, function(index){
obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
layer.close(index);
//向服务端发送删除指令
});
} else if(layEvent === ‘edit’){ //编辑
//同步更新缓存对应的值 — 看这里
obj.update({
username: ‘123’
,title: ‘xxx’
});
}
});
实际应用
但是这样只能更新行数据,是没有办法更新toobar的
table.on(‘tool(test)’, function(obj){
var data = obj.data; //获得当前行数据
var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
if(layEvent === ‘updateStatus’){ //修改状态
//ajax请求 — 略 status -> 1
//更新当前行数据的状态值 status 是属性值
obj.update({
status: 1
});
}
});
源码里面的定义
这个代码是从:https://blog.csdn.net/MicroAnswer/article/details/102871487,
我本地的table.js 没有格式化 所以就灭有翻译,直接引用了一下
// 这里就是我们实际调用更新的代码位置。
,update: function(fields){ //修改行数据
fields = fields || {};
// 遍历传进来的每一个键值对(实际上就是我们的每一条数据)。
layui.each(fields, function(key, value){
// data 是通过服务器返回的实际的每一行数据
if(key in data){
// 这边定义一个templet用于确定下方是使用模板来更新数据还是
// 直接使用字段的值来进行填充。
var templet,
td = tr.children(‘td[data-field=”‘+ key +'”]’);
data[key] = value;
// 这个 eachCols 就是一个循环,i 是下标, item2 就是我们render函数
// 传递进来的每一个col的配置项。
that.eachCols(function(i, item2){
// 判断指定字段是否使用模板进行数据展示。
// 是的话就直接赋值模板。
if(item2.field == key && item2.templet){
templet = item2.templet;
}
});
// 然后这里就进行数据的模板渲染,然后更新到表格界面
td.children(ELEM_CELL).html(parseTempData({
templet: templet
}, value, data));
td.data(‘content’, value);
}
});
}
分析:其实可以看到update方法就是:
1.传入过去的fileds数组进行遍历
2.把需要更新的filed的值进行更新
3.如果filed是有模板:templet 进行渲染的话就进重新进行模板渲染
所以要实现toolbar一起更新,我们就把toolbar
1. 添加一个filed
2. 调用update 重新渲染templet 就可以了
toolbar一起更新
之前定义的toolbar
修改后的toolbar
1.把toolbar – 修改为 : templet
2.添加filed 字段: remark1这个字段是后台返回的一个字段,我的代码里面这个字段没有用到,大家可以重新定义一个
这里其实主要就是为了让 当执行update字段的时候让它重新渲染
在我们的update里面把这个字段也更新一下
table.on(‘tool(test)’, function(obj){
var data = obj.data; //获得当前行数据
var layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
if(layEvent === ‘updateStatus’){ //修改状态
//ajax请求 — 略 status -> 1
//更新当前行数据的状态值 status 是属性值
obj.update({
status: 1 ,
remark1:” //这里的字段值随便是什么都可以,主要是为了重新让它渲染
});
}
});
这样就可以实现只刷薪当前行数据和toolbarl
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/sunshinezx8023/article/details/119343923
layui updateRow 更新某个表格 某行数据 - CSDN文库
来源: layui updateRow 更新某个表格 某行数据 – CSDN文库
在使用 layui 的表格组件时,您可以使用 “updateRow” 方法来更新表格中的某行数据。具体的使用方法如下:
- 获取表格对象:
var table = layui.table;
- 找到需要更新的行数据,并将其存储在一个对象中,例如:
var rowData = {
id: '123', // 某行数据的唯一标识
name: '张三',
age: 25,
address: '北京市海淀区'
};
- 调用 “updateRow” 方法更新数据:
table.updateRow('tableId', rowData);
其中,”tableId” 是您表格的 ID,”rowData” 是上一步中获取到的需要更新的行数据对象。这将会更新表格中 ID 为 “123” 的行数据为 “张三”、25 岁、地址为 “北京市海淀区”。
需要注意的是,”updateRow” 方法只是更新了表格中的数据,并没有直接修改数据库或其他数据源中的数据。如果您需要更新数据库中的数据,还需要额外进行相应的操作。
updateRow 更新某个表格 某行数据
是的,您可以使用 “updateRow” 命令来更新数据库或电子表格应用程序中的某行数据。具体的语法和使用方法会根据不同的应用程序而有所不同。在一些常见的关系型数据库系统中,例如MySQL,可以使用以下语法来更新表格中的某行数据:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE some_column = some_value;
这将更新 “table_name” 表中 “some_column” 列为 “some_value” 的行的 “column1” 和 “column2” 列的值。您可以根据实际情况修改列名、值和条件来更新您需要的行数据。
table.updateRow 更新某个表格某行某个字段
table.updateRow
方法可以更新整行数据,如果只需要更新某个表格某行的某个字段,可以通过以下步骤实现:
- 获取要更新的行的索引或 ID。
- 获取要更新的字段名。
- 更新该行数据的相应字段。
- 使用
updateCell
方法更新表格中该行该字段的值。
以下是一个示例代码,仅供参考:
// 获取表格对象
var table = layui.table;
// 定义表格数据
var data = [
{id: 1, name: '张三', age: 20},
{id: 2, name: '李四', age: 22},
{id: 3, name: '王五', age: 24}
];
// 渲染表格
table.render({
elem: '#demo',
data: data,
cols: [[
{field: 'id', title: 'ID'},
{field: 'name', title: '姓名'},
{field: 'age', title: '年龄'}
]]
});
// 更新表格数据
var rowIndex = 1; // 要更新的行的索引
var field = 'age'; // 要更新的字段名
var newValue = 23; // 新值
var rowData = table.cache.demo[rowIndex]; // 获取要更新的行数据
rowData[field] = newValue; // 更新该行数据的相应字段
table.updateRow('demo', rowIndex, rowData); // 更新表格中该行数据
// 使用 updateCell 方法更新表格中该行该字段的值
var cellIndex = table.config.cols[0].findIndex(function(item){
return item.field === field;
});
table.updateCell({rowIndex: rowIndex, colIndex: cellIndex, value: newValue});
在上面的示例代码中,我们首先定义了一个表格数据,然后使用 table.render
方法渲染表格。然后,我们通过 rowIndex
获取要更新的行数据,并更新该行数据的相应字段。接着,使用 table.updateRow
方法更新表格中该行数据。最后,通过 updateCell
方法更新表格中该行该字段的值,其中 colIndex
为要更新的列的索引,value
为新值。
6款支持C#语言的AI辅助编程工具,开发效率提升利器! - 追逐时光者 - 博客园
来源: 6款支持C#语言的AI辅助编程工具,开发效率提升利器! – 追逐时光者 – 博客园
前言
在这个AI迅速发展的阶段,涌现出了一大批好用的AI辅助编程工具。AI辅助编程工具能够提高开发效率、改善代码质量、降低bug率,是现代软件开发过程中的重要助手。今天大姚给大家分享6款AI辅助编程工具(并且都支持C#语言),希望对大家有所帮助。
AI辅助编程工具
以下6个AI辅助编程工具都已收录到DotNetGuide中,假如你有更好的推荐欢迎文末留言或者RP投稿。
通义灵码(免费)
通义灵码,基于通义大模型的 AI 研发辅助工具,提供代码智能生成、研发智能问答、任务自主执行等能力,为开发者带来智能化研发体验,引领 AI 原生研发新范式。
支持语言
支持 Java、Python、Go、C/C++、C#、JavaScript、TypeScript、PHP、Ruby、Rust、Scala 等 200 多种语言。
支持工具
兼容 Visual Studio Code、Visual Studio、JetBrains IDEs 等主流编程工具。
CodeGeeX(免费)
CodeGeeX是一款基于大模型的智能编程助手,它可以实现代码的生成与补全、自动为代码添加注释、自动解释代码、自动编写单元测试、实现代码审查Code Review、自动修复代码fixbug、自动生成commit message完成git提交,以及在不同编程语言的代码间实现互译、针对技术和代码问题的智能问答等丰富的功能。
支持语言
支持Python、Java、C#、C++/C、JavaScript、Go等多种语言。
支持工具
Visual Studio Code、JetBrains IDEs、Visual Studio、HBuilderX、DeepIn-IDE等。
Fitten Code(免费)
Fitten Code是由非十大模型驱动的AI编程助手,它可以自动生成代码,提升开发效率,帮您调试Bug,节省您的时间。还可以对话聊天,解决您编程碰到的问题。
支持语言
支持javascript, markdown, java, json, php, python, c#, typescript, html, c, cpp, yaml, zig, go, ruby, css, kotlin, shell等80多种语言。
支持工具
Visual Studio、Visual Studio Code、JetBrains IDEs、Vim。
GitHub Copilot(付费)
GitHub Copilot 是一款 AI 编码助手,可帮助你更快、更省力地编写代码,从而将更多精力集中在问题解决和协作上。GitHub Copilot 会在你编码时提供建议:有时是当前行的补全,有时是全新的代码块。可以接受全部或部分建议,也可以忽略建议并继续键入。
支持语言
支持Python、JavaScript、TypeScript、Ruby、Go、C# 和 C++等多种语言。
支持工具
Visual Studio、Visual Studio Code、Azure Data Studio、JetBrains IDEs、Vim/Neovim。
Baidu Comate(免费)
Baidu Comate 由文心大模型 ERNIE-Code 提供技术支持,通过对百度多年积累的非涉密代码数据和 GitHub 头部公开代码数据进行训练,为您自动生成完整的、且更符合实际研发场景的代码行或整个代码块,帮助每一位开发者轻松完成研发任务。基于AI的智能代码生成让你的编码更快、更好、更简单!
支持语言
Baidu Comate 支持C#、C/C++、Java、Python、Go、JavaScript、TypeScript、Rust、PHP、Kotlin、ObjectC等100+主流编程语言。
支持工具
支持在JetBrains、Visual Studio Code、Visual Studio、Xcode、Eclipse等主流IDE。
CodeWhisperer(免费)
CodeWhisperer是亚⻢逊出品的一款基于机器学习的通用代码生成器,可实时提供代码建议。在编写代码时,它会自动根据我们现有的代码和注释生成建议。从单行代码建议到完整的函数,它可为我们提供各种大小和范围的个性化建议。
支持语言
支持Python、Java、C#、JavaScript、Typescript等15种编程语言。
支持工具
VS Code、IntelliJ IDEA、Visual Studio(预览版)、AWS Cloud9、AWS Lambda 控制台、JupyterLab 和 Amazon SageMaker Studio。
开源的AI和LLM相关项目框架
DotNetGuide技术社区交流群
- DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
- 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
- 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。
无网络状态下利用libcimbar传输文件-CSDN博客
来源: 无网络状态下利用libcimbar传输文件-CSDN博客
前言
无网络环境下传输文件又有了一个新的选择:使用二维码。无需互联网、蓝牙、WIFI、NFC等,所有数据都可通过相机镜头传输。
项目地址
https://github.com/sz3/libcimbar
https://github.com/sz3/libcimbar
实现方式
简单来说就是将文件转化为图标矩阵码,用其他设备扫码进行传输。
libcimbar: 颜色图标矩阵条形码
Behold: 一种用于气隙数据传输的实验性条形码格式。
它只需使用计算机显示器和智能手机摄像头即可维持 106 KB/s的速度传输!
操作步骤
编码器将动画条形码输出到计算机或智能手机屏幕上:
打开 https://cimbar.org/选择需要传输的文件 (网页端就是一个html文件,无网络环境下浏览器打开也能正常使用)
解码器是一个使用手机摄像头读取动画条形码的手机应用程序:手机打开APP,对准屏幕,传输开始会出现进度条
原理
cimbar 是一种高密度 2D 条形码格式。数据存储在彩色图块网格中 — 根据选择的图块以及选择的颜色来绘制图块,对位进行编码。对数据应用 Reed Solomon 纠错,以解释视频 -> 数字解码的有损性质。预计错误率低于 1%,并得到纠正。
网格上每个图块(位置)有 16 个可能的符号,每个图块编码 4 位。此外,网格上的每个位置可以编码 2-3 个颜色位,这意味着每个图块最多总共 7 个位。
libcimbar 为优化实现,包括一个基于 fountain 代码 (wirehair) 和 zstd 压缩构建的文件编码的简单协议。最大 33MB 的文件(压缩后)被编码为一系列 cimbar 代码,这些代码可以输出为图像或实时视频源。一旦成功解码了足够多的不同图像帧,文件将成功重建和解压缩。即使图像的接收顺序不正确,或者某些图像已损坏或丢失,也是如此。
备注
1. 网页端html文件下载:https://github.com/sz3/libcimbar/releases
2. Android APP下载:https://github.com/sz3/cfc/releases
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_35159705/article/details/142066070
SaaS架构:流程架构分析 - 架构师汤师爷 - 博客园
来源: SaaS架构:流程架构分析 – 架构师汤师爷 – 博客园
大家好,我是汤师爷~
今天聊聊SaaS架构中的流程架构分析。
业务流程的概念
业务流程是企业为实现目标而制定的一套系统化的工作方法。它由一系列有序的业务活动组成,按照既定规则将资源(输入)转化为有价值的结果(输出)。这一过程需结合企业的具体情况和可用资源,旨在为客户创造价值,同时达成企业目标。
通过梳理和设计业务流程,我们可以明确责任分配和绩效要求。这不仅指导和推动流程的建设、优化和整合,还能打破部门间的壁垒,有效管理企业的变革和运营,从而显著提升整体运营效率。
在业务架构设计阶段,业务流程发挥着关键作用。它不仅影响企业资源的有效利用,还直接决定了应用架构中的应用服务的设计。
业务流程有2个核心视角:
- 端到端流程:强调跨部门的协作与整体效率,贯穿整个业务链条,从客户需求的起点到最终满足的终点。
- 职能流程:聚焦于各个部门内部的专业化分工,确保每个职能领域的高效运作。
这两种流程相辅相成,共同构建了企业的完整业务体系。
端到端流程
简单来说,端到端流程就是从客户需求发起,到最终客户需求被满足的整个过程。
端到端流程是对价值流的具体实现和优化。前文中讲到,通过梳理价值流,我们可以聚焦客户需求,发现哪些环节是在为客户创造价值,哪些环节存在浪费。然后,基于这些环节,形成高效的端到端流程。
从价值流到端到端流程,就是把企业的价值创造流程化、系统化。通过优化端到端流程,企业可以提高效率、降低成本,更好地满足客户需求。端到端流程的价值包括:
- 全面了解业务:通过梳理从需求发起到满足的完整过程,揭示各环节衔接和潜在问题,就像清晰的路线图,指明了工作方向。
- 聚焦核心目标:端到端流程始于客户的真实需求。通过聚焦这些需求,我们能提供更精准的产品或服务,从而避免资源浪费。
- 增强企业响应能力:面对瞬息万变的市场和客户需求,清晰的流程让企业能够迅速调整策略。当新需求出现时,企业可以快速组合现有的流程模块,及时响应市场机会。
端到端流程如何切分?
端到端流程可以基于客户的核心业务场景进行划分的。这种方法确保流程设计始终以客户需求为中心,让企业能更好地理解和优化客户体验,同时提高内部运营效率。
例如,在零售行业中,销售类端到端流程可以根据客户的购买渠道和消费场景进行细分。例如,我们可以将流程划分为以下几类:
- 线上渠道销售流程:包括自有商城、社交媒体平台(如微信、抖音等)的销售流程。
- 线下门店销售流程:涵盖传统实体店、旗舰店和快闪店等不同类型门店的销售流程。
- 外卖平台销售流程:针对与第三方外卖平台合作的销售流程。
此外,在单一渠道内,我们还可以根据不同的交付方式细分流程。比如:
- 即时配送流程:适用于需要快速送达的商品。
- 预约自提流程:允许客户在线下单,选择方便的时间到店取货。
- 门店服务流程:针对实体店内客户的服务全过程。
职能流程
职能流程是企业各部门为完成特定任务而制定的工作规范。
职能流程有什么价值?通过梳理和完善职能流程,各部门的工作流程变得清晰明确。这为构建端到端流程提供了可靠的基础模块。职能流程的价值包括:
- 看清企业管理的完整性:职能流程的构建让企业能从业务角度审视职能的完整性。由于企业组织架构通常基于职能分工,梳理各职能流程就像对企业进行全面体检,找出需要改进的方面。
- 构建端到端流程:梳理职能流程使各部门工作更加明确。这为构建端到端流程提供了可靠基础,没有职能流程架构,端到端流程可能需要重复梳理,并且无法准确反映企业的实际管理情况。
职能流程如何切分?
关键在于以”业务对象”为核心进行划分。业务对象指在业务活动中产生的具有业务含义的文档、表单或数据,它们记录了业务事项的完整过程。以业务对象为基础切分职能流程,可确保每个流程涵盖完整的业务事项,避免过度拆分或模糊不清。
以蛋糕加工作业流程为例,从提交加工单开始,经过领料、配料、烘烤、裱花与装饰,直到加工完成。整个流程都围绕加工单这一对象展开,不应将领料、配料等环节拆分成独立流程,以免导致流程不闭环,增加管理复杂性。
通过以业务对象管理闭环为核心,切分职能流程,企业可统一流程得颗粒度,确保各部门在流程梳理时标准一致。
从价值流到业务流程
“价值流”是企业业务的战略蓝图,概括了整体价值创造过程;”端到端流程”则是这个蓝图的具体实施方案,详细描绘了每个环节的操作细节。
价值流为企业提供了宏观视角,而端到端流程则将其转化为可执行的具体步骤。这种从概念到落地的转化,确保企业能够有效地将战略意图转化为日常运营。
示例:新零售企业的业务流程
下图展示了一个典型的线上预订蛋糕并配送到家得端到端流程,其中包含了多个部门的职能流程。例如,客服部门负责接收、确认蛋糕细节、派单。中央厨房负责蛋糕的制作,物流部门则负责配送。
这些部门各自的工作流程体现了职能流程的具体实施。每个部门的泳道内的活动序列,准确地反映了该部门在整个业务流程中的职责和具体操作步骤。
从整体来看,我们可以清晰地观察到各个职能部门如何协同工作,共同完成从接收订单到最终交付的全过程。
总结
本文深入探讨了业务架构中的流程架构,重点阐述了以下几个方面:
- 业务流程的概念:解释了业务流程是企业为实现目标而制定的系统化工作方法,强调了其在企业运营中的重要性。
- 核心视角:介绍了端到端流程和职能流程两个核心视角,说明了它们在企业业务体系中的作用。
- 端到端流程:详细讨论了其定义、价值和切分方法,强调了以客户需求为中心的重要性。
- 职能流程:阐述了其定义、价值和切分方法,强调了以业务对象为核心进行划分的重要性。
- 价值流与业务流程的关系:解释了如何从战略层面的价值流转化为可执行的具体业务流程。
本文已收录于,我的技术网站:tangshiye.cn 里面有,算法Leetcode详解,面试八股文、BAT面试真题、简历模版、架构设计,等经验分享。
本文来自博客园,作者:架构师汤师爷,转载请注明原文链接:https://www.cnblogs.com/tangshiye/p/18422085
.NET常见的几种项目架构模式,你知道几种?(附带使用情况投票) - 追逐时光者 - 博客园
来源: .NET常见的几种项目架构模式,你知道几种?(附带使用情况投票) – 追逐时光者 – 博客园
前言
项目架构模式在软件开发中扮演着至关重要的角色,它们为开发者提供了一套组织和管理代码的指导原则,以提高软件的可维护性、可扩展性、可重用性和可测试性。
假如你有其他的项目架构模式推荐,欢迎在文末留言🤞!!!
项目架构模式使用情况收集(微信投票,请在微信中打开参与):https://mp.weixin.qq.com/s/kr1vlt4tj3dSyXyRv-GqOw
三层架构
三层架构是一种经典的软件架构模式,它将应用程序分为三个主要层次:表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。
分层职责
- 表示层(UI):负责用户界面和用户交互,是用户直接接触的部分。
- 业务逻辑层(BLL):处理业务规则和业务逻辑,是应用程序的核心部分。它负责数据的处理、验证、计算等业务操作。
- 数据访问层(DAL):负责与数据库的交互,包括数据的CRUD(创建、读取、更新、删除)操作。
MVC架构
MVC架构模式将一个应用区分为三部分主要组件:模型、视图、与控制器。这种模式有助实现关注分离,使用这种模式,用户请求被路由到控制器,控制器负责与模型协作以执行用户操作和/或返回请求结果。极大地提高了应用程序的可维护性和扩展性。
分层职责
- 模型(Model):表示应用程序和任何应由其执行的业务逻辑或操作的状态。业务逻辑应与保持应用程序状态的任何实现逻辑一起封装在模型中。
- 视图(View):负责通过用户界面展示内容。它们使用 Razor 视图引擎在 HTML 标记中嵌入 .NET 代码。视图中应该有最小逻辑,并且其中的任何逻辑都必须与展示内容相关。
- 控制器(Controller):处理用户交互、使用模型并最终选择要呈现的视图的组件。在 MVC 应用程序中,视图仅显示信息;控制器处理并响应用户输入和交互。在 MVC 模式中,控制器是初始入口点,负责选择要使用的模型类型和要呈现的视图。
DDD分层架构
领域驱动设计(Domain-Driven Design,简称DDD)是一种软件设计方法和理念,由Eric Evans在2004年提出。它通过深入理解业务领域,将复杂的业务逻辑转化为可维护、可扩展的软件系统。DDD的核心在于建立一个丰富的领域模型,这个模型能够反映业务实体、业务规则和业务流程。
DDD 强调以领域模型为核心来驱动软件的设计和开发。
分层职责
- 表示层(UI): 负责处理用户界面和用户交互,它可以是Web界面、移动应用程序或桌面应用程序等形式。表示层负责接收用户的输入和展示数据给用户,但它不包含业务逻辑。
- 应用层(Application): 表示层与领域层的中介,编排业务对象执行特定的应用程序任务,使用应用程序逻辑实现用例。
- 领域层(Domain): 包含业务对象以及业务规则,是应用程序的核心。领域层的设计应遵循领域驱动设计的原则,通过深入理解业务领域,将业务知识和业务逻辑封装在领域模型中,以提高软件系统的可维护性和可扩展性。
- 基础设施层(Infrastructure): 提供技术基础设施支持,如数据库访问、消息队列、缓存等。
整洁架构
整洁架构(Clean Architecture)是一种软件架构设计原则,由罗伯特·C·马丁(Robert C. Martin)提出,它旨在使软件系统更加灵活、可维护和可测试,其核心目标是构建一种简洁、灵活且易于维护的系统结构。
分层职责
- 实体层(Entities):实体层代表了系统中的核心业务概念和对象。这一层包含了那些在整个系统的生命周期中持续存在且具有明确业务含义的实体。
- 用例层(Use Cases):用例层包含了系统的具体业务逻辑和用例。它协调实体层和其他层之间的交互,以实现特定的业务功能。
- 接口适配器层(Interface Adapters):接口适配器层将用例层与外部系统(如数据库、用户界面、外部服务等)进行连接。它将外部系统的接口转换为用例层可以理解的形式,并将用例层的输出转换为适合外部系统的格式。
- 框架与驱动层(Frameworks and Drivers):框架与驱动层包含了外部的框架和工具,如数据库、Web 框架、消息队列等。这一层通常是由具体的技术实现组成,为上层提供基础设施支持。
CQRS架构
CQRS(命令和查询责任分离)是一种架构模式,旨在将一个系统的读操作(查询)和写操作(命令)分离开来。通过这种分离,系统可以在处理读写请求时进行不同的优化,从而提高系统性能、可扩展性和维护性。
分层职责
- Presentation(表现层):负责处理用户界面的请求和响应。它接收用户输入并将其传递给后端服务,同时将后端服务的响应展示给用户。
- Validation(验证):在命令被处理之前,对用户输入的数据进行验证,确保数据的合法性和完整性。
- Commands(命令):封装用户请求的写操作,如创建、更新或删除数据的操作。
- Domain Logic(领域逻辑):执行核心业务逻辑和规则,命令处理器通常会调用领域模型和领域服务来执行业务逻辑,确保业务规则得到正确应用。
- Data Persistence(数据持久化):在命令处理完成后,数据会被保存到写数据存储中,确保数据的一致性和持久性。
- Write Data Store(写数据存储):写数据存储负责管理所有写操作的数据,包括事务处理和数据一致性。
- Read Data Store(读数据存储):读数据存储优化了读取操作的性能,提供快速响应的查询结果。
- Queries(查询):查询对象被传递给查询处理器,查询处理器直接从读数据存储中获取数据,并生成DTOs返回给展示层。
最后总结
每种项目架构模式都有其各自特点和适用场景,开发者应根据项目的具体需求和技术栈来选择最合适的项目架构模式。
参考文章
DotNetGuide技术社区
- DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目框架推荐、求职和招聘资讯、以及解决问题的平台。
- 在DotNetGuide技术社区中,开发者们可以分享自己的技术文章、项目经验、学习心得、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
- 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台。无论您是初学者还是有丰富经验的开发者,我们都希望能为您提供更多的价值和成长机会。