【Algorithms 4】算法(第4版)学习笔记 16 - 4.2 有向图

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:介绍
      • 1.1:有向图简介
      • 1.2:应用举例
      • 1.3:相关问题
      • 2:有向图 API
      • 2.1:有向图表示
      • 2.1.1:邻接表数组 Adjacency-list
      • 2.1.2:Java 实现:邻接表数组
      • 2.2:实际应用
      • 2.3:小结
      • 3:有向图搜索
      • 3.1:可达性
      • 3.2:深度优先搜索 depth-first search
      • 3.2.1:demo 演示
      • 3.2.2:Java 实现
      • 3.3:可达性应用
      • 3.3.1:程序控制流分析
      • 3.3.2:标记-清除垃圾回收
      • 3.4:小结
      • 3.5:广度优先搜索 breadth-first search
      • 3.5.1:demo 演示
      • 3.5.2:多源最短路径
      • 3.6:BFS 应用
      • 3.6.1:网络爬虫
      • 3.6.2:Java 实现
      • 4:拓扑排序 topological sort
      • 4.1:定义
      • 4.2:demo 演示
      • 4.3:Java 实现:DFS 排序
      • 4.4:DAG 拓扑排序证明
      • 4.5:有向循环检测
      • 5:强连通分量 strong components
      • 5.1:定义
      • 5.2:无向图连通分量 vs. 有向图强连通分量
      • 5.3:强连通分量算法简史
      • 5.4:Kosaraju-Sharir 算法
      • 5.4.1:直觉
      • 5.4.2:demo 演示
      • 5.4.2.1:第一阶段
      • 5.4.2.2:第二阶段
      • 5.4.3:过程小结
      • 5.4.4:证明
      • 5.4.5:Java 实现
      • 6:有向图处理小结

前言

本篇主要内容包括:有向图 API有向图搜索拓扑排序 以及 强连通分量

强烈建议在学习本篇之前先行学习或回顾上一篇无向图的内容。

参考目录

  • B站 普林斯顿大学《Algorithms》视频课
    (请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。)
  • 微信读书《算法(第4版)》
    (本文主要内容来自《4.2 有向图》)
  • 官方网站
    (有书本配套的内容以及代码)

学习笔记

注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。
注3:如果 PPT 截图中没有翻译,会在下面进行汉化翻译,因为内容比较多,本文不再一一说明。

1:介绍

1.1:有向图简介

在这里插入图片描述

书中有向图图解:

在这里插入图片描述

1.2:应用举例

image-20240307083507140

1.3:相关问题

![L13-42DirectedGraphs_11]

问题描述
s → t path从 s 到 t 的路径是否存在?
shortest s → t path从 s 到 t 的最短路径是什么?
directed cycle图中是否存在有向环?
topological sort (拓扑排序)能否将有向图绘制为所有边都指向上的拓扑排序形式?
strong connectivity (强连通性)图中任意两点之间是否存在方向任意的有向路径?
transitive closure (传递闭包)对于哪些顶点 v 和 w,存在从 v 到 w 的有向路径?
PageRank (页面排名算法)网页的重要性是什么?

2:有向图 API

![image-20240307091117855]

2.1:有向图表示

2.1.1:邻接表数组 Adjacency-list

![L13-42DirectedGraphs_15]

2.1.2:Java 实现:邻接表数组

(可参考对比无向图 Graph 实现)

edu.princeton.cs.algs4.Digraph

![image-20240307095043211]

edu.princeton.cs.algs4.Digraph#Digraph

![image-20240307095141935]

edu.princeton.cs.algs4.Digraph#addEdge

![image-20240307095232234]

edu.princeton.cs.algs4.Digraph#adj

![image-20240307095333624]

2.2:实际应用

![image-20240307095644883]

**在实际应用中:**我们采用邻接表的方式来表示图结构。

  • 许多算法都是基于从顶点 v 出发逐个遍历其指向的所有其他顶点。
  • 实际应用中的有向图数据结构往往具有稀疏特性。(虽然顶点数量可能非常庞大,但平均每个顶点所连接的边数相对较少。)

2.3:小结

![image-20240307100306896]

注:边的数组 list of edges 以及 邻接矩阵 adjacency matrix 没有详细说明,可以参考无向图 #2.4 相关内容。

3:有向图搜索

3.1:可达性

![L13-42DirectedGraphs_20]

3.2:深度优先搜索 depth-first search

![L13-42DirectedGraphs_21]

与无向图方法相同:

  • 每一个无向图都可以视为一个有向图(每条边都有两个方向)。
  • 深度优先搜索(DFS)是一个应用于有向图的算法。

3.2.1:demo 演示

![image-20240308083822573]

访问一个顶点 v 时:

  • 将顶点 v 标记为已访问状态。
  • 递归地访问从顶点 v 出发的所有未标记的顶点。

初始状态:

![image-20240308084052618]

同样地,v 代表顶点,marked[] 保存标记状态,edgeTo[] 保存边信息。

访问第一个顶点 0:

![image-20240308084405582]

依次检查 与顶点 0 相邻且由此出发所指向的 顶点:分别是 5、1。

检查顶点 5:

![image-20240308084715158]

检查与顶点 5 相邻且由此出发所指向的顶点:4。

检查顶点 4:

![image-20240308084900765]

检查与顶点 4 相邻且由此出发所指向的顶点:分别是 3、2。

检查顶点 3:

![image-20240308085020730]

检查与顶点 3 相邻且由此出发所指向的顶点:分别是 5、2。

检查顶点 5,已经被标记。

检查顶点 2:

![image-20240308085202510]

检查与顶点 2 相邻且由此出发所指向的顶点:分别是 0、3。

检查顶点 0,已经被标记。

检查顶点 3,已经被标记。

完成顶点 2 的搜索:

![image-20240308085351466]

返回顶点 3,完成顶点 3 的搜索:

![image-20240308085516067]

返回顶点 4 继续搜索:

检查顶点 2,已经被标记。

完成顶点 4 的搜索:

![image-20240308085731886]

返回顶点 5,完成顶点 5 的搜索:

![image-20240308085811186]

返回顶点 0 继续搜索:

搜索顶点 1,没有需要搜索的相邻节点,完成顶点 1 的搜索:

![image-20240308085939969]

完成顶点 0 的搜索:

![image-20240308090119040]

完成了所有顶点 0 可达的顶点搜索:

![image-20240308090233915]

3.2.2:Java 实现

(与无向图完全相同,只是替换了方法名称以及对象类型)

edu.princeton.cs.algs4.DirectedDFS

![image-20240308090856191]

edu.princeton.cs.algs4.DirectedDFS#dfs

![image-20240308090914605]

edu.princeton.cs.algs4.DirectedDFS#marked

![image-20240308090928992]

3.3:可达性应用

3.3.1:程序控制流分析

![image-20240308092044359]

每个程序都可以表示为一个有向图。

  • 顶点(Vertex):表示一组连续执行的指令集(基本块)。
  • 边(Edge):表示程序控制流中的跳转关系。

死代码消除。
寻找并移除不可达(永远不会被执行)的代码。

无限循环检测。
判断程序是否存在无法到达退出点的情况。

3.3.2:标记-清除垃圾回收

![image-20240308092832284]

每种数据结构都可以表示为一个有向图。

  • 顶点(Vertex):表示对象(Object)。
  • 边(Edge):表示引用(Reference)。

根对象(Roots)。
指那些可以直接被程序访问的对象(例如,栈中的对象)。

可达对象(Reachable objects)。
指那些通过程序可以从根对象间接访问到的对象(从某个根开始,沿着一系列指针链进行跟踪)。

![image-20240308093117066]

标记-清除算法(由麦卡锡于 1960 年提出):

  • 标记阶段(Mark):标记所有能够被程序访问到的对象。
  • 清除阶段(Sweep):若对象未被标记,则判定其为垃圾对象(从而将它加入到空闲列表中释放)。

内存成本:
该算法对每个对象需要额外占用 1 个标记位,并且还需要使用深度优先搜索栈(这会增加一定的内存开销)。

标记-清除算法 是学习 JVM 的时候一个很重要的算法。

3.4:小结

![L13-42DirectedGraphs_29]

深度优先搜索(DFS)能够直接解决一些简单的有向图问题。

  • 可达性(判断图中两个顶点间是否存在可达路径。)
  • 路径查找(找到一条从起点到终点的路径。)
  • 拓扑排序(对有向无环图中的顶点进行排序,使得对于任意指向顶点 u 的边,顶点 u 都在顶点 v 之前。)
  • 有向循环检测(判断有向图中是否存在环路。)

深度优先搜索是解决复杂有向图问题的基础方法。

  • 二元可满足性问题求解(在逻辑运算中判断给定的布尔公式是否能通过真值赋值使其结果为真的问题。)
  • 有向欧拉路径(在有向图中寻找一条经过每条边恰好一次的路径。)
  • 强连通分量(识别出有向图中互相可达的所有顶点集合,这些集合内的顶点两两之间都存在可达路径。)

3.5:广度优先搜索 breadth-first search

![L13-42DirectedGraphs_30]

同样的方法也适用于无向图。

  • 每个无向图都可以看作是有向图(每条边都是双向的)。
  • 广度优先搜索(BFS)是一种有向图算法。

**命题:**在有向图中,广度优先搜索(BFS)可以在时间复杂度为 O(E+V) 的时间内,计算出从顶点 s 到其他所有顶点的最短路径(即最少边数的路径)。

3.5.1:demo 演示

![image-20240308112651220]

重复执行以下操作,直到队列为空:

  • 从队列中移除顶点 v。
  • 将从顶点 v 出发的所有未标记的顶点加入队列,并将它们标记为已访问。

初始状态:

![image-20240308112814925]

将顶点 0 添加到队列:

![image-20240308113008940]

queue 代表队列,v 代表顶点,edgeTo[] 保存边信息,distTo[] 保存路径长度信息。

顶点 0 出队:

![image-20240308113155176]

需要依次检查 与顶点 0 相邻且由此出发所指向的 顶点:分别是 2、1。

![image-20240308113313544]

检查顶点 2:

![image-20240308113440038]

顶点 2 没有被标记,添加到队列中。

检查顶点 1:

![image-20240308113515785]

顶点 1 没有被标记,添加到队列中。

完成顶点 0 搜索:

![image-20240308113622358]

顶点 2 出队:

![image-20240308113912866]

依次检查与顶点 2 相邻且由此出发所指向的顶点:4。

![image-20240308114040848]

检查顶点 4:

![image-20240308114137636]

顶点 4 没有被标记,添加到队列中。

完成顶点 2 搜索:

![image-20240308114213642]

顶点 1 出队:

![image-20240308114303032]

依次检查与顶点 1 相邻且由此出发所指向的顶点:2。

检查顶点 2,已经被标记。

完成顶点 1 搜索:

![image-20240308114433307]

顶点 4 出队:

![image-20240308114539272]

依次检查与顶点 4 相邻且由此出发所指向的顶点:3。

![image-20240308114807806]

检查顶点 3:

![image-20240308114855110]

顶点 3 没有被标记,添加到队列中。

完成顶点 4 搜索:

![image-20240308114932405]

顶点 3 出队:

![image-20240308115007828]

依次检查与顶点 3 相邻且由此出发所指向的顶点:分别是 5、2。

![image-20240308115112474]

检查顶点 5:

![image-20240308115323083]

顶点 5 没有被标记,添加到队列中。

检查顶点 2,已经被标记。

完成顶点 3 搜索:

![image-20240308115343655]

顶点 5 出队:

![image-20240308115449300]

依次检查与顶点 5 相邻且由此出发所指向的顶点:0。

![image-20240308115429564]

检查顶点 0,已经被标记。

完成顶点 5 搜索:

![image-20240308115515870]

完成所有搜索:

![image-20240308115548973]

3.5.2:多源最短路径

![L13-42DirectedGraphs_33]

多源最短路径
给定一个有向图和一组起点顶点,找出从该组任意起点顶点到图中其他所有顶点的最短路径。

Q. 如何实现多源最短路径算法?
A. 可以使用广度优先搜索(BFS),但是在初始化时,将所有源顶点都入队列。 (具体做法是首先将所有指定的源顶点放入队列中作为搜索的起点,然后按照广度优先搜索的规则依次遍历图中的其他顶点,逐步计算出从各个源顶点到图中所有其他顶点的最短路径。)

3.6:BFS 应用

3.6.1:网络爬虫

![L13-42DirectedGraphs_34]

**目标:**从某一指定的根网页(例如www.princeton.edu)出发爬取整个网站。

**解决方案:**使用 广度优先搜索(BFS) 算法隐式构建的有向图 进行爬取。

步骤如下:

  1. 将根网页设为源节点 s
  2. 维护一个用于存储待探索网站的 队列(Queue)
  3. 维护一个记录已发现网站的 集合(SET),用于去重。
  4. 从队列中取出下一个网站,并检查其指向的所有链接所对应的网站(前提是这些网站尚未被添加进队列或集合中)。
    • 如果某个链接指向的网站还未被发现,则将其加入队列。
    • 同时将新发现的网站添加到已发现网站的集合中,确保不会重复抓取同一网站。

Q. 为什么不用 DFS 实现?

(利用通义千问总结一下) 网络爬虫的实现通常首选广度优先搜索(BFS)而不是深度优先搜索(DFS)的原因在于以下几个关键因素:

  1. 短路径优先
    • BFS 保证爬虫首先遍历到的是离起始网页最近的网页,因此对于寻找最短路径的情况非常有利。在网络爬虫场景下,如果目的是快速抓取到尽可能接近种子 URL 的网页,BFS 能够找到从起始网页到任意页面的最短跳转路径。
  2. 更全面的初始层级覆盖
    • BFS 逐层遍历,能更均匀地抓取同一层级上的所有链接,这对于初步建立网站的拓扑结构、索引和导航结构的初步构建十分有效,能够迅速获取到一个网站的第一层链接资源。
  3. 避免过深探索
    • DFS 可能会导致爬虫陷入深层次且可能不是特别重要的链接结构中,而忽视了其他重要性较高的较浅层次页面。尤其是在没有合理剪枝策略的情况下,DFS 可能导致爬虫在某一分支上耗费过多资源,而忽略了其他可能更重要的部分。
  4. 减少重复爬取
    • BFS 通过维护一个已经访问过的网页集合(通常是哈希表),能够有效地避免爬虫反复进入同一个网页的多个入口,减少了不必要的重复抓取。
  5. 反映网页的重要性
    • 在某些基于链接流行度的评价体系中,入链数量往往代表了一定程度上的网页重要性。BFS 倾向于先抓取那些有更多的入链(即被更多网页链接到的网页),这在一定程度上符合优先抓取重要网页的需求。

综上所述,网络爬虫采用 BFS 作为基础遍历策略,能够更好地满足实际应用中的需求,如高效地获取范围广泛的链接、平衡地抓取不同层次的内容以及减少不必要开销等。当然,具体实现时根据任务的具体要求,有时候也会结合 DFS 或其他策略来优化爬虫的行为。

3.6.2:Java 实现

![L13-42DirectedGraphs_35]

4:拓扑排序 topological sort

4.1:定义

![L13-42DirectedGraphs_39]

4.2:demo 演示

![image-20240309124401947]

  • 执行深度优先搜索
  • 按逆后序返回顶点

初始状态:

![image-20240309124627112]

访问第一个顶点 0:

![image-20240309124957020]

依次检查相邻顶点:1、2、5。

检查顶点 1:

![image-20240309125144970]

检查相邻顶点:4。

检查顶点 4:

![image-20240309125252832]

顶点 4 没有出度,完成搜索并加入堆栈(后序 postorder):

![image-20240309125515783]

返回顶点 1,完成搜索并加入后序:

![image-20240309125720202]

返回顶点 0 继续搜索。

检查顶点 2:

![image-20240309132239841]

顶点 2 没有出度,完成搜索并加入后序:

![image-20240309132322686]

返回顶点 0 继续搜索。

检查顶点 5:

![image-20240309132404455]

检查顶点 2,已经被标记。

顶点 5 完成搜索并加入后序:

![image-20240309132510999]

完成顶点 0 的搜索并加入后序:

![image-20240309132602881]

按顺序检查其他未标记顶点。

顶点 1、2 已经被标记,检查顶点 3:

![image-20240309132929427]

依次检查相邻顶点:2、4、5、6。

检查顶点 2,已经被标记。

检查顶点 4,已经被标记。

检查顶点 5,已经被标记。

检查顶点 6:

![image-20240309133145225]

检查相邻顶点:0、4。

检查顶点 0,已经被标记。

检查顶点 4,已经被标记。

完成顶点 6 的搜索并加入后序:

![image-20240309133254279]

完成顶点 3 的搜索并加入后序:

![image-20240309133329349]

完成所有顶点搜索。

4.3:Java 实现:DFS 排序

edu.princeton.cs.algs4.DepthFirstOrder

![image-20240309134132609]

edu.princeton.cs.algs4.DepthFirstOrder#dfs

![image-20240309134209810]

edu.princeton.cs.algs4.DepthFirstOrder#reversePost

![image-20240309134249391]

4.4:DAG 拓扑排序证明

![L13-42DirectedGraphs_44]

对应书本命题 F:

![image-20240309134810658]
img
图4.2.11 有向无环图的逆后序是拓扑排序

4.5:有向循环检测

![L13-42DirectedGraphs_45]

**命题:**一个有向图存在拓扑排序当且仅当它不含任何有向环。

证明:

  • 若存在有向环,则无法构造拓扑排序。
  • 若不存在有向环,则基于深度优先搜索(DFS)的算法能够找到一个拓扑排序。

5:强连通分量 strong components

5.1:定义

(PPT 和书本内容一致,直接把书本的内容贴出来)

定义:

![image-20240309141811365]

性质:

![image-20240309141859632]
image-20240309141927944

5.2:无向图连通分量 vs. 有向图强连通分量

![L13-42DirectedGraphs_52]

5.3:强连通分量算法简史

![L13-42DirectedGraphs_55]

1960年代:核心运筹学问题。

  • 广泛研究,出现了一些实用算法。
  • 其复杂性尚未被充分理解。

1972年:线性时间的深度优先搜索(DFS)算法(由 Tarjan 提出)。

  • 经典算法,在算法领域占有重要地位。
  • 算法难度级别相当于“Algs4 进阶版”。
  • 显示了深度优先搜索在广泛应用场景下的重要性和实用性。

1980年代:简易两遍线性时间算法(Kosaraju-Sharir 算法)。

  • 教授课程时忘记带讲义,为了授课临时开发出该算法!
  • 后来发现该算法实际上在 1972 年的俄罗斯科学文献中已有记载。

1990年代:更多简易的线性时间算法出现。

  • Gabow 改进了原有的运筹学算法。
  • Cheriyan 和 Mehlhorn 设计了一种单遍线性时间算法,这是 LEDA 项目所需的关键技术。

Prof. Sedgewick 总结:

So this story indicates, even from fundamental problems in graph processing, there’s algorithms out there still waiting to be discovered. And this algorithm is a good example of that.

因此,这个故事表明,即使在图形处理的基本问题中,仍然存在有待发现的算法。而上述提到的算法恰好是一个很好的例子。

5.4:Kosaraju-Sharir 算法

5.4.1:直觉

![L13-42DirectedGraphs_56]

**反向图:**原图 G 中的强连通分量与反向图 GR 中的相同。

**核 DAG(Kernel DAG):**将每个强连通分量收缩成单个顶点。

思路:

  • 在核 DAG 中计算拓扑排序(采用逆后序)。
  • 以逆拓扑顺序考虑顶点,并运行深度优先搜索(DFS)。

书中的描述:

![image-20240309145233298]

5.4.2:demo 演示

![image-20240309145412029]

阶段1: 在 GR 图中计算逆后序排列。
阶段2: 在 G 图中运行深度优先搜索,按照 GR 图中的逆后序排列顺序访问未标记的顶点。

初始状态:

![image-20240309145554570]

5.4.2.1:第一阶段

在反向图 GR 图中计算逆后序排列。

反向图 GR

![image-20240309150628583]

逆后序排列演示在前面拓扑排序刚说完,就不一一截图了,大致搜索过程如下(* 粗体 代表搜索完成放入后序):

0 —— 6 —— 8

8 —— 6 —— 7

7 —— 6

6 —— 0 —— 2 —— 4 —— 11 —— 9 —— 12 —— 10

10 —— 12

12 —— 9

9 —— 11

11 —— 4 —— 5 —— 3

3 —— 5

5 —— 4

4 —— 2

2 —— 0

1

检查确保所有顶点都已经被标记。

第一阶段结束后的结果:

![L13-42DirectedGraphs_58]

5.4.2.2:第二阶段

在 G 图中运行深度优先搜索,按照 GR 图中的逆后序排列顺序访问未标记的顶点。

原始图 G:

![image-20240309151559229]

以第一阶段结果 1 0 2 4 5 3 11 9 12 10 6 7 8 进行搜索。

搜索顶点 1:

![image-20240309151936900]

没有其他顶点,强连通分量编号标记为 0,完成搜索。

![image-20240309152114934]

同理,搜索其他分量,大致过程如下:

0 —— 5 —— 4 —— 3 —— 2

![image-20240309152415181]

顶点 0、2、3、4、5 为强连通分量,标记为 1。

11 —— 12 —— 9 —— 10

![image-20240309152706706]

顶点 9、10、11、12 为强连通分量,标记为 2。

6 —— 8

![image-20240309153115846]

顶点 6、8 为强连通分量,标记为 3。

7

![image-20240309153139893]

顶点 7 为强连通分量,标记为 4。

完成所有的连通分量查询:

![L13-42DirectedGraphs_59]

5.4.3:过程小结

Kosaraju-Sharir 算法:计算强连通分量的简单(但神秘)算法。

![L13-42DirectedGraphs_60]

![L13-42DirectedGraphs_61]

5.4.4:证明

![image-20240309153852150]

证明具有一定的数学复杂性,但编码实现非常简单。

5.4.5:Java 实现

edu.princeton.cs.algs4.KosarajuSharirSCC

![image-20240309154159062]

![image-20240309154252073]

edu.princeton.cs.algs4.KosarajuSharirSCC#dfs

![image-20240309154328483]

edu.princeton.cs.algs4.KosarajuSharirSCC#stronglyConnected

![image-20240309154408874]

6:有向图处理小结

![L13-42DirectedGraphs_65]

(完)

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

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

相关文章

Sftp服务器搭建(linux)

Sftp服务器搭建(linux) 一、基本工作原理 FTP的基本工作原理如下: 1)建立连接:客户端与服务器之间通过TCP/IP建立连接。默认情况下,FTP使用端口号21作为控制连接的端口。​​​​​​​ 2)身…

基于AI软件平台 HEGERLS智能托盘四向车机器人物流仓储解决方案持续升级

随着各大中小型企业对仓储需求的日趋复杂,柔性、离散的物流子系统也不断涌现,各种多类型的智能移动机器人、自动化仓储装备大量陆续的应用于物流行业中,但仅仅依靠传统的物流技术和单点的智能化设备,已经无法更有效的应对这些挑战…

Office 2007软件安装教程(附软件下载地址)

软件简介: 软件【下载地址】获取方式见文末。注:推荐使用,更贴合此安装方法! 微软Office 2007是一款具有重大创新与革命性的办公软件套件。它引入了全新设计的用户界面,提供稳定安全的文件格式,并实现了无…

数据结构 - 堆(优先队列)+ 堆的应用 + 堆练习

文章目录 前言堆一、什么是堆二、堆又分为大根堆和小根堆三、由于堆的逻辑结构被看成完全二叉树,那么我们先来了解一下完全二叉树。四、堆使用数组还是链表储存数据呢?五、数组构建二叉树和父子节点之间的定位六、堆进行的操作七、实现小根堆1、堆的初始…

vue2【详解】生命周期(含父子组件的生命周期顺序)

1——beforeCreate:在内存中创建出vue实例,数据观测 (data observer) 和 event/watcher 事件配置还没调用(data 和 methods 属性还没初始化) 【执行数据观测 (data observer) 和 event/watcher 事件配置】 2——created&#xf…

指纹加密U盘/指纹KEY方案——采用金融级安全芯片 ACH512

方案概述 指纹加密U盘解决方案可实现指纹算法处理、数据安全加密、数据高速存取(EMMC/TF卡/NandFlash),可有效保护用户数据安全。 方案特点 • 采用金融级安全芯片 ACH512 • 存储介质:EMMC、TF卡、NandFlash • 支持全系列国密…

解决白屏问题:让你的网站重焕生机

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

软件测试 —— 如何测试图片上传功能?

作为一名专业的软件测试人员,测试图片上传功能是一个重要的任务,以下是一些测试该功能的常用方法: 1. 上传功能测试:确保图片上传功能正常工作,包括选择图片文件、点击上传按钮、上传进度显示、上传成功/失败的提示等。…

JavaWeb03-HTTP协议,Tomcat,Servlet

目录 一、HTTP协议 1.概述 2.特点 3.请求数据格式 (1)请求行 (2)请求头 (3)请求体 (4)常见请求头 (5)GET和POST请求区别 4.响应数据格式 &#xf…

gRPC-第二代rpc服务

在如今云原生技术的大环境下,rpc服务作为最重要的互联网技术,蓬勃发展,诞生了许多知名基于rpc协议的框架,其中就有本文的主角gRPC技术。 一款高性能、开源的通用rpc框架 作者作为一名在JD实习的Cpper,经过一段时间的学…

Flask python开发篇: 写一个简单的接口

第一步:新建flask项目 参考使用pycharm新建一个项目 打开pycharm,根据下面图中箭头顺序,新建一个flask的项目; 第二步:运行项目, 安装成功以后,会有个app.py文件,打开以后&#…

qt一个项目有且只有有一个maindow,其他小窗口用QWidget,QDialog是带有yes和no的QWidget

QMaindow QWidget QDialog区别很大 我想要在生成一个小窗口,结果选择基类为maindow,应该是QWidget 然后就出现奇奇怪怪的问题 QMaindow和QWidget不能乱选择,而且各自QPaintEvent也有很多区别 以下就是错误: 我继承maindow的基类…

云服务器实例重启后,各个微服务的接口(涉及mysql操作的)都用不了了

问题描述: 云服务器被黑客植入挖矿。重启云服务器实例后得到解决,接着把docker(zookeeper、redis啥的)还有后端jar包啥的都重启了,然后发现后端接口访问不了,只有不涉及数据库操作的接口正常访问&#xff…

【毕业】 医药药店销售管理系统

1、引言 设计结课作业,课程设计无处下手,网页要求的总数量太多?没有合适的模板?数据库,java,python,vue,html作业复杂工程量过大?毕设毫无头绪等等一系列问题。你想要解决的问题&am…

自动驾驶革命:解密端到端背后的数据、算力和AI奇迹

作者 |毫末智行数据智能科学家 贺翔 编辑 |祥威 最近,特斯拉FSD V12的发布引发了业界对端到端自动驾驶的热议,业界纷纷猜测FSD V12的强大能力是如何训练出来的。从马斯克的测试视频可以大致归纳一下FSD V12系统的一些核心特征: 训练数据&am…

防御保护第七次作业-IPSEC VPPN实验

(场景选用点到点,配置好FW1的出接口地址和对端FW3的接口地址,认证方式选用预共享密钥,身份认证选用IP地址) 1、FW1 IP Sec策略配置 IKE参数配置: IP Sec参数: FW2配置: 加密数据流配…

【附教程】2024,人工智能+AI绘画,看这里就够了~14款主流图像生成软件工具总有一个适合你

AI绘画技术通过深度学习和处理海量图像数据,能够迅速将文字描述转化为富有创意和艺术性的画作。这一技术不仅极大地提升了艺术家的创作效率和作品质量,还为他们提供了全新的灵感来源和创作方式,推动了艺术领域的创新与发展。 同时&#xff0…

Redis持久化:RDB和AOF

RDB(Redis DataBase) AOF(Append Only File) AOF重写 RDB AOF 混合持久化 开启 RDB 持久化: RDB 是默认启用的,但你可以检查并设置相关参数以满足你的需求,例如更改保存间隔时间、数据库大…

接口自动化测试框架搭建:基于python+requests+pytest+allure实现

众所周知,目前市面上大部分的企业实施接口自动化最常用的有两种方式: 1、基于代码类的接口自动化,如: PythonRequestsPytestAllure报告定制 2、基于工具类的接口自动化,如: PostmanNewmanJenkinsGit/svnJme…

c++0305习题

一、求下面表达式的值 1.0 2.-1 3.1 4.(1)1 (2)3.2 (3)0 (4)7.0 5.(1)0(2)300.005&a…