前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[用户权限管理 ]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
SpringBoot
...er或其他协调服务来管理任务执行状态,确保任务只在一个节点上执行,其他节点等待。 4. ConsistentHashing 如果任务负载均衡且没有互斥操作,可以考虑使用一致性哈希算法将任务分配给不同的节点,这样当增加或减少节点时,任务分布会自动调整。 四、代码示例 使用Consul作为服务发现 为了实现多节点的部署,我们还可以利用Consul这样的服务发现工具。首先,配置Spring Boot应用连接Consul,并在启动时注册自身服务。然后,使用Consul的健康检查来确保任务节点是活跃的。 java import com.ecwid.consul.v1.ConsulClient; import com.ecwid.consul.v1.agent.model.ServiceRegisterRequest; @Configuration public class ConsulConfig { private final ConsulClient consulClient; public ConsulConfig(ConsulClient consulClient) { this.consulClient = consulClient; } @PostConstruct public void registerWithConsul() { ServiceRegisterRequest request = new ServiceRegisterRequest() .withId("my-task-service") .withService("task-service") .withAddress("localhost") .withPort(port) .withTags(Collections.singletonList("scheduled-task")); consulClient.agent().service().register(request); } @PreDestroy public void deregisterFromConsul() { consulClient.agent().service().deregister("my-task-service"); } } 五、总结与未来展望 将SpringBoot的定时任务服务从单节点迁移到多节点并非易事,但通过合理选择合适的技术栈(如消息队列、分布式锁或服务发现),我们可以确保任务的可靠执行和扩展性。当然,这需要根据实际业务场景和需求来定制解决方案。干活儿的时候,咱们得眼观六路,耳听八方,随时盯着,不断测验,这样才能保证咱这多站点的大工程既稳如老狗,又跑得飞快,对吧? 记住,无论你选择哪种路径,理解其背后的原理和潜在问题总是有益的。随着科技日新月异,各种酷炫的工具和编程神器层出不穷,身为现代开发者,你得像海绵吸水一样不断学习,随时准备好迎接那些惊喜的变化,这可是咱们吃饭的家伙!
2024-06-03 15:47:34
47
梦幻星空_
转载文章
...19。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 半自动化批量下载专利全文pdf傻瓜攻略 写在前面 适合人群 使用前提 基本思路 键鼠记录器脚本 前期准备 脚本原理 注意事项 检查下载效果 写在前面 整理专利的时候,在专利引擎上只能一条条的下载,很是烦人。我比较讨厌这种重复性劳动,所以每次碰上都得想想办法怎么自动化操作,虽然上每次研究自动化办法的时间把都足够把活干完了哈哈。可惜的是每次搞完都没有把文档保留下来,下次有点什么事情又得从头开始。因此准备开始写写文档记录一些思路,同时如果能帮到有需要的人就更好了! 适合人群 不会爬虫的都可以来看看!能大概看明白python就够了。 使用前提 python环境配好 有梯子 不排斥键鼠记录器读取键鼠记录 基本思路 现在的专利搜索引擎大概都有批量下载库,如果只要摘要的话直接下载就可以了。但是下载全文的时候,大部分引擎都不支持批量下载,只能一个一个点,还得输验证码。 这里就不得不提到google patent了,这是我目前找到的唯一一个不需要验证码就能下载的专利引擎了(其实主要是还不会用python识别验证码)。那么有了google patent这个神器,就可以用自动办法来进行下载了。我这里使用的是按键精灵,傻瓜式操作。(没用python爬虫的原因是requests不能挂梯子。。。这里我不是很确定是什么问题,希望有大佬指点一下。anyway,主要思路就是用键鼠记录器点点点,我用的是按键精灵,理论上什么记录器都可以。 ps. 听说poxoq能批量下载,但是新版本只能下载前十页,因此我没有尝试,如果能直接下载全文的话请评论区告诉我。 键鼠记录器脚本 前期准备 按格式排好公开号或者申请号,在编辑器中打开; 把google patent搜索页面和文本编辑器分屏显示,便于操作。 脚本原理 以edge浏览器为例,按键精灵双击全选文本中第一行的公开号,ctrl+c复制,鼠标转到网页搜索框,ctrl+v粘贴,点搜索。等搜索完成右键download PDF,选链接另存为并确定,之后点击网页关闭下载栏,一次下载完成。返回编辑器,删除第一行的文本,把第二行提到第一行,完成复位。 这样就形成了完整的一次过程,只要重复运行脚本就可以把所有专利全文下载下来。 注意事项 实际操作中,可能遇到两大问题: 网页反馈问题 这里指的是搜索后没有来到我们想象中的专利页,可能是没有搜索到专利,或该专利google patent没有pdf文档,这时如果脚本还在运行,那么显然就会错误运行。 脚本运行问题 主要要考虑的是命令之间的延时。延时调小确实运行速度会变快,但是如果电脑运行速度不够或者网速/服务器慢了,就会错误执行命令。我的建议是文本操作可以适当删减延时,涉及网页的部分适量增加延时,保证脚本的容错率。 由此可以看出来这个脚本还是离不开人的,在跑的时候还是需要盯着点,如果有错误可以及时处理。 检查下载效果 看了上面的注意事项,想必你也知道这个脚本不太靠谱。那么解决这个问题的方法就是负反馈。下载完了检查一遍就好了。 由于google patent下载的文件是以公开号命名的,所以对照要下载的和已下载的公开号就能看出哪些专利没有下载成功。 我这里写了一个python小脚本。 import pandas as pdimport os读取待下载专利的公开号,地址修改成你自己存放的位置df = pd.read_excel("target.xlsx",header= 0, usecols= "B").drop_duplicates()取前11位作为对比(以中国专利作为参考)PublicNumber_tgt = list(map(lambda x: x[0:11],df["公开(公告)号"].to_list()))读取已下载专利的公开号,地址修改成你自己存放的位置filelist=os.listdir(r'C:\Users\mornthx\Desktop\专利全文')取前11位作为对比PublicNumber_dl = list(map(lambda x: x[0:11],filelist))比较两者差值diff = set(PublicNumber_tgt).difference(set(PublicNumber_dl))print(diff) 没下载的专利具体问题具体解决就好了。 希望能帮到大家! 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_38688347/article/details/124000919。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-21 12:55:28
275
转载
转载文章
...92。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 前言 本文写于2007年11月,那时候我是在Discuz!开发组为PHPChina的《PHPer》写的稿,一直也没有发到blog上了,今天偶然之间记起,顺手转发过来。 一、关于模板引擎的前言 从phplib到smarty,再到Discuz!的模板机制,本文试图通过PHP模板引擎为你讲解作者自己的PHP心得。 我清楚的记得在我刚上大学开始学习PHP的时候,曾经在phpe.net看到过一篇关于phplib Template和FastTemplate这两模板引擎性能比较的文章。让我在接下来半年的时间内持续的使用着phplib。不可否认phplib是左右了一代PHP开发人员对于PHP模板引擎的认识。或许你也会对下面的方法比较熟悉$t->set_file $t->set_var 当我对于phplib的执行效率不满意的时候,我开始寻找下一个PHP的模板引擎,于是smarty跳入我的视野范围,当我费尽心血去学会了smarty并使用开发了很多东西,而现在的我突然发现记得的也就只有下面的方法了$s->assign $s->display 究竟我们需要模板引擎来做什么呢,MVC?简单?易用?效率?请看下文的分析。 二、程序处理的分析 1.PHPLIB的程序处理过程 从phplib的处理开始讲起$t = new Template() $t->set_file $t->set_var $t->parse $t->p 看上面的代码,翻译成中文就是初始化模板类$t 设置模板文件 设置模板变量 分析模板文件中的模板变量 输出内容 通过了最少5个步骤在php程序中实现模板的处理 2.Smarty的程序处理过程 现在来看smarty的处理$s = new Smarty $s->assign $s->display 翻译成中文就是初始化模板类$s 设置模板变量 解析并输出模板 3.Discuz!模板的程序处理过程include template(tplname); 主要作用就是指定给程序需要处理的模板文件 在上述三种模板处理机制中,最容易理解和接受就是Discuz!模板的处理过程。初始化、设置变量、解析模板、输出内容,Discuz!只用了一个函数来做。对于一个开源的论坛软件,这样处理的好处是显而易见的,对于Discuz!进行二次开发的程序员的要求降低。简化模板语言,方便风格和插件的制作,这也在一定程度上促进了Discuz!的传播 三、模板源文件的语法 在phplib中处理循环嵌套的时候,使用: {it} 在smarty中处理循环嵌套的时候,引入了< {section name=loopName loop=$loopArray}>(当然还有foreach这样的) 在Discuz!中处理循环嵌套的时候, 其实真正的模板面对的可以说是不懂PHP或者懂一点PHP的美工同志们,模板的复杂就意味着美工制作页面的难度加大。在必不可少的需要模板有逻辑处理的时候,为什么不在html代码中使用原生态的PHP语法,而让美工相当于去学习另外一种语言呢?在我个人的经验中,显然是Discuz!的模板语言更为简单易学,也为我节省了更多的时间。 四、Discuz!模板处理机制 我剥离出一个简单的Discuz!模板处理函数function template($file, $templateid = 0, $tpldir = '') { $tplfile = DISCUZ_ROOT.'./'.$tpldir.'/'.$file.'.htm';//模板源文件,此处$tplfile变量的值可能是D:\discuz\templates\default\demo.htm $objfile = DISCUZ_ROOT.'./forumdata/templates/'. $templateid.'_'.$file.'.tpl.php';//模板缓存文件,此处$objfile变量的值可能是D:\discuz\forumdata\templates\1_demo.tpl.php //如果模板源文件的修改时间迟于模板缓存文件的修改时间, //就是模板源文件被修改而模板缓存没有更新的时候, //则调用parse_template函数重新生成模板缓存文件。 if(@filemtime($tplfile) > @filemtime($objfile)) { require_once DISCUZ_ROOT.'./include/template.func.php'; parse_template($file, $templateid, $tpldir); } //返回缓存文件名称 //$objfile变量内容可能为D:\discuz\forumdata\templates\1_demo.tpl.php return $objfile; } 而php页面的模板执行语句include template('demo'); 实际上在本例中就是相当于include 'D:\discuz\forumdata\templates\1_demo.tpl.php'; 这个流程就是一个demo.php文件中当数据处理完成以后include template('demo'),去显示页面。 五、总结 我也曾经看到过有列举出很多种的PHP模板引擎,但是我觉着phplib、smarty、Discuz!模板机制就足以说明问题了。 1.我们需要模板来做什么? 分离程序与界面,为程序开发以及后期维护提供方便。 2.我们还在关心什么? PHP模板引擎的效率,易用性,可维护性。 3.最后的要求什么? 简单就是美! 我的文章好像没有写完,其实已经写完了,我要说明的就是从PHP的模板引擎看Discuz!模板机制。分析已经完成,或许以后我会再写篇实际数据的测试供给大家参考! Tags: none 版权声明:原创作品,欢迎转载,转载时请务必以超链接形式标明文章原始地址、作者信息和本声明。 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_42557656/article/details/115159292。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-10-07 14:43:46
109
转载
Etcd
...种可靠的方式来存储和管理这些关键信息。哎呀,小伙伴们在操作Etcd这个超级棒的工具时,有时候可能会遇到一些小波折。比如说,“Request timeout while waiting for Raft term change”,这可是一个挺常见的小麻烦呢!想象一下,就像你在跟朋友玩儿接力赛,突然发现时间到了,但是你还没能顺利把棒子传过去一样,这事儿也挺让人着急的嘛。别担心,咱们找找原因,一步步解决,很快就能让Etcd继续飞快地跑起来啦!本文将深入探讨这个问题,了解其背后的原理,并提供解决策略。 1. Etcd与Raft协议 Etcd基于Raft协议来实现分布式一致性,这是一种用于多节点环境中的高效算法。在Etcd中,数据被组织成键值对的形式,并通过一个中心节点(称为leader)进行管理和分发。当一个节点想要修改数据或获取最新版本的数据时,它会与leader通信。哎呀,这事儿可真不是总能一帆风顺的,特别是当网速慢得跟蜗牛爬似的,或者服务器那边节点多到数不清的时候,你可能就得头疼了。遇到这种情况,最烦的就是请求老是半天没反应,像是跟服务器玩起了捉迷藏,怎么喊都不答应。 2. “Request timeout while waiting for Raft term change”错误详解 这个错误通常发生在客户端尝试获取数据更新或执行操作时,Etcd的leader在响应之前发生了切换。在Raft协议中,leader的角色由选举决定,而选举的过程涉及到节点状态的转换。当一个节点成为新的leader时,它会通知所有其他节点更新他们的状态,这一过程被称为term变更。如果客户端在等待这个变更完成之前超时,就会抛出上述错误。 3. 导致错误的常见原因 - 网络延迟:在网络条件不稳定或延迟较高的情况下,客户端可能无法在规定时间内收到leader的响应。 - 大规模操作:大量并发请求可能导致leader处理能力饱和,从而无法及时响应客户端。 - 配置问题:Etcd的配置参数,如客户端超时设置,可能不适用于实际运行环境。 4. 解决方案与优化策略 1. 调整客户端超时参数 在Etcd客户端中,可以调整请求超时时间以适应实际网络状况。例如,在Golang的Etcd客户端中,可以通过修改以下代码来增加超时时间: go client, err := etcd.New("http://localhost:2379", &etcd.Config{Timeout: time.Second 5}) 这里的Timeout参数设置为5秒,可以根据实际情况进行调整。 2. 使用心跳机制 Etcd提供了心跳机制来检测leader的状态变化。客户端可以定期发送心跳请求给leader,以保持连接活跃。这有助于减少由于leader变更导致的超时错误。 3. 平衡负载 确保Etcd集群中的节点分布均匀,避免单个节点过载。嘿,兄弟!你知道吗?要让系统稳定得像磐石一样,咱们得用点小技巧。比如说,咱们可以用负载均衡器或者设计一些更精细的路径规则,这样就能把各种请求合理地分摊开,避免某个部分压力山大,导致系统卡顿或者崩溃。这样一来,整个系统就像一群蚂蚁搬粮食,分工明确,效率超高,稳定性自然就上去了! 4. 网络优化 优化网络配置,如使用更快的网络连接、减少中间跳转节点等,可以显著降低网络延迟,从而减少超时情况。 5. 实践案例 假设我们正在开发一个基于Etcd的应用,需要频繁读取和更新数据。在实现过程中,我们发现客户端请求经常因网络延迟导致超时。通过调整客户端超时参数并启用心跳机制,我们成功降低了错误率。 go // 创建Etcd客户端实例 client, err := etcd.New("http://localhost:2379", &etcd.Config{Timeout: time.Second 5}) if err != nil { log.Fatalf("Failed to connect to Etcd: %v", err) } // 执行读取操作 resp, err := client.Get(context.Background(), "/key") if err != nil { log.Fatalf("Failed to get key: %v", err) } // 输出结果 fmt.Println("Key value:", resp.Node.Value) 通过实践,我们可以看到,合理配置和优化Etcd客户端能够有效应对“Request timeout while waiting for Raft term change”的挑战,确保分布式系统的稳定性和高效运行。 结语 面对分布式系统中的挑战,“Request timeout while waiting for Raft term change”只是众多问题之一。哎呀,兄弟!要是咱们能彻底搞懂Etcd这个家伙到底是怎么运作的,还有它怎么被优化的,那咱们系统的稳定性和速度肯定能上一个大台阶!就像给你的自行车加了涡轮增压器,骑起来又快又稳,那感觉简直爽翻天!所以啊,咱们得好好研究,把这玩意儿玩到炉火纯青,让系统跑得飞快,稳如泰山!在实际应用中,持续监控和调整系统配置是保证服务稳定性的关键步骤。希望本文能为你的Etcd之旅提供有价值的参考和指导。
2024-09-24 15:33:54
121
雪落无痕
转载文章
...05。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 1、插件说明 jstree官方地址:https://www.jstree.com bootstrap官方地址:https://v3.bootcss.com font-awesome官方地址:http://www.fontawesome.com.cn/faicons/ github项目地址:https://github.com/chengchuanqiang/jstreeDemo 2、jstreedemo主要文件 2.1、html页面代码 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>jstree demo</title><link rel="stylesheet" href="jstree/dist/themes/default/style.min.css" /><link rel="stylesheet" type="text/css" href="bootstrap-3.3.7-dist/css/bootstrap.min.css" /> <link rel="stylesheet" type="text/css" href="font-awesome-4.7.0/css/font-awesome.min.css" /> </head><body><div class="container"> <div class="row" style="height: 100px;"></div><div class="row"><div > <button class="btn btn-info" onclick="node_create()"> 新增 </button><button class="btn btn-info" onclick="node_rename()"> 编辑</button><button class="btn btn-info" onclick="node_delete()"> 删除</button></div></div><div class="row" style="height: 5px;"></div><div class="row"> <div class="col-md-3"> <!-- 描述:搜索框 --> <div class="input-group row"> <span class="input-group-addon" id="basic-addon1"><i class="glyphicon glyphicon-screenshot"></i></span> <input type="text" class="form-control" placeholder="请输入功能名称..." id="search_ay" aria-describedby="basic-addon1"> </div> <!--描述:jstree 树形菜单容器--> <div id="jstree_demo_div" class="row"> </div> </div> <div lass="col-md-9"> <button class="btn btn-tab" var='json/data.json'>data.json</button> <!--点击切换资源--> <button class="btn btn-tab" var='json/data2.json'>data2.json</button> <!--点击切换资源--> <button class="btn refresh "><i class="glyphicon glyphicon-refresh"></i></button> <!--点击刷新资源--> </div> </div> </div> <script src="jquery/jquery.min.js"></script><script src="jstree/dist/jstree.min.js"></script><script src="jstreeDemo.js?20180125"></script></body></html> 2.2、jstreeDemo.js代码 function jstree_fun(url){var $tree = $("jstree_demo_div").jstree({"core":{//'multiple': false, // 是否可以选择多个节点//"check_callback": true, // 允许拖动菜单 唯一 右键菜单"check_callback" : true,//设置为true,当用户修改数时,允许所有的交互和更好的控制(例如增删改)"themes" : { "stripes" : true },//主题配置对象,表示树背景是否有条带"data" : {//'url' : url,//'data' : function(node){//return { 'id' : node.id };//}"url" : url,"dataType" : "json"},"check_callback" : function(operation, node, node_parent, node_position, more){if(operation === "move_node"){var node = this.get_node(node_parent);if(node.id === ""){alert("根结点不可以删除");return false;}if(node.state.disabled){alert("禁用的不可以删除");return false;} }else if(operation === "delete_node"){var node = this.get_node(node_parent);if(node.id === ""){alert("根结点不可以删除");return false;} }return true;} },"plugins": [ //插件 "search", //允许插件搜索 // "sort", //排序插件 "state", //状态插件 "types", //类型插件 "unique", //唯一插件 "wholerow", //整行插件"contextmenu"],types:{ "default": { //设置默认的icon 图 "icon": "glyphicon glyphicon-folder-close", } } });$tree.on("open_node.jstree", function(e,data){ //监听打开事件var currentNode = data.node; data.instance.set_icon(currentNode, "glyphicon glyphicon-folder-open"); });$tree.on("close_node.jstree", function(e,data){ //监听关闭事件 var currentNode = data.node; data.instance.set_icon(currentNode, "glyphicon glyphicon-folder-close"); });$tree.on("activate_node.jstree", function(e, data){var currentNode = data.node; //获取当前节点的json .node //alert(currentNode.a_attr.id) //alert(currentNode.a_attr.href) //获取超链接的 .a_attr.href "链接" .a_attr.id ID //alert(currentNode.li_attr.href) //获取属性的 .li_attr.href "链接" .li_attr.id ID });// 创建$tree.on("create_node.jstree", function(e, data){alert("创建node节点");});// 修改$tree.on("rename_node.jstree", function(e, data){alert("修改node节点");});// 删除$tree.on("delete_node.jstree", function(e, data){alert("删除node节点");});// 查询节点名称var to = false;$("search_ay").keyup(function(){if(to){clearTimeout(to);}to = setTimeout(function(){$tree.jstree(true).search($('search_ay').val()); //开启插件查询后 使用这个方法可模糊查询节点 },250);});$('.btn-tab').click(function(){ //选项事件 //alert($(this).attr("var")) $tree.jstree(true).destroy(); //可做联级 $tree = jstree_fun($(this).attr("var"));//可做联级 //alert($(this).attr("var")) }); $('.refresh').click(function(){ //刷新事件 $tree.jstree(true).refresh () }); return $tree; }function node_create(){var ref = $("jstree_demo_div").jstree(true);var sel = ref.get_selected();if(!sel.length){alert("请先选择一个节点");return;}sel = sel[0];sel = ref.create_node(sel);if(sel){ref.edit(sel); } }function node_rename(){var ref = $("jstree_demo_div").jstree(true);var sel = ref.get_selected();if(!sel.length){alert("请先选择一个节点");return;}sel = sel[0];ref.edit(sel);}function node_delete(){var ref = $("jstree_demo_div").jstree(true);var sel = ref.get_selected();if(!sel.length){alert("请先选择一个节点");return;}sel = sel[0];if(ref.get_node(sel).parent==''){alert("根节点不允许删除");return;}ref.delete_node(sel);}// 初始化操作function init(){var $tree = jstree_fun("json/data.json");}init(); 3、图片效果展示 本篇文章为转载内容。原文链接:https://blog.csdn.net/qq_27717967/article/details/79167605。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-09-08 13:23:58
54
转载
Dubbo
...定性和可观察性与配置管理息息相关。近期,Apache Dubbo社区发布了一项重要更新,针对配置中心的功能进行了强化升级,支持更灵活、动态的配置管理方式,有效降低了因配置问题引发的故障风险。 此外,随着云原生技术的快速发展,Kubernetes等容器编排平台对Java应用环境变量的管理提供了更为精细化的解决方案。通过结合ConfigMap和Envoy sidecar代理,可以实现服务运行时环境变量的自动化注入与热更新,进一步提升Dubbo等微服务框架在复杂分布式环境下的健壮性与稳定性。 同时,日志作为系统运行状态的重要反馈途径,其标准化与集中化处理也日益受到重视。例如,业界广泛采用的ELK(Elasticsearch、Logstash、Kibana)栈为日志收集、分析与可视化提供了强大支持,结合开源项目如log4j2或Logback与Dubbo进行深度集成,不仅可以实时监控Dubbo服务内部运行状态,还能快速定位并排查各类问题,极大提升了运维效率。 综上所述,对于使用Dubbo的开发者而言,紧跟社区发展动态,掌握最新的配置管理工具与日志处理技术,将有力推动项目的高效运行与维护。同时,理解和实践DevOps理念,注重基础设施即代码(Infrastructure as Code, IaC)以及持续集成/持续部署(CI/CD)等现代软件工程方法,亦是提高服务质量和团队协作效率的关键所在。
2023-06-21 10:00:14
436
春暖花开-t
转载文章
...35。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 本文内容为海贼王全集的分章节目录介绍,还有本人在观看时候记录的精彩打斗剧集,可以方便大家直接定位想看的章节和精彩内容, 源文件已经上传到我的资源中,有需要的可以去看看, 我主页中的思维导图中内容大多从我的笔记中整理而来,相应技巧可在笔记中查找原题, 有兴趣的可以去 我的主页 了解更多计算机学科和考研的精品思维导图整理 本文可以转载,但请注明来处,觉得整理的不错的小伙伴可以点赞关注支持一下哦! 博客中思维导图的高清PDF版本,可关注公众号 一起学计算机 点击 资源获取 获得 目录 0.精彩打斗剧集 0.剧场版 1.东海冒险篇1-60 2.阿拉巴斯坦篇61-130 3.TV原创篇131-143 4.空岛篇144-195 5.海军要塞G8196-206 6.长链岛篇207-226 7.司法岛篇227-325 8.旗帜猎人篇326-336 9.恐怖三桅帆船篇337-383 10.香波地群岛篇384-407 11.女儿岛篇408-421 12.海底监狱篇422-456 13.大事件篇457-504 14.新世界前篇505-516 15.鱼人岛篇517-574 16.Z的野心篇575-578 17.庞克哈萨德篇579-628 18.德雷斯罗萨篇629-746 19.银之要塞篇747-750 20.佐乌篇751-782 21.托特兰篇783-877 22.世界会议篇878-889 23.和之国篇890-至今 我的更多精彩文章链接, 欢迎查看 经典动漫全集目录 精彩剧集 海贼王 动漫 全集目录 分章节 精彩打斗剧集 思维导图整理 火影忍者 动漫 全集目录 分章节 精彩打斗剧集 思维导图整理 死神 动漫 全集目录 分章节 精彩打斗剧集 思维导图整理 计算机专业知识 思维导图整理 Python 北理工慕课课程 知识点 常用代码/方法/库/数据结构/常见错误/经典思想 思维导图整理 C++ 知识点 清华大学郑莉版 东南大学软件工程初试906 思维导图整理 计算机网络 王道考研 经典5层结构 中英对照 框架 思维导图整理 算法分析与设计 北大慕课课程 知识点 思维导图整理 数据结构 王道考研 知识点 经典题型 思维导图整理 人工智能导论 王万良慕课课程 知识点 思维导图整理 红黑树 一张导图解决红黑树全部插入和删除问题 包含详细操作原理 情况对比 各种常见排序算法的时间/空间复杂度 是否稳定 算法选取的情况 改进 思维导图整理 人工智能课件 算法分析课件 Python课件 数值分析课件 机器学习课件 图像处理课件 考研相关科目 知识点 思维导图整理 考研经验--东南大学软件学院软件工程 东南大学 软件工程 906 数据结构 C++ 历年真题 思维导图整理 东南大学 软件工程 复试3门科目历年真题 思维导图整理 高等数学 做题技巧 易错点 知识点(张宇,汤家凤)思维导图整理 考研 线性代数 惯用思维 做题技巧 易错点 (张宇,汤家凤)思维导图整理 高等数学 中值定理 一张思维导图解决中值定理所有题型 考研思修 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理 考研近代史 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理 考研马原 知识点 做题技巧 同类比较 重要会议 1800易错题 思维导图整理 考研数学课程笔记 考研英语课程笔记 考研英语单词词根词缀记忆 考研政治课程笔记 Python相关技术 知识点 思维导图整理 Numpy常见用法全部OneNote笔记 全部笔记思维导图整理 Pandas常见用法全部OneNote笔记 全部笔记思维导图整理 Matplotlib常见用法全部OneNote笔记 全部笔记思维导图整理 PyTorch常见用法全部OneNote笔记 全部笔记思维导图整理 Scikit-Learn常见用法全部OneNote笔记 全部笔记思维导图整理 Java相关技术/ssm框架全部笔记 Spring springmvc Mybatis jsp 科技相关 小米手机 小米 红米 历代手机型号大全 发布时间 发布价格 常见手机品牌的各种系列划分及其特点 历代CPU和GPU的性能情况和常见后缀的含义 思维导图整理 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_43959833/article/details/115670535。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-01-12 18:13:21
742
转载
Spark
...理和高效恢复,为海量用户行为分析提供了有力保障。 总之,随着大数据处理需求的不断增长和技术环境的日益复杂,Spark在数据传输中断问题上的策略与实践将持续演进并扩展至更多创新领域。对于企业和开发者来说,紧跟Spark的最新发展动态,并结合自身业务特点进行技术创新与实践,将是构建健壮、高效的大数据处理系统的关键所在。
2024-03-15 10:42:00
576
星河万里
转载文章
...11。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 1月19日,人人网发布一款语音产品,名字与啪啪非常类似,叫啵啵,并号称是中国首款带语音滤镜的语音社交产品。目前其首页已经放出安卓版本,iOS版暂时还未上线。雷锋网进行了试用,跟大家介绍。 从官方的介绍来看,啵啵这个应用主要有三个特色,最大的特点是声音滤镜。另外,还可以在应用内使用声音、图片和文字等元素进行信息表达。最后当然就是社交分享功能。 打开应用,首先是类似Path或者啪啪那样一片红色的开始界面。界面中从下部飘起三个气泡,分别是人人登录、新浪微博登录以及直接进入使用。啵啵可以无需注册直接进入应用进行发布消息。 进入主界面后,主界面以时间线的形式把用户所关注的人发的声音图片信息。每条信息中,表示声音的大图标覆盖在图片显眼位置,意味着啵啵想让用户知道声音才是这个应用的主要元素,图片是作为背景图的辅助元素出现的。另外,在背景图右边有表示喜欢和评论的按钮。 主界面下方中心有十分突出显眼的声音按钮,点击后首先进入录音界面。 录音完成后,应用立刻列出表示声音滤镜的各种可爱图标。选择了某种滤镜效果后,声音生成完毕。进入发布界面,此时可以选择是否添加图片。可选择把信息分享到人人网或者新浪微博。 添加图片完成后,同时下方还可以添加文字描述,果然是声音、图片和文字三位一体全方位出击之应用。虽然这里主打声音,但声音、图片和文字分离的形式才更为符合人们对信息介质的认知习惯,小编一直认为啪啪中的所谓声音图片的概念只是一个伪概念。 对于新用户来说,可以选择添加人人网好友或者新浪微博好友,当然,应用本身会推荐优质应用建议新用户进行关注。另外,用户的关注、喜欢等信息会出现在用户的消息中心中。 这是一个同样基于信息分享的移动社交产品,其本质其实与Instagram等图片分享社区、啪啪等语音分享社区一样。啪啪本来是最先进行声音信息分享的社区,但啪啪把声音与图片混合在一起生硬造出了一个声音图片的概念,反而留下了主打声音信息分享的切入点,现在人人就抓住了这个切入点推出啵啵这个产品。 事实上,从目前已经存在啵啵社区中的用户发的消息来看,其性质与啪啪并无很大区别。啵啵主打的声音滤镜功能,有一个非常非常严重的缺陷。图片分享社区的滤镜功能对图片的改造是美化,图片滤镜可以把一张普通的图片改的看上去非常的优美和文艺,因而大大增强了用户的分享欲望,让人人都有当一回摄影师的感觉。 但声音滤镜做不到这样的效果,至少从啵啵中看来达不到美化的效果,目前从社区中声音信息可知,声音经过滤镜处理之后变得非常怪异。本身声音美的用户尤其女孩子必然受不了这样的声音变化,声音不好听的用户,经过处理后,结果是更加的不堪回首。所以,从实际情况来看,大多数人都会直接发布不加滤镜的原音。 另外,应用中有个设置奇特的地方在于,如果发布信息时只发布声音不附加图片,这条信息的背景会有一大片的空白,效果比较差。别说应用制作者,用户们都会觉得很有违和感,因而绝大多数用户都会添加图片。 这时候,啵啵变得非常类似啪啪,虽然本身,其与啪啪就相差不大。 是的,这是啪啪披着声音滤镜的外衣,事实上笔者怀疑啪啪不做声音滤镜就是有声音滤镜反而丑化声音的考虑。据了解,这是本周重组后的人人公司新的无线事业部推出的两款移动应用之一。但如果说这就是一个上市大公司在移动端发力所能做到的全部,这无疑是稍让人失望的。而且,人人网能不能不要这么马虎对待自己的产品?所谓的@啵啵官博就只在1月18日发布了一条消息,之后这个微博账号再无动静。 如果按照许朝军解释啪啪名字的来源:啪=口+拍,声音加图片。那啵啵又作何解? 好吧,其实人人网解释是这样的:“语音产品,所以取拟声名字,明确定位”。 参考:http://www.hooxiao.com/index.php?m=content&c=index&a=show&catid=19&id=14864(2013-01-21 10:04:03) 本篇文章为转载内容。原文链接:https://blog.csdn.net/prairie79/article/details/8546911。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-08-17 12:49:28
488
转载
转载文章
...05。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 D(x)=E{[x−E(x)]2} :相对于平均数差距的平方的期望; 数理统计一词的理解:mathematical stats,也即用数学的观点审视统计,为什么没有数理概率,因为概率本身即为数学,而对于统计,random variable 的性质并不全然了解,所以数理统计在一些书里又被称作:stats in inference(统计推论,已知 ⇒ 未知) 概率与统计的中心问题,都是random variable, PMF与PDF PMF:probability mass function,概率质量函数,是离散型随机变量在各特定取值上的概率。与概率密度函数(PDF:probability density function)的不同之处在于:概率质量函数是对离散型随机变量定义的,本身代表该值的概率;概率密度函数是针对连续型随机变量定义的,本身不是概率(连续型随机变量单点测度为0),只有在对连续随机变量的pdf在某一给定的区间内进行积分才是概率。 notation 假设X 是一个定义在可数样本空间S 上的离散型随机变量S⊆R ,则其概率质量函数PMF为: fX(x)={Pr(X=x),0,x∈Sx∈R∖S 注意这在所有实数上,包括那些X 不可能等于的实数值上,都定义了pmf,只不过在这些X 不可能取的实数值上,fX(x) 取值为0(x∈R∖S,Pr(X=x)=0 )。 离散型随机变量概率质量函数(pmf)的不连续性决定了其累积分布函数(cdf)也不连续。 共轭先验(conjugate prior) 所谓共轭(conjugate),描述刻画的是两者之间的关系,单独的事物不构成共轭,举个通俗的例子,兄弟这一概念,只能是两者才能构成兄弟。所以,我们讲这两个人是兄弟关系,A是B的兄弟,这两个分布成共轭分布关系,A是B的共轭分布。 p(θ|X)=p(θ)p(X|θ)p(x) p(X|θ) :似然(likelihood) p(θ) :先验(prior) p(X) :归一化常数(normalizing constant) 我们定义:如果先验分布(p(θ) )和似然函数(p(X|θ) )可以使得先验分布(p(θ) )和后验分布(p(θ|X) )有相同的形式(如,Beta(a+k, b+n-k)=Beta(a, b)binom(n, k)),那么就称先验分布与似然函数是共轭的(成Beta分布与二项分布是共轭的)。 几个常见的先验分布与其共轭分布 先验分布 共轭分布 伯努利分布 beta distribution Multinomial Dirichlet Distribution Gaussian, Given variance, mean unknown Gaussian Distribution Gaussian, Given mean, variance unknown Gamma Distribution Gaussian, both mean and variance unknown Gaussian-Gamma Distribution 最大似然估计(MLE) 首先来看,大名鼎鼎的贝叶斯公式: p(θ|X)=p(θ)p(X|θ)p(X) 可将θ 看成欲估计的分布的参数,X 表示样本,p(X|θ) 则表示似然。 现给定样本集\mathcal{D}=\{x_1,x_2,\ldots,x_N\}D={x1,x2,…,xN} ,似然函数为: p(\mathcal{D}|\theta)=\prod_{n=1}^Np(x_n|\theta) p(D|θ)=∏n=1Np(xn|θ) 为便于计算,再将其转换为对数似然函数形式: \ln p(\mathcal{D}|\theta)=\sum_{n=1}^N\ln p(x_n|\theta) lnp(D|θ)=∑n=1Nlnp(xn|θ) 我们不妨以伯努利分布为例,利用最大似然估计的方式计算其分布的参数(pp ),伯努利分布其概率密度函数(pdf)为: f_X(x)=p^x(1-p)^{1-x}=\left \{ \begin{array}{ll} p,&\mathrm{x=1},\\ q\equiv1-p ,&\mathrm{x=0},\\ 0,&\mathrm{otherwise} \end{array} \right. fX(x)=px(1−p)1−x=⎧⎩⎨⎪⎪p,q≡1−p,0,x=1,x=0,otherwise 整个样本集的对数似然函数为: \ln p(\mathcal{D}|\theta)=\sum_{n=1}^N\ln p(x_n|\theta)=\sum_{n=1}^N\ln (\theta^{x_n}(1-\theta)^{1-x_n})=\sum_{n=1}^Nx_n\ln\theta+(1-x_n)\ln(1-\theta) lnp(D|θ)=∑n=1Nlnp(xn|θ)=∑n=1Nln(θxn(1−θ)1−xn)=∑n=1Nxnlnθ+(1−xn)ln(1−θ) 等式两边对\thetaθ 求导: \frac{\partial \ln(\mathcal{D}|\theta)}{\partial \theta}=\frac{\sum_{n=1}^Nx_n}{\theta}-\frac{N}{1-\theta}+\frac{\sum_{n=1}^Nx_n}{1-\theta} ∂ln(D|θ)∂θ=∑Nn=1xnθ−N1−θ+∑Nn=1xn1−θ 令其为0,得: θml=∑Nn=1xnN Beta分布 f(μ|a,b)=Γ(a+b)Γ(a)Γ(b)μa−1(1−μ)b−1=1B(a,b)μa−1(1−μ)b−1 Beta 分布的峰值在a−1b+a−2 处取得。其中Γ(x)≡∫∞0ux−1e−udu 有如下性质: Γ(x+1)=xΓ(x)Γ(1)=1andΓ(n+1)=n! 我们来看当先验分布为 Beta 分布时的后验分布: p(θ)=1B(a,b)θa−1(1−θ)b−1p(X|θ)=(nk)θk(1−θ)n−kp(θ|X)=1B(a+k,b+n−k)θa+k−1(1−θ)b+n−k−1 对应于python中的math.gamma()及matlab中的gamma()函数(matlab中beta(a, b)=gamma(a)gamma(b)/gamma(a+b))。 条件概率(conditional probability) P(X|Y) 读作: P of X given Y ,下划线读作given X :所关心事件 Y :条件(观察到的,已发生的事件),conditional 条件概率的计算 仍然从样本空间(sample space)的角度出发。此时我们需要定义新的样本空间(给定条件之下的样本空间)。所以,所谓条件(conditional),本质是对样本空间的进一步收缩,或者叫求其子空间。 比如一个人答题,有A,B,C,D 四个选项,在答题者对题目一无所知的情况下,他答对的概率自然就是 14 ,而是如果具备一定的知识,排除了 A,C 两个错误选项,此时他答对的概率简单计算就增加到了 12 。 本质是样本空间从S={A,B,C,D} ,变为了S′={B,D} 。 新样本空间下P(A|排除A/C)=0,P(C|排除A/C)=0 ,归纳出来,也即某实验结果(outcome,oi )与某条件Y 不相交,则: P(oi|Y)=0 最后我们得到条件概率的计算公式: P(oi|Y)=P(oi)P(o1)+P(o2)+⋯+P(on)=P(oi)P(Y)Y={o1,o2,…,on} 考虑某事件X={o1,o2,q1,q2} ,已知条件Y={o1,o2,o3} 发生了,则: P(X|Y)=P(o1|Y)+P(o2|Y)+0+0=P(o1)P(Y)+P(o2)P(Y)=P(X∩Y)P(Y) 条件概率与贝叶斯公式 条件概率: P(X|Y)=P(X∩Y)P(Y) 贝叶斯公式: P(X|Y)=P(X)P(Y|X)P(Y) 其实是可从条件概率推导贝叶斯公式的: P(A|B)=P(B|A)=P(A|B)P(B)===P(B|A)=P(A∩B)P(B)P(A∩B)P(A)P(A∩B)P(B)P(B)P(A∩B)P(A)P(B|A)P(A|B)P(B)P(A) 证明:P(B,p|D)=P(B|p,D)P(p|D) P(B,p|D)====P(B,p,D)P(D)P(B|p,D)P(p,D)P(D)P(B|p,D)P(p,D)P(D)P(B|p,D)P(p|D) References [1] 概率质量函数 本篇文章为转载内容。原文链接:https://blog.csdn.net/lanchunhui/article/details/49799405。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-02-26 12:45:04
518
转载
MySQL
...分类,例如商品分类、用户等级等。其中,无限极分类是一种非常常用的数据分类方式,它可以用来表示一种层次结构,如商品分类中的父类、子类等。然而,在处理这种数据时,我们常常会遇到一个问题:如何快速、有效地将无限极分类转换为层级结构呢? 二、为什么要使用无限极分类? 首先,我们需要了解一下什么是无限极分类。无限极分类就像一棵大树,它的构造挺有趣。在这样的树形结构中,每一个小节点都有一个自己的‘老爹’节点,而这个‘老爹’呢,它还可能是其他许多小节点的‘老爹’。这样的构造方式,其实就像家谱一样,可以展示出各种级别的层次关系。比如说在商品分类里,就有爷爷辈的大类别、爸爸辈的中类别、儿子辈的小类别,甚至还有孙子辈的更细分的类别呢! 其次,无限极分类的优点在于它可以方便地进行扩展。假如我们想要新增一个类别,就像在家族树上添个新枝丫一样简单,你只需要在它的“老爸”类别下加一个新的“小子类别”,这样一来,数据的一致性和完整性就能轻轻松松地保持住啦! 三、什么是递归? 那么,如何使用递归来处理无限极分类呢?这就需要用到递归的概念。递归啊,就是那种函数自己调用自己的神奇操作。你想象一下,这个函数有点像一个超级有耐心的小助手,一遍又一遍地做着同一件事情,但每次做的时候都比上次更进一步。通过这种自我迭代的过程,我们竟然能解开很多看起来超级复杂、让人挠头的问题呢! 在处理无限极分类时,我们可以使用递归的方式,从根节点开始,一层一层地遍历下去,直到找到所有的叶子节点。然后,我们可以根据每层的节点,构建出相应的层级结构。 四、如何使用递归来处理无限极分类? 接下来,我们来看一下如何使用递归来处理无限极分类。假设我们有一个无限极分类的数据库表,其中包含id、parent_id和name三个字段。喏,你听我说哈,id呢,就相当于每个小节点的身份证号,是独一无二的。而parent_id呢,顾名思义,就是每个小节点它爹——父节点的身份证号啦。至于name嘛,简单易懂,那就是给每个小节点起的专属昵称哈! 我们可以定义一个函数,输入参数是一个父节点的id,输出是一个层级结构的数组。具体操作如下: php function getTree($id){ $sql = "SELECT FROM node WHERE parent_id = '$id'"; $result = mysqli_query($conn, $sql); $arr = array(); while($row = mysqli_fetch_assoc($result)){ $arr[] = $row; } foreach($arr as $value){ if($value['child'] > 0){ $arr = array_merge($arr, getTree($value['id'])); } } return $arr; } 以上就是使用递归来处理无限极分类的一个简单示例。这个例子嘛,我们先从某个特定的老爸节点下手,把它的所有小崽子(子节点)都给挖出来。接着呢,对每一个小崽子,如果它们自己还有更下一代的小崽子,那我们就得像孙悟空钻进葫芦娃的肚子里那样,一层层地往里递归调用这个过程,把那些隐藏更深的孙子辈节点也给找全了。最后呢,咱们把这一大家子所有的节点都聚到一块儿,拼成一个完整的、层层分明的家族结构。 然而,递归虽然强大,但也有它的局限性。当数据量大时,递归可能会导致栈溢出,影响程序的执行效率。因此,我们需要寻找其他的解决方案。 五、不使用递归,如何处理无限极分类? 那么,如果不使用递归,我们该如何处理无限极分类呢?答案就是使用非递归的方式,也就是我们常说的迭代法。 迭代法的基本思想是从根节点开始,每次只处理一层数据,直到处理完所有的数据。这种方法压根儿不需要递归调用,所以你完全不用担心什么栈溢出的问题。而且实话跟你说,通常情况下,它的工作效率要比递归高不少! 接下来,我们来看一下如何使用迭代法处理无限极分类。假设我们已经有了一个无限极分类的数据库表,其中包含id、parent_id和name三个字段。我们可以按照以下步骤进行处理: 1. 创建一个空的层级结构数组,用于存储所有的节点; 2. 获取根节点,将其添加到层级结构数组中; 3. 遍历所有的节点,对于每一个节点,如果它还没有被处理过,则对其进行处理,将其添加到层级结构数组中,然后处理它的所有子节点。 具体的代码实现如下: php function getTree($root){ $tree = array(); $queue = array($root); while(count($queue) > 0){ $node = array_shift($queue); $tree[$node['id']] = array( 'id' => $node['id'], 'parent_id' => $node['parent_id'], 'name' => $node['name'], 'children' => array() ); if($node['child'] > 0){ $queue = array_merge($queue, getChildren($conn, $node['id'])); } } return $tree; } function getChildren($conn, $id){ $sql = "SELECT FROM node WHERE parent_id = '$id'"; $result = mysqli_query($conn, $sql); $arr = array(); while($row = mysqli_fetch_assoc($result)){ $arr[] = $row; } return $arr; } 以上就是在非递归的情况下,处理无限极分类的一个简单示例。在举这个例子的时候,我们首先动手整了个空荡荡的层级结构数组出来,接着找准了那个根节点,把它给塞进了这个层级结构数组里头。然后,我们就像在超市排队结账一样,用一个队列来装那些等待被处理的节点。每当轮到一个节点时,我们就把它从队列里拽出来,塞进层级结构数组这个大篮子里,并且仔仔细细地处理它所有的“孩子”——也就是子节点。最后一步,咱们就像玩接龙游戏一样,把已经处理过的节点从队列里拿出来,然后美滋滋地接着处理下一个排着队的节点,就这么一直玩下去,直到队列里一个节点都不剩,就表示大功告成了! 总结来说,无论是使用递归还是非递归,都可以有效地处理无限极分类。但是,不同的方法适用于不同的场景,我们需要根据实际情况选择合适的方法。
2023-08-24 16:14:06
59
星河万里_t
转载文章
...28。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 一、配置文件 几乎所有的前端工程师都知道可以用babel将es6+的语法转换为es5,转换工具要么使用babel-cli,要么使用webpack的babel-loader,不管使用哪种转换工具,通常都需要一个配置文件来建立转换规则(也可以在webpack的babel-loader的配置项,原理都一样)。 babel执行时默认从当前目录查找配置文件,支持的配置文件格式有:.babelrc,.babelrc.js,babel.config.js和package.json。它们的配置项都是相同,作用也是一样的,只需要选择其中一种,推荐使用.js结尾的文件,这样可以在配置文件中进行编程控制,如下: module.exports = function (api) {api.cache(true);const presets = [ ... ];const plugins = [ ... ];return {presets,plugins};} 也可以直接使用module.exports = {},没有必要一定是一个function。 在编写配置文件中,最主要的就是设置plugins(插件)和presets(预设),每个插件或预设都是一个npm包,插件和预设会在编译过程中把我们的ES6+代码转换成ES5。 二、插件和预设的关系 babel中的插件太多,以es2015为例: @babel/plugin-transform-arrow-functions @babel/plugin-transform-block-scoped-functions @babel/plugin-transform-block-scoping .... 如果只采用插件的话,我们需要配置非常多的插件数组,如果项目使用了es2016又得增加一堆,而且我们压根也记不住哪个es版本里该使用哪些插件。 preset就是解决这个问题的,它是一系列插件的集合,以@babel/preset-env为例,假设项目中安装的npm包版本是2020年1月发布的,那么这个预设里包含了2020年1月以前所有进入到stage4阶段的语法转换插件。 可能有小伙伴会问,假如我设置了一个语法插件,指定某个预设里又包含了插件,此时会发生什么?这就涉及到插件和预设的执行顺序了,具体的规则如下: 插件比预设先执行 插件执行顺序是插件数组从前向后执行 预设执行顺序是预设数组从后向前执行 三、插件和预设的参数 不配置参数的情况下,每个插件或预设都是数组中的一个字符串成员,例:preset:["@babel/preset-env","@babel/preset-react"],如果某个插件或预设需要配置参数,成员项就需要由字符串换成一个数组,数组的第一项是插件或预设的名称字符串,第二项为对象,该对象用来设置插件或预设的参数,格式如下: {"presets": [["@babel/preset-env",{"useBuiltIns": "entry"}]]} 四、插件和预设的简写 插件或可以在配置文件里用简写名称,如果插件的npm包名称的前缀为 babel-plugin-,可以省略前缀。例如"plugins": ["babel-plugin-transform-decorators-legacy"]可以简写为"plugins": ["transform-decorators-legacy"]。 如果npm包名称的前缀带有作用域@,例如@scope/babel-plugin-xxx,短名称可以写成@scope/xxx。 到babel7版本时,官方的插件大多采用@babel/plugin-xxx格式的,没有明确说明是否可以省略@babel/plugin-,遇到这中npm包时,最好还是采用全称写法比较稳妥。 预设的短名称规则跟插件差不多,前缀为babel-preset-或带有作用域的包@scope/babel-preset-xxx的可以省略掉babel-preset-。 babel7里@babel/preset-前缀开头的包,例如@babel/preset-env的短名称是@babel/env,官方并没有给出明确说明以@babel/preset-xxx卡头的包是否都可以采用简写,因此最好还是采用全称。 五、混乱的babel6预设 如果直接接触babel7的前端同事都知道es预设直接用@babel/preset-env就行了,但是如果要维护和迭代基于babel6的项目呢?各个项目中使用的可能都不一样,babel-preset-es20xx、babel-preset-stage-x、babel-preset-latest这些预设是啥意思? babel-preset-es20xx: TC39每年发布的、进入标准的ES语法转换器预设,最后一个预设是babel-preset-es2017,不再更新。 babel-preset-stage-x: TC39每年草案阶段的ES语法转换器预设。x的值是0到3,babel7时已废弃,不再更新。 babel-preset-latest: TC39每年发布的、进入标准的ES语法转换器预设。在babel6时等于babel-preset-es2015、babel-preset-es2016、babel-preset-es2017。该包从 v2 开始,需要@babel/core@^7.0.0,也就是需要babel7才能使用,既然要升级到babel7,不如使用更加强大的@babel/preset-env。 本篇文章为转载内容。原文链接:https://blog.csdn.net/douyinbuwen/article/details/123729828。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-01-16 22:15:54
122
转载
Saiku
... 一、直观性挑战 从用户反馈中窥探 用户反馈显示,Saiku配置文件编辑器的界面设计相对传统,对于非技术背景的用户来说,理解其工作原理和操作逻辑较为困难。主要体现在以下几个方面: - 术语晦涩:专业术语如“维度”、“度量”等在初次接触时难以理解。 - 布局混乱:界面元素分布缺乏逻辑性,导致用户在寻找特定功能时费时费力。 - 信息密度高:大量的配置选项集中在一个页面上,容易造成视觉疲劳,降低操作效率。 二、案例分析 以“时间序列分析”为例 假设我们正在为一家零售公司构建一个销售趋势分析仪表板,需要配置时间序列数据进行展示。在Saiku配置文件编辑器中,用户可能首先会面临以下挑战: 1. 选择维度与度量 - 用户可能不清楚如何在众多维度(如产品类别、地区、时间)和度量(如销售额、数量)中做出最佳选择来反映他们的分析需求。 - 缺乏直观的提示或预览功能,使得用户难以预见到不同选择的最终效果。 2. 配置时间序列 - 在配置时间序列时,用户可能会遇到如何正确设置时间粒度(如日、周、月)以及如何处理缺失数据的问题。 - 缺乏可视化的指导,使得用户在调整时间序列设置时感到迷茫。 三、改进建议 增强直观性和用户友好性 针对上述挑战,我们可以从以下几个方面着手改进Saiku配置文件编辑器: 1. 简化术语 引入更易于理解的语言替换专业术语,例如将“维度”改为“视角”,“度量”改为“指标”。 2. 优化布局与导航 采用更加清晰的分层结构,将相关功能模块放置在一起,减少跳转次数。同时,增加搜索功能,让用户能够快速定位到需要的配置项。 3. 提供可视化预览 在用户进行配置时,实时展示配置结果的预览图,帮助用户直观地理解设置的效果。 4. 引入动态示例 在配置页面中嵌入动态示例,通过实际数据展示不同的配置效果,让用户在操作过程中学习和适应。 5. 增加教程与资源 开发一系列针对不同技能水平用户的教程视频、指南和在线问答社区,帮助用户更快掌握Saiku的使用技巧。 四、结语 从实践到反馈的闭环 改进Saiku配置文件编辑器的直观性是一个持续的过程,需要结合用户反馈不断迭代优化。哎呀,听我说啊,要是咱们按照这些建议去操作,嘿,那可是能大大提升大家用咱们Saiku的体验感!这样一来,不光能让更多的人知道并爱上Saiku,还能让数据分析这块儿的整体发展更上一层楼呢!你懂我的意思吧?就像是给整个行业都添了把火,让数据这事儿变得更热乎,更受欢迎!哎呀,兄弟!在咱们这项目推进的过程中,得保持跟用户之间的交流超级通畅,听听他们在使用咱们产品时遇到的具体难题,还有他们的一些建议。这样咱们才能对症下药,确保咱们改进的措施不是空洞的理论,而是真正能解决实际问题,让大家都满意的好办法。毕竟,用户的反馈可是我们优化产品的大金矿呢! --- 通过这次深入探讨,我们不仅认识到Saiku配置文件编辑器在直观性上的挑战,也找到了相应的解决路径。哎呀,希望Saiku在将来能给咱们的数据分析师们打造一个既温馨又高效的工具平台,就像家里那台超级好用的咖啡机,让人一上手就爱不释手。这样一来,大家就能专心挖出数据背后隐藏的金矿,而不是老是跟那些烦人的技术小难题过不去,对吧?
2024-10-12 16:22:48
74
春暖花开
Apache Lucene
...的性能和灵活性成为了用户体验的关键因素之一。Apache Lucene,作为一款强大的全文搜索库,为我们提供了丰富的查询选项,其中之一就是FuzzyQuery,它允许我们在搜索时处理模糊匹配,即使用户输入的关键词可能不完全精确。今天,我们将深入剖析如何在实际项目中利用FuzzyQuery,让搜索体验更加人性化。 二、什么是FuzzyQuery 1. 概念解析 FuzzyQuery是Lucene中用于执行模糊搜索的核心工具,它通过计算查询词与索引中的单词之间的Levenshtein距离(也称编辑距离),找到那些相似度超过预设阈值的文档。你知道吗,编辑距离这玩意儿就像个搞笑的测谎游戏,它比量两个词串之间的亲密度,简单说就是,你要么得添字、减字或者动动手脚换个别字,最少几次才能让这两个词串变成亲兄弟一样挨着。 三、FuzzyQuery的使用示例 2. 编码实现 以下是一个简单的Java代码片段,展示了如何使用FuzzyQuery进行模糊搜索: java import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.TextField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; public class FuzzySearchExample { public static void main(String[] args) throws Exception { Directory indexDir = new RAMDirectory(); // 创建内存索引 Analyzer analyzer = new StandardAnalyzer(); // 使用标准分析器 // 假设我们有一个文档集合,这里只创建一个简单的文档 Document doc = new Document(); doc.add(new TextField("content", "Lucene is awesome", Field.Store.YES)); IndexWriterConfig config = new IndexWriterConfig(analyzer); IndexWriter writer = new IndexWriter(indexDir, config); writer.addDocument(doc); writer.close(); String queryTerm = "Lucenes"; // 用户输入的模糊查询词 float fuzziness = 1f; // 设置模糊度,例如1代表允许一个字符的差异 QueryParser parser = new QueryParser("content", analyzer); FuzzyQuery fuzzyQuery = new FuzzyQuery(parser.parse(queryTerm), fuzziness); IndexReader reader = DirectoryReader.open(indexDir); TopDocs topDocs = searcher.search(fuzzyQuery, 10); // 返回最多10个匹配结果 for (ScoreDoc scoreDoc : topDocs.scoreDocs) { Document hitDoc = searcher.doc(scoreDoc.doc); System.out.println("Score: " + scoreDoc.score + ", Hit: " + hitDoc.get("content")); } reader.close(); } } 这段代码首先创建了一个简单的索引,然后构造了一个FuzzyQuery实例,指定要搜索的关键词和允许的最大编辑距离。搜索时,我们能看到即使用户输入的不是完全匹配的"Lucene",而是"Lucenes",FuzzyQuery也能返回相关的结果。 四、FuzzyQuery优化策略 3. 性能与优化 当处理大量数据时,FuzzyQuery可能会变得较慢,因为它的计算复杂度与搜索词的长度和索引的大小有关。为了提高效率,可以考虑以下策略: - 前缀匹配:使用PrefixQuery结合FuzzyQuery,仅搜索具有相同前缀的文档,这可以减少搜索范围。 - 阈值调整:根据应用需求调整模糊度阈值,更严格的阈值可以提高精确度,但搜索速度会下降。 - 分批处理:如果搜索结果过多,可以分批处理,先缩小范围,再逐步细化。 五、结论 4. 未来展望与总结 FuzzyQuery在提高搜索灵活性的同时,也对性能提出了挑战。要想在项目里游刃有余,得深入理解那些神奇的机制和巧妙的策略,这样才能精准又高效,就像个武林高手一样,既能一击即中,又能快如闪电。Lucene那强大的模糊搜索绝不仅仅是纠错能手,它还能在你打字时瞬间给出超贴心的拼写建议,让找东西变得超级简单,简直提升了搜寻乐趣好几倍!随着科技日新月异,Lucene这家伙也越变越聪明,咱们可真盼着瞧见那些超酷的新搜索招数,让找东西这事变得更聪明又快捷,就像点穴一样精准! 在构建现代应用程序时,了解并善用这些高级查询工具,无疑会让我们的搜索引擎更具竞争力。希望这个简单示例能帮助你开始在项目中运用FuzzyQuery,提升搜索的精准度和易用性。
2024-06-11 10:54:39
498
时光倒流
ZooKeeper
一、 引言 动物园管理员 ZooKeeper(ZK),作为开源分布式协调服务,自2006年发布以来凭借其高效可靠的特性在全球范围内得到了广泛应用,尤其是在大规模分布式系统如Hadoop、Spark等中的任务调度、数据存储与一致性保证等方面发挥着关键作用。其实,ZooKeeper的成功绝不是天上掉馅饼的事儿,它的设计理念里头藏着不少既巧妙又接地气的“小秘密”,正是这些实实在在的原则,像支柱一样撑起了一个无比强大的分布式协作系统。接下来,我们将深入剖析ZooKeeper的设计原则,并结合实际代码示例进行解读。 二、ZooKeeper 设计原则概览 1. 顺序一致性 (Linearizability) - 理解:ZooKeeper保证所有的更新操作遵循严格的顺序性,即看起来就像在单个进程上执行一样,这对于分布式环境下的事务处理至关重要。这意味着无论网络延迟如何变化,客户端收到的数据总是按照创建或者更新的顺序排列。 - 代码示例: java // 创建节点 Stat createdStat = zk.create("/my/znode", "initial data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); // 更新节点 byte[] updatedData = "updated content".getBytes(); zk.setData("/my/znode", updatedData, -1); - 思考:如果两个客户端同时尝试创建同一个路径的节点,ZooKeeper会确保先创建的请求成功返回,后续的请求则等待并获得正确的顺序响应。 2. 最终一致性 (Eventual Consistency) - 理解:虽然ZooKeeper提供强一致性,但在高可用场景下,为了容忍临时网络分区和部分节点故障,它采用了一种最终一致性模型。客户端不会傻傻地卡在等待一个还没完成的更新上,而是能够继续干自己的活儿。等到网络恢复了,或者那个闹别扭的节点修好了,ZooKeeper这个小管家就会出马,保证所有客户端都能看到一模一样的最终结果,没得商量! - 代码示例: 当一个客户端尝试更新一个已有的zNode,ZooKeeper会为此次更新生成一个事务zxid(Transaction ID)。即使中途网络突然抽风一下断开了,别担心,一旦网络重新连上,客户端就会收到一条带着新zxid的更新消息,这就表示这个事务已经妥妥地完成提交啦! java try { zk.exists("/my/znode", false); // check if zNode exists zk.setData("/my/znode", updatedData, -1); // update data with new transaction id } catch ( KeeperException.NoNodeException e) { System.out.println("ZNode doesn't exist yet"); } 3. 可观察性 (Observability) - 理解:ZooKeeper设计的核心在于使客户端能够感知服务器状态的变化,它通过Watcher监听机制让客户端在节点发生创建、删除、数据变更等事件后得到通知,从而保持客户端与ZooKeeper集群的同步。 - 代码示例: java // 注册一个节点变更的监听器 Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { switch (event.getType()) { case NodeDeleted: System.out.println("ZNode deleted: " + event.getPath()); break; case NodeCreated: System.out.println("New ZNode created: " + event.getPath()); break; // ... other cases for updated or child events } }; }; zk.getData("/my/znode", false, watcher); 三、ZooKeeper设计原则的实际应用与影响 综上所述,顺序一致性提供了数据操作的可靠性,最终一致性则兼顾了系统的容错性和可扩展性,而可观测性则是ZooKeeper支持分布式协调的关键特征。这三大原则,不仅在很大程度上决定了ZooKeeper自身的行为习惯和整体架构,还实实在在地重塑了我们开发分布式应用的方式。比如说,在搭建分布式锁、配置中心或者进行分布式服务注册与发现这些常见应用场景时,开发者能够直接借用ZooKeeper提供的API和设计思路,轻而易举地打造出高效又稳定的解决方案,就像是在玩乐高积木一样,把不同的模块拼接起来,构建出强大的系统。 结论 随着云计算时代的到来,大规模分布式系统对于一致性和可靠性的需求愈发凸显,ZooKeeper正是在这个背景下诞生并不断演进的一颗璀璨明星。真正摸透并灵活运用ZooKeeper的设计精髓,那咱们就仿佛掌握了在分布式世界里驰骋的秘诀,能够随心所欲地打造出既稳如磐石又性能超群的分布式应用。
2024-02-15 10:59:33
34
人生如戏-t
转载文章
...54。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 本文将以Java为基础,讲解开发中,面向接口编程的知识,只要以简单的例子为主,讲解如何进行面向接口编程,并会区分其于面向实现编程的区别。下面先讲一讲依赖倒置原则,再过渡到案例解释。 本文目的在于用极其简单的图解帮助新手来简单的理解面向接口开发,并不会提出很高深的理论支持来描述。 文章若有错误的内容,希望大佬指正 依赖倒置原则 什么是依赖倒置原则: 高层模块不应该依赖低层模块,二者都应该依赖其抽象 抽象不应该依赖细节,细节应该依赖抽象 针对接口编程,不要针对实现编程 即: 每个类尽量继承自接口或者抽象类 优点:减少类之间的耦合,提高代码的稳定性,代码的可读性维护性。 案例: 背景: 现在有一个用户类叫Ggzx(也就是我),想要学习一些课程,简单的来实现调用学习的方法,然后在一个Test类之中输入学习的内容。但是我暂时只学java和web,但是可能我后面还要学习Spring,SpringMVC… 1.面向实现编程 public class Ggzx {public void stduyJava(){System.out.println("学习了java课程");}public void studyWeb(){System.out.println("学习了Web课程");} } public class Test {public static void main(String[] args) {Ggzx ggzx=new Ggzx();ggzx.studyJava();ggzx.studyPython();ggzx.studyGo();} } 分析: 上面使用的面向实现编程,但是Test作为我们控制的"应用层",也就是高层,而Ggzx作为低层,其实这样在比较简单的例子中,其实是没问题的,因为假如不需要扩展,仅仅是实现两个很简单的功能,并没有必要去面向接口开发,但是一般在开发中通常有很复杂的开发环境和开发需求。 现在如果想添加新的功能,学习其他的课程,怎么办??? 继续使用面向实现编程,直接在 Ggzx 类中直接添加新的方法,可以完成这个功能需求。 用上面的方法实现有没有缺点??? 学习的课程和 Ggzx 类耦合比较严重。是学习的课程只能通过Ggzx 才能得到 。并且是想要学习新的课程也要在 Ggzx 类中不断添加和修改 —>高耦合 Ggzx 作为当前 demo 的底层,经常的被改动,高层Test依赖于低层 Ggzx 的实现 ---->对应依赖倒置原则中的:高层过度依赖低层了 2.面向接口编程(简单版) 为了解决上面出现的问题,我们可以考虑把学习的课程抽出来成为一个类。到现在,类和类之间的耦合其实就已经降低很多了。然后将其当做参数传入Ggzx里面,然后调用课程里面的学习方法 //web课程类public class WebCourse {public void studyCourse() {System.out.println("学习了Web课程");} } //这里是Java课程类public class JavaCourse {public void studyCourse() {System.out.println("学习Java课程");} } 当我们写出来这两个类,想要对Ggzx里面的学习方法进行编写的时候,有没有发现其实有一些小问题呢???? Ggzx里面接收这些类的参数是什么?? 难道要这样? //以下是Ggzx类中的内容public void studyJava(JavaCourse javaCourse){}public void studyWeb(WebCourse webCourse){} nonono,如果这样做,虽然当前已经把课程类和 Ggzx 用户剥离一点点了,但是是还是形同虚设,课程类虽然分离开了,但是还是像狗皮膏药一样贴在 Ggzx 类中,但是看着还是很难受,高层 Test 调用方法还是得依赖 Ggzx 里面有什么方法 每次加入新课程,都需要修改底层功能 如何修改??? 接口是个好东西,课程类之间是不是都包含同样一个方法,被学习的方法( studyCourse ),那么我们可以将所有课程类都实现一个ICourse课程! 对应上面的问题,我们该传入什么参数能解决问题??可以传入一个接口 改编后的 UML 图解展示(Ggzx 被废弃,用新的 NewGgzx 代替):(如果没了解过UML类图,或者是纯小白,只需要知道一个大框是一个类,虚线表示实现了箭头方向的接口,小m是方法 即可) 观察上面的UML图 WebCourse 和 JavaCourse 实现自同一个接口 ICourse,每个课程都有自己的 studyXxx 方法。 这样好在什么地方? - 课程类和Ggzx类是解耦的,无论你增加多少个课程类,只要实现了ICourse接口,都能直接传入Ggzx的studyMyCourse()方法中 public interface ICourse {void studyCourse();} public class WebCourse implements ICourse{@Overridepublic void studyCourse() {System.out.println("学习了Web课程");} } public class NewGgzx {public void studyMyCourse(ICourse iCourse){iCourse.studyCourse();} } 上面就是案例的面向接口编程,我们可以看到,在 NewGgzx 类中,我们可以传入一个实现 ICourse 接口的课程类,我们在Test类中调用的时候,只需要传入一个课程类即可调用学习方法,这样当想扩展新的内容,只需要创建一个新的课程类实现 ICourse 即可 Test使用 NewGgzx newGgzx =new NewGgzx();newGgzx.studyMoocCourse(new WebCourse());newGgzx.studyMoocCourse(new com.ggzx.design.priciple.dependenceiversion.JavaCourse()); 从面向实现到面向接口,我们处理问题的方法改变了: 开始时,我们需要考虑在Test类中调用Ggzx里面的哪一种学习方法,即注重调用什么方法能够实现特定的课程 到面向接口编程,我们考虑传入什么课程即可实现学习 当业务需求拓展时,拓展方法也改变了: 面向实现:需要改变底层的代码来协调我们需要使用的功能,用上面的例子来解释就是:当你想要学习一个课程,你就需要改变你底层的实现,增加新的代码 面向接口:想学习什么课程,不会对其他课程造成影响,也不会影响到低层的Ggzx 。实际操作就是增加一门新的课程即可,实现接口之后,传入这个类到Ggzx的方法中就可以学习这一门课了 相对于细节的多变性,抽象的东西更稳定,以抽象为基础搭建的架构比以细节搭建的架构更加稳定 本篇文章为转载内容。原文链接:https://blog.csdn.net/m0_52410356/article/details/122828154。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-08-26 15:35:43
634
转载
转载文章
...16。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 前言 Neighbor2Neighbor属于自监督去噪中算法,通过训练后可以对任意尺寸的图像进行去噪,现在对去噪代码中如何实现任意尺寸图像去噪进行解读。 代码 先贴源码 import torchfrom PIL import Imagefrom torchvision import transformsfrom arch_unet import UNetimport numpy as npdef get_generator():global operation_seed_counter 全局变量 在局部变量可以引用全局变量并修改operation_seed_counter += 1g_cuda_generator = torch.Generator(device="cuda")g_cuda_generator.manual_seed(operation_seed_counter)return g_cuda_generatorclass AugmentNoise(object): 添加噪声的类def __init__(self, style):print(style)if style.startswith('gauss'):self.params = [float(p) / 255.0 for p in style.replace('gauss', '').split('_')]if len(self.params) == 1:self.style = "gauss_fix"elif len(self.params) == 2:self.style = "gauss_range"elif style.startswith('poisson'):self.params = [float(p) for p in style.replace('poisson', '').split('_')]if len(self.params) == 1:self.style = "poisson_fix"elif len(self.params) == 2:self.style = "poisson_range"def add_train_noise(self, x):shape = x.shapeif self.style == "gauss_fix":std = self.params[0]std = std torch.ones((shape[0], 1, 1, 1), device=x.device)noise = torch.cuda.FloatTensor(shape, device=x.device)torch.normal(mean=0.0,std=std,generator=get_generator(),out=noise)return x + noiseelif self.style == "gauss_range":min_std, max_std = self.paramsstd = torch.rand(size=(shape[0], 1, 1, 1),device=x.device) (max_std - min_std) + min_stdnoise = torch.cuda.FloatTensor(shape, device=x.device)torch.normal(mean=0, std=std, generator=get_generator(), out=noise)return x + noiseelif self.style == "poisson_fix":lam = self.params[0]lam = lam torch.ones((shape[0], 1, 1, 1), device=x.device)noised = torch.poisson(lam x, generator=get_generator()) / lamreturn noisedelif self.style == "poisson_range":min_lam, max_lam = self.paramslam = torch.rand(size=(shape[0], 1, 1, 1),device=x.device) (max_lam - min_lam) + min_lamnoised = torch.poisson(lam x, generator=get_generator()) / lamreturn noiseddef add_valid_noise(self, x):shape = x.shapeif self.style == "gauss_fix":std = self.params[0]return np.array(x + np.random.normal(size=shape) std,dtype=np.float32)elif self.style == "gauss_range":min_std, max_std = self.paramsstd = np.random.uniform(low=min_std, high=max_std, size=(1, 1, 1))return np.array(x + np.random.normal(size=shape) std,dtype=np.float32)elif self.style == "poisson_fix":lam = self.params[0]return np.array(np.random.poisson(lam x) / lam, dtype=np.float32)elif self.style == "poisson_range":min_lam, max_lam = self.paramslam = np.random.uniform(low=min_lam, high=max_lam, size=(1, 1, 1))return np.array(np.random.poisson(lam x) / lam, dtype=np.float32)model_path = 'test_dir/unet_gauss25_b4e100r02/2022-03-02-22-24/epoch_model_040.pth' 导入训练的模型文件device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')net = UNet().to(device)net.load_state_dict(torch.load(model_path, map_location=device))net.eval()noise_adder = AugmentNoise(style='gauss25')img = Image.open('validation/Kodak/000014.jpg')im = np.array(img, dtype=np.float32) / 255.0origin255 = im.copy()origin255 = origin255.astype(np.uint8)noisy_im = noise_adder.add_valid_noise(im)H = noisy_im.shape[0]W = noisy_im.shape[1]val_size = (max(H, W) + 31) // 32 32noisy_im = np.pad(noisy_im,[[0, val_size - H], [0, val_size - W], [0, 0]],'reflect')transformer = transforms.Compose([transforms.ToTensor()])noisy_im = transformer(noisy_im)noisy_im = torch.unsqueeze(noisy_im, 0)noisy_im = noisy_im.cuda()with torch.no_grad():prediction = net(noisy_im)prediction = prediction[:, :, :H, :W]prediction = prediction.permute(0, 2, 3, 1)prediction = prediction.cpu().data.clamp(0, 1).numpy()prediction = prediction.squeeze()pred255 = np.clip(prediction 255.0 + 0.5, 0, 255).astype(np.uint8)Image.fromarray(pred255).convert('RGB').save('test1.png') 输入图像 尺寸大小为(408, 310),PIL读入后进行归一化处理。 img = Image.open('validation/Kodak/00001.jpg')print('img', img.size) img (408, 310)im = np.array(img, dtype=np.float32) / 255.0print('im', im.shape) im (310, 408, 3) 先对不规则图像进行填充,要求填充的尺寸是32的倍数,否则输入到网络中会报错。在训练的时候是随机裁剪256256的切片的。 b = torch.rand(1, 3, 255, 255).to('cuda')a = net(b)print(a.shape) 在卷积神经网络中,为了避免因为卷积运算导致输出图像缩小和图像边缘信息丢失,常常采用图像边缘填充技术,即在图像四周边缘填充0,使得卷积运算后图像大小不会缩小,同时也不会丢失边缘和角落的信息。在Python的numpy库中,常常采用numpy.pad()进行填充操作。 val_size = (max(H, W) + 31) // 32 32noisy_im = np.pad(noisy_im,[[0, val_size - H], [0, val_size - W], [0, 0]],'reflect') ‘reflect’, 表示对称填充。 上图转自 http://t.zoukankan.com/shuaishuaidefeizhu-p-14179038.html >>> a = [1, 2, 3, 4, 5]>>> np.pad(a, (2, 3), 'reflect')array([3, 2, 1, 2, 3, 4, 5, 4, 3, 2]) 个人感觉使用reflect操作,而不是之间的填充0是为了在边缘去噪的时候更平滑一些。镜像填充后的图如下: 输入网络后,得到预测结果。最后进行裁剪,得到去噪后的图像。 prediction = prediction[:, :, :H, :W] 本篇文章为转载内容。原文链接:https://blog.csdn.net/qq_42948594/article/details/124712116。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-13 14:44:26
129
转载
Lua
...Lua编写游戏逻辑、用户界面、AI行为等,极大地提高了开发效率。例如,Lua允许开发者在不修改游戏核心代码的情况下轻松地调整和测试游戏逻辑,这在迭代频繁的游戏开发周期中尤为重要。 Lua在跨平台开发中的优势 Lua的跨平台特性使得它成为游戏开发者构建多平台游戏的理想选择。开发者只需编写一次代码,通过LuaJIT(Just-In-Time编译器)或其他相关工具,即可在Windows、Linux、macOS、Android、iOS等多个平台上运行游戏,大大减少了开发成本和时间。 Lua在游戏服务器与网络编程中的应用 Lua在游戏服务器端的开发中展现出强大的潜力。其简洁的语法和高效的执行速度使得开发者能够快速搭建和维护游戏服务器,处理复杂的网络通信、并发请求等任务。此外,Lua还支持多种网络编程模型,如异步IO,这使得在高并发环境下保持良好的性能成为可能。 Lua与现代游戏技术的结合 随着虚拟现实(VR)、增强现实(AR)、云计算等技术的发展,Lua也在不断探索与这些前沿技术的结合点。例如,开发者可以使用Lua编写VR/AR游戏的逻辑,利用云服务实现大规模的分布式计算,优化游戏性能和用户体验。 Lua社区与生态系统的成长 Lua社区的活跃和生态系统的不断完善,为开发者提供了丰富的资源和工具。从开源库到专业服务,开发者可以根据项目需求快速找到合适的解决方案,加速项目进展。此外,社区活动、教程和文档的丰富也为新加入的开发者提供了友好的入门路径。 总的来说,Lua在游戏开发领域的应用正呈现出多元化、高效化和智能化的趋势。随着技术的进一步发展,Lua有望在游戏开发中发挥更加重要的作用,推动游戏产业向更高水平迈进。
2024-08-12 16:24:19
168
夜色朦胧
Maven
...en是一个强大的依赖管理工具,其灵活性使得配置变得复杂,同时也增加了出错的可能性。 三、常见原因与排查步骤 1. 配置文件错误 检查pom.xml文件是否正确。错误可能出现在元素属性值、标签闭合、版本号、依赖关系等方面。 示例:错误的pom.xml配置可能导致无法识别的元素或属性。 xml com.example example-module unknown-version 这里,属性值未指定,导致Maven无法识别该版本信息。 2. 命令行参数错误 在执行Maven命令时输入的参数不正确或拼写错误。 示例:错误的命令行参数可能导致构建失败。 bash mvn compile -Dsome.property=wrong-value 这里的参数-Dsome.property=wrong-value中property的值可能与实际配置不匹配,导致Maven无法识别或处理。 3. 依赖冲突 多个版本的依赖包共存,且版本不兼容。 示例:两个依赖包同时声明了相同的类名或方法名,但版本不同,可能会引发编译错误。 xml org.example example-library 1.0.0 org.example example-library 1.0.1 四、解决方案与优化建议 1. 检查pom.xml文件 - 确保所有元素闭合、属性值正确。 - 使用IDE的自动完成功能或在线工具验证pom.xml的语法正确性。 2. 修正命令行参数 - 确认参数的拼写和格式正确。 - 使用Maven的help:effective-pom命令查看实际生效的pom.xml配置,确保与预期一致。 3. 解决依赖冲突 - 使用标签排除不必要的依赖。 - 更新或降级依赖版本以避免冲突。 - 使用Maven的dependency:tree命令查看依赖树,识别并解决潜在的冲突。 五、总结与反思 面对“Error:The project has a build goal with an invalid syntax”的挑战,关键在于细致地检查配置文件和构建命令,以及理解依赖关系。每一次遇到这样的错误,都是对Maven配置知识的深化学习机会。哎呀,你知道吗?就像你练习弹吉他一样,多用多练,咱们用Maven这个工具也能越来越顺手!它能帮咱们开发时节省不少时间,就像是有了个超级助手,能自动搞定那些繁琐的构建工作,让咱们的项目推进得飞快,没有那么多绊脚石挡道。是不是感觉挺酷的?咱们得好好加油,让这玩意儿成为咱们的拿手好戏! 六、结语 Maven作为项目构建管理工具,虽然强大且灵活,但也伴随着一定的复杂性和挑战。嘿!兄弟,这篇文章就是想给你支点招儿,让你在开发过程中遇到问题时能更顺手地找到解决方法,让编程这个事儿变得不那么头疼,提升你的码农体验感。别再为那些小bug烦恼了,跟着我的节奏,咱们一起搞定代码里的小麻烦,让编程之路畅通无阻!嘿,兄弟!听好了,每当你碰上棘手的问题,那可是你升级技能、长本事的绝佳机会!别急,拿出点好奇心,再添点耐心,咱们一起动手,一步步地去解谜,去学习,去挑战。就像在探险一样,慢慢你会发现自己的开发者之路越走越宽广,越来越精彩!所以啊,别怕困难,它们都是你的成长伙伴,加油,咱们一起成为更棒的开发者吧!
2024-08-09 16:06:13
94
初心未变
转载文章
...19。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 根据jeff377 的话,竹子将这验证码改进了一下,请大家讨论看看。 -------jeff377-------------------------------------------- 我研究所的论文就是在做类神经网络处理文字辨识,以你的例子而言,旋转随意角度对辨识来说并不会有太大影响,只要抓字的重心,360度旋转抓取特微值,还是可以辨识的出来。 通常文字辨识的有一个重要的动作,就是要把个别文字分割,你只要把文字弄的难分割就有不错的安全性。 --------------------------------------------------- 代码比较粗糙,而且比较菜,其中遇到一个问题,未对 Graphics 填充底色,那么文字的 ClearType 效果没有了,文字毛边比较明显,不知道为什么,谁能告诉竹子? 代码相对粗糙,没有考虑更多的情况,在测试过程中,以20px 字体呈现,效果感觉还不错,只是 ClearType 效果没有了。 帖几张看看 ------------ ------------ ------------ ------------ 有一些随机的不好,象下面这张 相关链接: 查看 V1.0 .NET 2.0 代码如下: using System; using System.Drawing; using System.Web; namespace Oran.Image { /// <summary> /// 旋转的可视验证码图象 /// </summary> public class RotatedVlidationCode { public enum RandomStringMode { /// <summary> /// 小写字母 /// </summary> LowerLetter, /// <summary> /// 大写字母 /// </summary> UpperLetter, /// <summary> /// 混合大小写字母 /// </summary> Letter, /// <summary> /// 数字 /// </summary> Digital, /// <summary> /// 混合数字与大小字母 /// </summary> Mix } public static string GenerateRandomString(int length, RandomStringMode mode) { string rndStr = string.Empty; if (length == 0) return rndStr; //以数组方式候选字符,可以更方便的剔除不要的字符,如数字 0 与字母 o char[] digitals = new char[10] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; char[] lowerLetters = new char[26] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; char[] upperLetters = new char[26] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; char[] letters = new char[52]{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; char[] mix = new char[62]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; int[] range = new int[2] { 0, 0 }; Random random = new Random(); switch (mode) { case RandomStringMode.Digital: for (int i = 0; i < length; ++i) rndStr += digitals[random.Next(0, digitals.Length)]; break; case RandomStringMode.LowerLetter: for (int i = 0; i < length; ++i) rndStr += lowerLetters[random.Next(0, lowerLetters.Length)]; break; case RandomStringMode.UpperLetter: for (int i = 0; i < length; ++i) rndStr += upperLetters[random.Next(0, upperLetters.Length)]; break; case RandomStringMode.Letter: for (int i = 0; i < length; ++i) rndStr += letters[random.Next(0, letters.Length)]; break; default: for (int i = 0; i < length; ++i) rndStr += mix[random.Next(0, mix.Length)]; break; } return rndStr; } /// <summary> /// 显示验证码 /// </summary> /// <param name="seed">随机数辅助种子</param> /// <param name="strLen">验证码字符长度</param> /// <param name="fontSize">字体大小</param> /// <param name="mode">随机字符模式</param> /// <param name="clrFont">字体颜色</param> /// <param name="clrBg">背景颜色</param> public static void ShowValidationCode(ref int seed, int strLen, int fontSize, RandomStringMode mode, Color clrFont, Color clrBg) { int tmpSeed; unchecked { tmpSeed = (int)(seed DateTime.Now.Ticks); ++seed; } Random rnd = new Random(tmpSeed); string text = GenerateRandomString(strLen, mode); int height = fontSize 2; // 因为字体旋转后每个字体所占宽度会所有加大,所以要加一点补偿宽度 int width = fontSize text.Length + fontSize / (text.Length - 2); Bitmap bmp = new Bitmap(width, height); Graphics graphics = Graphics.FromImage(bmp); Font font = new Font("Courier New", fontSize, FontStyle.Bold); Brush brush = new SolidBrush(clrFont); Brush brushBg = new SolidBrush(clrBg); graphics.FillRectangle(brushBg, 0, 0, width, height); Bitmap tmpBmp = new Bitmap(height, height); Graphics tmpGph = null; int degree = 40; Point tmpPoint = new Point(); for (int i = 0; i < text.Length; i++) { tmpBmp = new Bitmap(height, height); tmpGph = Graphics.FromImage(tmpBmp); // tmpGph.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; // 不填充底色,文字 ClearType 效果不见了,why?! // tmpGph.FillRectangle(brushBg, 0, 0, tmpBmp.Width, tmpBmp.Height); degree = rnd.Next(20, 51); // [20, 50]随机角度 if (rnd.Next(0, 2) == 0) { tmpPoint.X = 12; // 调整文本坐标以适应旋转后的图象 tmpPoint.Y = -6; } else { degree = ~degree + 1; // 逆时针旋转 tmpPoint.X = -10; tmpPoint.Y = 6; } tmpGph.RotateTransform(degree); tmpGph.DrawString(text[i].ToString(), font, brush, tmpPoint); graphics.DrawImage(tmpBmp, i fontSize, 0); // 拼接图象 } //输出图象 System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(); bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Gif); HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.ClearContent(); HttpContext.Current.Response.ContentType = "image/gif"; HttpContext.Current.Response.BinaryWrite(memoryStream.ToArray()); HttpContext.Current.Response.End(); //释放资源 font.Dispose(); brush.Dispose(); brushBg.Dispose(); tmpGph.Dispose(); tmpBmp.Dispose(); graphics.Dispose(); bmp.Dispose(); memoryStream.Dispose(); } } } 转载于:https://www.cnblogs.com/iRed/archive/2008/06/22/1227687.html 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_30600197/article/details/96672619。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-05-27 09:38:56
250
转载
Beego
...开发方法论,强调基于用户需求和系统行为来描述测试场景和预期结果。在本文中,Ginkgo是一个遵循BDD原则的测试框架,它鼓励开发者通过清晰易读的语言描述测试上下文、前置条件、行为以及预期结果。在Ginkgo中,Describe、BeforeEach、It 和 By 等关键字被用来构建易于理解的行为测试用例,这有助于团队成员更好地沟通并确保对系统功能有共同的理解和一致的验收标准。
2024-02-09 10:43:01
460
落叶归根-t
转载文章
...12。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 ↑ 点击上方【计算机视觉联盟】关注我们 最经典的决策树算法有ID3、C4.5、CART,其中ID3算法是最早被提出的,它可以处理离散属性样本的分类,C4.5和CART算法则可以处理更加复杂的分类问题,本文重点介绍ID3算法。 1、决策树基本流程 决策树 (decision tree) 是一类常见的机器学习方法。它是对给定的数据集学到一个模型对新示例进行分类的过程。下图所示为一个流程图的决策树,长方形代表判断模块(decision block),椭圆形代表终止模块(terminating block),表示已经得出结论,可以终止运行。从判断模块引出的左右箭头称作分支(branch),可以达到另一个判断模块或终止模块。 决策过程是基于树结构来进行决策的。如下图,首先检查邮件域名地址,如果地址为myEmployer.com,则将其分类为“无聊时需要阅读的邮件”。否则,则检查邮件内容里是否包含单词“曲棍球”,如果包含则归类为“需要及时处理的朋友邮件”,如果不包含则归类到“无需阅读的垃圾邮件” 流程图形式的决策树 显然,决策过程的最终结论对应了我们所希望的判定结果,例如"需要阅读"或"不需要阅读”。 决策过程中提出的每个判定问题都是对某个属性的"测试",如邮件地址域名为?是否包含“曲棍球”? 每个测试的结果或是导出最终结论,或是导出进一步的判定问题,其考虑范围是在上次决策结果的限定范围之内,例如若邮件地址域名不是myEmployer.com之后再判断是否包含“曲棍球”。 一般的,决策树包含一个根节点、若干个内部节点和若干个叶节点。根节点包含样本全集;叶节点对应于决策结果,例如“无聊时需要阅读的邮件”。其他每个结点则对应于一个属性测试;每个节点包含的样本集合根据属性测试的结果被划分到子结点中。 决策树学习基本算法 显然,决策树的生成是一个递归过程.在决策树基本算法中,有三种情形会导致递归返回: (1)当前结点包含的样本全属于同一类别,无需划分; (2)当前属性集为空,或是所有样本在所有属性上取值相同,无法划分; (3)当前结点包含的样本集合为空,不能划分。 2、划分选择 决策树算法的关键是如何选择最优划分属性。一般而言,随着划分过程不断进行,我们希望决策树的分支结点所包含的样本尽可能属于同一类别,即结点的"纯度" (purity)越来越高。 (1)信息增益 信息熵 "信息熵" (information entropy)是度量样本集合纯度最常用的一种指标,定义为信息的期望。假定当前样本集合 D 中第 k 类样本所占的比例为 ,则 D 的信息熵定义为: H(D)的值越小,则D的纯度越高。信息增益 一般而言,信息增益越大,则意味着使周属性 来进行划分所获得的"纯度提升"越大。因此,我们可用信息增益来进行决策树的划分属性选择,信息增益越大,属性划分越好。 以西瓜书中表 4.1 中的西瓜数据集 2.0 为例,该数据集包含17个训练样例,用以学习一棵能预测设剖开的是不是好瓜的决策树.显然,。 在决策树学习开始时,根结点包含 D 中的所有样例,其中正例占 ,反例占 信息熵计算为: 我们要计算出当前属性集合{色泽,根蒂,敲声,纹理,脐部,触感}中每个属性的信息增益。以属性"色泽"为例,它有 3 个可能的取值: {青绿,乌黑,浅自}。若使用该属性对 D 进行划分,则可得到 3 个子集,分别记为:D1 (色泽=青绿), D2 (色泽2=乌黑), D3 (色泽=浅白)。 子集 D1 包含编号为 {1,4,6,10,13,17} 的 6 个样例,其中正例占 p1=3/6 ,反例占p2=3/6; D2 包含编号为 {2,3,7,8, 9,15} 的 6 个样例,其中正例占 p1=4/6 ,反例占p2=2/6; D3 包含编号为 {5,11,12,14,16} 的 5 个样例,其中正例占 p1=1/5 ,反例占p2=4/5; 根据信息熵公式可以计算出用“色泽”划分之后所获得的3个分支点的信息熵为: 根据信息增益公式计算出属性“色泽”的信息增益为(Ent表示信息熵): 类似的,可以计算出其他属性的信息增益: 显然,属性"纹理"的信息增益最大,于是它被选为划分属性。图 4.3 给出了基于"纹理"对根结点进行划分的结果,各分支结点所包含的样例子集显示在结点中。 然后,决策树学习算法将对每个分支结点做进一步划分。以图 4.3 中第一个分支结点( "纹理=清晰" )为例,该结点包含的样例集合 D 1 中有编号为 {1, 2, 3, 4, 5, 6, 8, 10, 15} 的 9 个样例,可用属性集合为{色泽,根蒂,敲声,脐部 ,触感}。基于 D1计算出各属性的信息增益: "根蒂"、 "脐部"、 "触感" 3 个属性均取得了最大的信息增益,可任选其中之一作为划分属性.类似的,对每个分支结点进行上述操作,最终得到的决策树如圈 4.4 所示。 3、剪枝处理 剪枝 (pruning)是决策树学习算法对付"过拟合"的主要手段。决策树剪枝的基本策略有"预剪枝" (prepruning)和"后剪枝 "(post" pruning) [Quinlan, 1993]。 预剪枝是指在决策树生成过程中,对每个结点在划分前先进行估计,若当前结点的划分不能带来决策树泛化性能提升,则停止划 分并将当前结点标记为叶结点; 后剪枝则是先从训练集生成一棵完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升,则将该子树替换为叶结点。 往期回顾 ● 带你详细了解机器视觉竞赛—ILSVRC竞赛 ● 到底什么是“机器学习”?机器学习有哪些基本概念?(简单易懂) ● 带你自学Python系列(一):变量和简单数据类型(附思维导图) ● 带你自学Python系列(二):Python列表总结-思维导图 ● 2018年度最强的30个机器学习项目! ● 斯坦福李飞飞高徒Johnson博士论文: 组成式计算机视觉智能(附195页PDF) ● 一文详解计算机视觉的广泛应用:网络压缩、视觉问答、可视化、风格迁移 本篇文章为转载内容。原文链接:https://blog.csdn.net/Sophia_11/article/details/113355312。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-08-27 21:53:08
285
转载
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
systemctl start|stop|restart|status service_name
- 管理systemd服务。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"