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

Linux性能优化--实用工具:性能工具助手

8.0 概述

本章介绍一些在Linux系统上可用的实用程序,它们能够加强性能工具的有效性和可用性。实用工具本身不是性能工具,但是当它们与性能工具一起使用时,它们可以帮助完成如下功能:自动执行繁琐的任务、分析性能统计数据,以及创建性能工具友好的应用程序。
阅读本章后,你将能够:

  1. 定期显示并收集性能数据(bash、watch)。
  2. 记录性能调查过程中所有的命令以及显示的输出(tee、script)。
  3. 导入、分析性能数据并将其图形化(gnumeric)。
  4. 确定应用程序使用的库(ldd)。
  5. 确定链接库中有哪些函数(objdump)。
  6. 研究应用程序的运行时特征(gdb)。
  7. 创建性能工具/调试友好的应用程序(gcc)。

8.1性能工具助手

Linux有着丰富的工具,这些工具一起使用比起单个使用之和的功能更强大。性能工具也是一样的,虽然可以单独使用,但是它们与其他Linux工具结合起来就能够显著提升其有效性和易用性。

8.1.1自动执行和记录命令

如同前面章节所述,性能调查中最有价值的步骤之一就是保存在调查过程中发出的命令和产生的结果。这使得你可以在之后对它们进行回顾并寻求新的见解。为了帮助实现这个目的,Linux提供了两个命令:tee和script,前者能将工具的输出保存为文件,后者能记录每一个按键和屏幕上的每一个输出。这些信息可以保存下来,便于之后查看或者创建脚本来自动执行测试。
自动执行命令很重要,因为它可以减少出错的机会,使你在思考问题时不需记住所有的细节。在你一次性键入又长又复杂的命令行之后,bash shell和watch命令都可以让你周期性地自动执行这些命令。在你保证了命令行的正确性后,bash和watch能够周期性地自动执行它们,不需要再次键入。

8.1.2性能统计信息的绘图与分析

除了记录与自动化工具之外,Linux还提供了强大的分析工具帮助你理解性能统计数据的含义。尽管大多数性能工具可以把性能统计数据输出为文本,但是想要发现其中的模式和随时间变化的趋势并不总是件容易的事儿。Linux提供的gnumeric电子表格很强大,它可以对性能数据进行导入、分析和绘图。当你绘制数据图时,性能问题的原因可能会变得明晰,或者至少能揭示调查的新角度。

8.1.3调查应用程序使用的库

还有一些Linux的工具能使你确定应用程序使用了哪些库,以及显示给定库提供的所有函数。ldd命令给出一个特定应用程序使用的全部共享库的列表。在你想要跟踪被应用程序使用的库的数量和位置时,这个命令很有用。Linux中还有一个命令objdump,它可以在指定库或应用程序中搜索并显示其提供的全部函数。ltrace只能给出一个应用程序调用函数的名称,但是结合命令ldd和objdump,你就能够利用ltrace的输出来确定指定函数属于哪个库。

8.1.4创建和调试应用程序

最后,Linux还为你提供了能够创建性能工具友好型应用程序的工具,以及交互式调试和调查运行中应用程序属性的工具。GNU编译器集(gcc)可以在应用程序中插入调试信息,以帮助oprofile找出某个具体性能问题对应的代码行和源文件。此外,GNU调试器(gdb)还可以用来查找被各种性能工具默认不可得的应用程序的运行时信息。

8.2 工具

本节讨论的工具一起使用时,可以极大地提高前面章节介绍的性能工具的有效性和易用性。

8.2.1 bash

bash是默认的Linux命令行shell,在你每次与Linux命令行交互时,最有可能使用它。bash通常有一个功能强大的脚本语言来创建shell脚本。不过这个脚本语言也可以从命令行调用,从而使你在性能调查过程中,能轻松地将一些比较繁琐的任务进行自动化。

8.2.1.1性能相关的选项

bash有一组命令可以一起使用,来周期性地运行特定命令。大多数Linux用户都把bash作为默认的shell,因此,只要登录到一台机器或打开一个终端就会出现bash提示。如果你没有使用bash,也可以键入bash来调用它。
有了bash命令提示符后,你可以输入一系列的bash脚本命令来自动连续地执行特定命令。在使用特定命令周期性提取性能统计数据的情况下,这个功能非常有用。表8-1给出了这些脚本选项。
在这里插入图片描述
bash极其灵活,它记录在bash手册中。虽然bash非常复杂,但是在使用它之前并不需要完全掌握它。

8.2.1.2 用法示例

虽然有些性能工具,如vmstat和sar,能周期性地更新性能统计信息,但是其他的命令,比如ps和ifconfig则不能。bash可以调用诸如ps或ifconfig命令来周期性地显示它们的统计数据。例如,在清单8.1中,我们要求bash在条件为true时执行while循环。由于true命令总是为真,因此这个while循环永远都不会结束。接着,在do命令后启动每次迭代之后都要执行的命令,这些命令要求bash休眠1秒钟,然后运行ifconfig来抽取eth0控制器的性能信息。不过,我们只关心接收数据包,因此,我们用grep搜索并显示字符串为“RX packets”的ifconfig输出。最后,执行done命令来告诉bash循环完成。由于true命令总是返回真,所以,该循环将一直执行直到用组合键终止它。
在这里插入图片描述
利用清单8.1的bash脚本,可以查看到按秒更新的网络性能统计信息。同样的循环还可以用于监控其他的事件,只要将ifconfig命令修改为其他的命令即可,而通过修改休眠数值也能够改变更新时间间隔。这个简单的循环容易直接在命令行中键入,并且能够自动显示任何你感兴趣的性能统计数据。

8.2.2 tee

tee是一个简单的命令,可以将命令的标准输出保存为文件并同时进行显示。在想要保存并同时查看性能工具输出的时候,tee是很有帮助的。比如,正在监控一个实时系统的性能统计信息的同时,保存这些数据以备将来对它们进行分析。

8.2.2.1性能相关的选项

tee的调用命令行如下:
I tee [-a] [file]
tee获取由提供的输出,在将其保存到指定文件的同时也显示到标准输出设备。如果特别指定了-a选项,则tee会将输出添加到文件上,而不是覆盖文件。

8.2.2.2 用法示例

清单8.2展示了用tee来记录vmstat的输出。如你所见,tee显示了vmstat生成的输出,并同时将其保存到文件/tmp/vmstat_out。保存vmstat的输出能让我们在将来的时间里对性能数据进行分析或绘图。
在这里插入图片描述
tee命令很简单,但由于它能轻松地记录指定性能工具的输出,因此它的能力也是非常强大的。

8.2.3 script

script命令用于将一个shell会话过程中产生的全部输入和输出保存为文本文件。这个文本文件在将来既可以用来重现被执行的命令也可以用来查看结果。在调查性能问题时,准确记录被执行命令是很有用的,因为你可以在之后的时间里查看执行过的测试。拥有被执行命令的记录就意味着在调查不同的问题时,你还可以简单地对命令行进行剪切和粘贴。此外,记录性能结果也是很有帮助的,这样你就可以在将来查看这些记录以寻求发现和解决问题的新视角。

8.2.3.1性能相关的选项

script是一个相对简单的命令。在执行的时候,它会启动一个新的shell,并记录下这个shell存续期间所有的键盘动作和输入,以及生成的输出,并将它们保存到文本文件。script 的调用命令行如下所示:
script [-a] [-t] [file]
默认情况下,script把所有的输出都放到名为typescript的文件中,除非你特别指定其他的文件。表8-2给出了一些script的命令行选项。
在这里插入图片描述
提醒:script字面上的意思是捕捉发送到屏幕的每一种类型的输出。但是,如果有彩色或加粗的输出,就会在输出文件中显示为esc字符。这些字符会明显让输出变得混乱,因此一般不怎么有用。不过,如果将TERM环境变量设置为dumb(在基于csh的shell中用setenv TERM dumb,在基于sh的shell中用export TERM=dumb),应用程序就不会输出转义字符。这就使得输出具有更好的可读性。
此外,script提供的计时信息也会扰乱输出。虽然自动生成计时信息是有用的,但是更方便的做法不是使用script的计时,而是直接用前面章节介绍的time命令来对重要命令进行计时。

8.2.3.2 用法示例

如前所述,如果将终端设置为dumb,会得到可读性更好的script输出。其实现方法是使用如下命令行:
[ezoltewintermute manuscript]$ export TERM=dumb
然后,正式启动script命令。清单8.3显示的是用输出文件ps_output启动的script。script会持续记录会话,直到用exit命令或按下组合键退出该shell。
在这里插入图片描述
接下来,在清单8.4中可以查看由script记录下的输出。如你所见,其中包含了所有的命令以及生成的全部输出。在这里插入图片描述
script是一个非常有用的命令,用来记录会话过程中所有的交互。与现代硬盘容量相比,script产生的文件非常小。记录性能调查会话,并将其保存下来以备将来查看一直都是一个很棒的主意。往最坏的情况考虑,它会浪费一点点精力和磁盘空间来记录会话。往最好的情况考虑,被保存的会话可以在之后的时间查看,而不需要重新运行该会话被记录下的命令。

8.2.4 watch

默认情况下,watch命令会每秒运行一条命令并将其输出显示到屏幕上。与那些不能周期性地显示更新结果的性能工具一起工作时,watch能发挥其作用。比如,有些工具,如ifconfig和ps,显示的是当前性能统计数据,然后退出。由于watch能周期性地执行命令并显示其输出,因此,通过观看屏幕就可以发现哪些统计数据发生了变化,以及它们的变化速率。

8.2.4.1性能相关的选项

watch用如下命令行调用:
watch [-d [=cumulative] ] [-n sec]
如果调用的时候不带参数,watch只会按秒显示给定命令的输出,直到你中断这个过程。默认输出通常很难发现一屏信息与另一屏信息的差异,因此,watch提供了选项来突出显示每个输出之间的不同。这样更容易发现每个采样之间的输出差异。表8-3对watch可接受命令行选项进行了说明。在这里插入图片描述
watch是一种强大的工具,用于查看性能统计数据如何随时间变化。它并不复杂,但是却能很好地完成自己的工作。它真正填补了使用某些性能工具所造成的空白,这些工具无法周期性地显示已更新的输出。在使用这些工具时,你可以用窗口形式运行watch,通过定期查看该窗口来了解统计信息是如何变化的。

8.2.4.2用法示例

清单8.5中的第一个例子展示了与ps命令一起使用的watch。我们要求ps给出每个进程产生的一般故障的数量。watch每10秒清除屏幕,并更新该信息。请注意,可能需要为你要求执行的命令加上引号,这样,watch就不会将你想要执行的命令的选项与它自身的选项搞混。
在这里插入图片描述
watch作为一种工具,其基本功能可以很容易地编写为简单的shell脚本。但是,watch 比使用shell脚本更简单,因为它几乎总是可用的,并且能正确地工作。别忘了,有些性能工具,如ifconfig或ps只能一次性地显示统计数据,而watch却能很容易地跟踪(只需看上一眼)统计数据的变化。

8.2.5gnumeric

在进行性能问题调查时,性能工具常常会生成庞大的性能统计数据。有些时候,梳理这些数据并从中找出能够表明系统运行情况的趋势与模式就成了一个问题。通常电子表格,尤其是gnumeric,能够从三个不同的方面使得这个任务变得容易实现。首先,gnumeric提供了内置函数,比如求最大值、最小值、平均值和标准偏差,这就使你能对性能数据进行数值分析。其次,gnumeric提供了灵活的方式来导入许多性能工具常用输出的表格文本数据。最后,gnumeric还有一个强大的绘图工具,可以将性能工具生成的性能数据可视化。这不但对于探寻较长时间内的数据趋势是极有价值的,而且对于寻找不同类型数据之间的相关性(比如磁盘I/O与CPU使用量之间的相关性)也是相当有用的。通常,要从文本输出中找出模式是比较困难的,但对图形来说,系统行为就会显得更加清晰。其他的电子表格,如OpenOffice的oocalc,也可以使用,不过gnumeric强大的文本导入器和绘图工具使得它成为最容易被使用的工具。

8.2.5.1性能相关的选项

使用电子表格帮助实现性能分析,只需完成以下步骤:

  1. 将性能数据保存到文本文件。
  2. 将文本文件导入到gnumeric。
  3. 分析数据或用数据绘图。
    gnumeric可以生成多种不同类型的图形,并且提供了多种不同的函数实现数据分析。了解gnumeric的强大功能和灵活性的最好方法就是加载一些数据进行实验。
8.2.5.2 用法示例

要展示gnumeric的实用性,首先必须生成用于绘图和分析的性能数据。清单8.6要求vmstat生成100秒的输出,并将该信息保存到文本文件vmstat_output中。数据将会被加载到gnumeric。-n选项表示vmstat只显示头信息一次(而不是每屏信息都显示)。
在这里插入图片描述
接下来,用如下命令启动gnumeric:
[ezoltenohs ezoltjs gnumeric &
这会打开一个空白电子表格用于导入vmstat数据。
在gnumeric中选择File>Open,弹出一个对话框(图中未显示)用于选择打开的文件及该文件的类型。我们选择Text Import(Configurable)作为文件类型,然后通过一系列的向导对话框来选择将vmstat_output文件的哪一列映射到电子表格的哪一列。对vmstat而言,最好从第二行文本开始导入,因为第二行包含了列名称以及每一列适合的大小。此外,为导入数据选择Fixed-Width也是很有用的,其原因是vmstat就是这样输出数据的。在成功导入数据后,我们就会看到如图8-1所示的电子表格。
接下来,利用导入的数据绘图。在图8-2中,我们用不同的CPU使用情况(us、sys、id、wa)创建了一个叠式图。由于这些数据的总和始终为100%(或接近该值),因此,每次都能看出哪种状态处于主导地位。本例中,系统在大部分时间都是空闲的,不过在图中1/4 的部分出现了大量的等待时间。
在这里插入图片描述
在这里插入图片描述
图形是查看一个测试单次运行时,其性能统计数据随时间变化情况的有力手段。同时,对于发现不同运行的对比差异也是很有帮助的。用不同运行得到的数据绘图时,要确保每个图使用的比例是相同的,这能让数据的比较对照更加容易。
gnumeric是一种轻量级的应用程序,它使你能快速简便地导入、绘图/分析大量的性能数据。它是一种很棒的工具,通过处理性能数据来探寻是否出现了任何有趣的特性。

8.2.6 ldd

ldd可以被用来显示特定的二进制文件依赖的是哪个库。ldd有助于跟踪一个应用程序可能使用的库函数的位置。通过给出应用程序正在使用的所有库,就可以对它们进行搜索,找出包含给定函数的库。

8.2.6.1性能相关的选项

ldd用如下命令行调用:
ldd
接着ldd会列出该二进制文件需要的所有库,以及系统中有哪些文件能实现这些需求。

8.2.6.2用法示例

清单8.7展示的是1dd用在二进制文件ls上。在这个特定的例子中,我们可以发现ls使用了如下这些库:linux-gate.so.1,librt.so.1,libaclso.1,libselinux.so.1,libc.so.6,libpthread.so.0,ld-linux.so.2和libattr.so.1。
在这里插入图片描述
ldd是一个相对简单的工具,但对于试图追踪应用程序使用了哪些库以及这些库在系统中的位置来说,它具有极大的价值。

8.2.7 objdump

对于分析二进制文件和库的各个方面来说,objdump是一种复杂而强大的工具。尽管它有许多其他的功能,它可以被用来确定给定的库提供了哪些函数。

8.2.7.1 性能相关的选项

objdump用如下命令行调用:
objdump -T
如果调用的时候使用了-T选项,则它将显示该库/二进制文件所依赖或提供的全部符号。这些符号可以是数据结构,也可以是函数。包含.text的每一行objdump输出都是该二进制文件提供的一个函数。

8.2.7.2 用法示例

清单8.8展示的是objdump用于分析库gtk。因为我们感兴趣的只有libgtk.so提供的符号,所以用fgrep对输出进行选择,仅输出那些包含.text的行。本例中,我们可以看到libgtk.so提供的一些函数,包括gtk_arg_values_equal、gtk_tooltips_set_colors和gtk_viewport_set_hadjustment。
在这里插入图片描述
在使用性能工具时,它们会显示一个应用程序调用的库函数(而不是库本身),objdump 能帮助找到每个函数所在的共享库。

8.2.8 GNU调试器(gdb)

gdb是一个很棒的应用程序调试器,它可以帮助调查一个正在运行的应用程序的多个不同方面。gdb具备三个特性使得它对诊断性能问题来说非常有价值。第一,gdb可以附加到当前正在运行的进程。第二,gdb可以展示该进程的回溯,即显示当前源代码行和调用树。附加到进程并抽取其回溯可以迅速找出一些比较明显的性能问题。但是,如果应用程序不是卡在单点上,那么使用gdb就难以进行问题诊断,此时,系统级的分析器,如oprofile,将会是一个更好的选择。第三,gdb可以将虚拟地址映射回特定的函数。与性能工具相比,gdb更擅长计算虚拟地址的位置。例如,如果oprofile给出了事件发生的虚拟地址而非函数名,那么gdb就可以计算出该地址的函数。

8.2.8.1性能相关的选项

gdb用如下命令行调用,其中,pid是指gdb将要附加的进程:
gdb -p pid
gdb附加到该进程后,它就进入到交互模式,这时就可以检查给定进程的当前执行位置和运行时变量。表8-4对其中的一条命令进行了说明,可用其检查正在运行的进程。
在这里插入图片描述
gdb还有很多命令行选项和运行时控件,它们更适合于调试而不是性能调查。获取更多信息请参见gdb手册页或在gdb提示中键入help。

8.2.8.2用法示例

想要研究gdb是如何工作的,可以先在一个简单的测试应用程序上演示它。清单8.9中的程序在main中只调用了函数a(),并陷入了一个无限循环。这个程序不会结束,因此当我们将gdb附加上去后,它将会一直执行函数a()的无限循环。在这里插入图片描述
清单8.10启动应用程序并用gdb附加到它的pid。我们要求gdb产生一个回溯,以便展示当前正在执行的究竟是哪条代码,以及哪组函数调用会导致当前的位置。如同预期的,gdb显示出正在执行的是无限循环a(),它是由main()调用的。
在这里插入图片描述
最后,在清单8.11中,我们要求gdb给出虚拟地址0x0804832F的位置,而gdb显示该地址是函数main的一部分。
在这里插入图片描述
gdb是一个极其强大的调试器,可以帮助调查性能问题。如果你想要知道特定代码路径发生的确切原因,那么gdb甚至在性能问题已经确定之后也能够发挥作用。

8.2.9 gcc(GNU编译器套件)

gcc是Linux系统中最流行的编译器。与所有的编译器一样,gcc需要源代码(如C、C++或Objective-C)生成二进制代码。它提供了多个选项不仅可以对得到的二进制代码进行优化,还能让应用程序的性能跟踪变得更容易。本书不涉及gcc性能优化的详细内容,但是如果想要提高应用程序的性能,你就应该研究一下这些内容。gcc提供的性能优化选项通过多种优化来调整已编译的二进制文件的性能,这些优化包括:架构通用优化(使用-01、-02、-03),特定架构优化(-march和-mcpu),以及基于反馈的优化(使用-fprofile -arcs和-fbranch-probabilities)。更多的优化选项详情请参阅gcc手册页。

8.2.9.1性能相关的选项

gcc最基本的调用格式如下所示:
gcc [-g level] [-pg] -0 prog_name source.c
gcc有数量庞大的选项来影响它对应用程序的编译。如果你有勇气的话,可以到gcc手册页上查阅它们。表8-5给出了有助于性能调查的具体选项。
在这里插入图片描述
许多性能调查工具,如oprofile,需要用调试信息编译应用程序,以便将性能信息映射回特定的应用程序源代码行。如果没有调试信息,它们一般也还是可以工作,但是如果启动调试,那么它们将会提供更丰富的信息。应用程序分析的更多信息参见前面的章节。

8.2.9.2用法示例

理解gcc可以提供的调试信息类型的最好方法可能就是看一个简单的例子。清单8.12 中有一个C应用程序的源代码deep.c,该程序仅调用了一组函数,然后根据传递的数字输出一定数量的字符串“hi”。程序的main函数调用函数a(),函数a()调用函数b(),然后输出“hi”。
在这里插入图片描述
在这里插入图片描述
首先,如清单8.13所示,编译该程序时不带任何调试信息。在调试器中启动该程序,在函数b()上添加一个断点。当程序运行时,它会在函数b()处暂停,并请求回溯。gdb可以弄清楚回溯,但是它并不知道函数之间传递了什么样的值或者函数存在于原始源代码文件中的什么位置。
在这里插入图片描述
清单8.14启动调试信息对同样的应用程序进行编译。现在,当运行gdb并产生回溯时,我们可以看到每个函数调用传递的数值,以及特定代码行所驻留的准确的源代码行。
在这里插入图片描述
在这里插入图片描述
调试信息会显著增加gcc最终生成的可执行文件的大小。但是,在追踪性能问题时,由其提供的信息却是无价的。

8.3 本章小结

本章给出了对调查性能问题有用的各种Linux实用工具的集合。首先介绍的工具如bash、watch、tee和script能自动显示和收集性能数据。之后介绍了gnumeric,该工具可以对基于文本的性能工具所得到的结果进行绘图和分析。之后研究了ldd和objdump,它们可用于发现一个函数属于哪个库。接着本章描述了gdb,它能够被用来调查当前正在运行的应用程序的执行和运行时信息。最后,本章给出了gcc,该工具可生成带符号调试信息的二进制文件,这可以帮助其他性能工具,如oprofile,将事件映射回一个特定的源代码行。
在之后的章节中,我们将集合迄今为止提出的所有工具,以解决一些现实的性能问题。

相关文章:

Linux性能优化--实用工具:性能工具助手

8.0 概述 本章介绍一些在Linux系统上可用的实用程序,它们能够加强性能工具的有效性和可用性。实用工具本身不是性能工具,但是当它们与性能工具一起使用时,它们可以帮助完成如下功能:自动执行繁琐的任务、分析性能统计数据&#x…...

[PyTorch]即插即用的热力图生成

先上张效果图,本来打算移植霹雳老师的使用Pytorch实现Grad-CAM并绘制热力图。但是看了下代码,需要骨干网络按照标准写法(即将特征层封装为features数组),而我写的网络图省事并没有进行封装,改造网络的代价又…...

golang笔记18--go并发多线程

golang笔记18--go并发多线程 介绍核心用法MutexRWMutexWaitGroupCondOncemapPoolContextselect 注意事项参考文档 介绍 大家都知道go语言近年来越来越火了,其中有一个要点是go语言在并发场景有很高的性能,比如可以通过启动很多个 goroutine 来执行并发任…...

使用OkHttp和Java来下载

以下是一个使用OkHttp和Java来下载内容的下载器程序,同时使用了jshk.com.cn/get_proxy来获取代理服务器。请注意,为了简化代码,我们将忽略一些异常处理和安全性检查。 import java.io.File;import java.io.FileOutputStream;import java.io.I…...

HttpServlet源码分析及HttpServletRequest接口

2023.10.20 HttpServlet HttpServlet类是专门为HTTP协议准备的。比GenericServlet更加适合HTTP协议下的开发。 http包下都有哪些类和接口呢?(jakarta.servlet.http.*) jakarta.servlet.http.HttpServlet (HTTP协议专用的Servlet…...

CENTOS 7基于ISO文件进行安装新软件

众所周知,YUM是CENTOS7的安装程序。 普通情况下,连网之后 ,用yum install 就可以安装。 但当网络环境经常出现连接失败的情况,默认情况下的行为就走不通了。 为解决这个问题,可以考虑如下三个方案 方案一:Y…...

模拟器-雷电-使用adb push或adb pull操作文件

一、环境 windows 10 雷电模拟器4.0.83 二、问题 有时候我们会需要往模拟器拷贝文件或者复制文件到我的电脑 三、方法 1、获取root权限 adb root adb remount 有可能遇到【daemon not running; starting now at tcp:5037】的报错 查看端口占用进程:netstat -…...

【前端设计模式】之命令模式

引言 命令设计模式是一种行为型设计模式,它允许你将命令封装到一个对象中,从而使你可以参数化不同的请求,以及存储、排队、重播和撤销请求。这种设计模式在处理用户界面操作、远程网络请求或其他需要异步执行的操作时非常有用。在前端开发中…...

用c++写一个高精度计算的乘法运算

这段代码是一个用C编写的程序&#xff0c;它实现了两个大整数的乘法运算。 #include<iostream> #include<cstdio> #include<cstring> using namespace std;int main(){char a1[101]"222",b1[101]"2";int a[101],b[101],c[10001],lena,l…...

UE5 ChaosVehicles载具 实现大漂移 (连载四)

载具设置成前驱模式 前轮摩擦力倍增x5 后轮摩擦力倍增x0.5...

基于Arrow的轻量线程池

基于Arrow的轻量线程池 大家好&#xff0c;我是光城&#xff0c;最近花了几周业余时间&#xff0c;开发出这款轻量线程池&#xff0c;代码也全部开源啦&#xff0c;欢迎大家star。 本线程池的设计与实现会有涉及非常多的知识&#xff0c;这些内容也都会以视频的方式分享在知识星…...

泛微OA E-Office V10 OfficeServer 任意文件上传漏洞复现

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 漏洞简介 泛微e-ofice是一款标准化的协同0A办公软件&#xff0c;泛微 …...

spring-cloud-starter-gateway踩坑

1.bean of type org.springframework.http.codec.ServerCodecConfigurer that could not be found. 需要将项目中用到的spring-boot-starter-web依赖给去掉 去掉以下的 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…...

视频SDK开发,多平台SDK快速接入

随着科技的不断发展&#xff0c;视频已经成为了企业业务中不可或缺的一部分。无论是在线教育、企业培训还是产品展示&#xff0c;视频都发挥着至关重要的作用。为了满足企业对视频应用的需求&#xff0c;美摄视频SDK应运而生&#xff0c;为企业提供了一站式的视频解决方案。 一…...

面试官:如何理解CDN?说说实现原理?

一、是什么 CDN (全称 Content Delivery Network)&#xff0c;即内容分发网络 构建在现有网络基础之上的智能虚拟网络&#xff0c;依靠部署在各地的边缘服务器&#xff0c;通过中心平台的负载均衡、内容分发、调度等功能模块&#xff0c;使用户就近获取所需内容&#xff0c;降…...

C语言 牛客网习题 10.20 day2

1.求最小公倍数 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值&#xff0c;设计一个算法&#xff0c;求输入A和B的最小公倍数。 1≤a, b≤100000 输入描述&#xff1a; 输入两个正整数A和B。 输出描述&#xff1a; 输出A和B的最小公倍数。 #include <st…...

SpringCloud: sentinel热点参数限制

一、定义controller package cn.edu.tju.controller;import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.web.bind.annotation.PathVariable; import org.springframewo…...

PDF编辑阅读 PDF Expert v3.5.2

PDF Expert是由Readdle开发的一款专业的PDF编辑和阅读工具。它可以帮助用户在Mac、iPad和iPhone等设备上查看、注释、编辑、填写和签署PDF文档。 以下是PDF Expert的特点&#xff1a; PDF编辑&#xff1a;PDF Expert提供了丰富的PDF编辑功能&#xff0c;包括添加、删除、移动…...

新技术:WEB组态能页面嵌套、属性继承吗?

目前市面上的工业组态或数据大屏工具有不少&#xff0c;也有很多0代码、无代码、低代码、零代码、低代码概念。 有没有可以支持图纸嵌套、属性暴露的&#xff1f;或者说页面任意嵌套、属性多继承暴露到上层&#xff1f; 比如页面A有输入框&#xff0c;页面B有对话框&#xff…...

【C++ Primer Plus学习记录】复习题

1.如何声明下述数据&#xff1f; a.actor是由30个char组成的数组。 char actor[30]; b.betsie是由100个short组成的数组。 short betsie[100]; c.chuck是由13个float组成的数组。 flaot chuck[13]; d.dipsea是由64个long double组成的数组。 long double dipsea[64]; …...

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

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

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...