直播 RTM 推流在抖音的应用与优化

news2024/11/15 9:23:45

动手点关注

97208aa7d3d336645be1b540187b4d2c.gif

干货不迷路

背景

随着互联网技术以及网络基建的快速发展和普及,视频直播已经成为了一种越来越普遍的娱乐和社交方式。无论是个人还是企业,都可以通过视频直播平台进行直播活动,向观众展示自己的生活、工作或者产品。同时,视频直播也成为了一种新型的社交媒体,让人们可以在虚拟空间中进行互动交流。

RTM(Real Time Media,低延时直播)是近期逐步兴起的一种以提升客户交互体验为目标的直播解决方案,它的特点是较传统的直播解决方案,端到端延时更小达到 1 秒级别,卡顿无明显负向,RTM 的网络传输层是基于 WebRTC 技术的(RTP/RTCP 协议)。

RTM 推流相比于传统的 RTMP 推流,在网络变化响应灵敏度、弱网对抗、带宽利用率等方面都有明显优势。在抖音的 AB 实验中主播人均被看播时长/被关注/被评论显著正向,拉流音频/视频卡顿 -22.2%/-7.8%,端到端延迟 -1.6%。目前 RTM 推流在抖音秀场完成了 10% 左右的常规放量。

技术架构

CDN 技术架构

目前 CDN 厂商对 RTM 的支持主要有两种技术架构,一种是基于传统的 RTMP/FLV 架构,在推拉流边缘节点增加 RTM 接入协议的支持,CDN 集群内部复用传统架构,另一种是 CDN 内部集群也采用 RTP/RTCP 协议和架构。CDN 的技术架构如下图所示:

d52456728d1b01878aa322a9be7a268d.png

客户端技术架构

在推流客户端,RTM 推流网络传输层使用了火山引擎自研 RTC SDK(VolcEngineRTC),在设计之初,为了支持业务无缝接入,以及最大化复用已有能力、避免重复造轮子,RTM 推流在客户端采用了 LiveCore(火山引擎自研直播推流 SDK)编码音视频 + VolcEngineRTC 传输的技术架构,如下图所示:

1691e3b692e0f8c6e499bc326365df67.png

主要包括三部分:

  • 推流建立连接时,LiveCore 调用 RTM 推流引擎的接口,RTM SDK 内部的 RTC 标准 SDP 信令管理模块,通过 VolcEngineRTC 的 W3C 标准 WebRTC 接口,和 CDN 服务端完成信令协商,信令交换使用的是 HTTP/HTTPS 协议(图中的红色箭头)

  • 推流过程中,LiveCore 完成音视频采集、编码,把编码后的 AAC 和 H.264/H.265 码流,送入 RTM 推流引擎,RTM 推流引擎再通过 VolcEngineRTC 的外部音视频源私有接口,把音视频码流送入 VolcEngineRTC,进而封装为 RTP/SRTP 包,发送到 CDN 服务端(图中的蓝色箭头)

  • 推流过程中,VolcEngineRTC 内部的网络传输引擎,对网络状态进行追踪,预估出网络可用带宽,并进行编码器带宽分配,再通过 VolcEngineRTC 私有接口回调到 RTM 推流引擎,最后再反馈到 LiveCore 的视频编码模块,进行视频编码码率调节(图中的黄色箭头)

技术优化

功能补齐和稳定性打磨

因为 RTM 是近期逐步兴起的直播解决方案,无论是在 CDN 服务端,还是客户端 SDK,都处于发展早期,功能仍有诸多欠缺,比如最初只有两家 CDN 支持 RTM 推流,音视频编码格式的兼容性也有欠缺,HE AAC、H.265 和视频 B 帧在前期联调阶段都是不支持的,而且稳定性也有待打磨,在联调和灰度放量过程中,多次遇到过花屏问题。

关于功能和稳定性,这里我们分享两个案例:支持视频 B 帧,解决花屏问题。

支持视频 B 帧

WebRTC 标准本身是不支持视频 B 帧的,因为 WebRTC 的设计初衷就是实时通话(RTC)场景,而视频编码开启 B 帧会引入额外的延迟,影响通话体验。但在直播场景,对延迟的要求比 RTC 要宽松很多,而开启 B 帧能提高视频压缩效率,可以提升画质或者节省带宽成本,所以在直播场景开启 B 帧是很普遍的做法。

下面是互娱-评测实验室同学针对开 B 帧进行的画质测评结论:

【互娱-评测实验室】抖音直播 Android 软编开 B 帧降码率画质评测报告

结合主客观表现,Android 设置软编 + B 帧后,静态清晰度与硬编无明显差异,但马赛克明显增多,劣化幅度较大, 软编各个降码率点之间马赛克差距不大(0.9、0.88、0.85、0.82)

主观画质:

  • 马赛克表现: 秀场场景,相较于硬编软编动态场景下均存在明显马赛克;PK 场景:软编动态场景存在轻微马赛克,稍差于硬编

  • 清晰度 表现: 软编面部纹理细节表现略优于硬编,各个降码率档位清晰度与不降码率差异主观感知不明显

客观画质:

  • VMAF 硬编切软编后,指标下降较明显,软编各个降码率点之间指标下降不明显

  • Acutance(图卡清晰度指标):硬编切软编后,指标下降较明显,软编各个降码率点之间指标下降不明显

acfd1a6ecfe97497416da5756d5e698f.png

9a00689c722bb9a9d61e1025fc40174b.png

b02495f8bbabde955a7607b5d893e363.png

测评发现虽然软编和硬编的主客观清晰度有比较明显的差异,但是在软编的情况下(都开了 B 帧),降低编码码率主客观清晰度都没有明显的差异。

为了支持 B 帧,我们需要对 WebRTC 进行媒体能力协商的 SDP 标准进行扩展,下面是《超低延时直播技术白皮书》(https://www.volcengine.com/docs/6469/103017#%E8%A7%86%E9%A2%91-b-%E5%B8%A7%E6%94%AF%E6%8C%81)中关于视频 B 帧支持的相关扩展定义:

SDP 视频 B 协商

客户端需要在 Offer SDP 中添加 B 帧相关信息,实现 B 帧 timestamp 非单调递增的处理逻辑,后台则需要实现相应 B 帧 timestamp 封装逻辑。SDP B 帧协商示例如下所示。

...
a=rtpmap:96 H264/90000
a=fmtp:96 BFrame-enabled=1;level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
...

SDP 中的 BFrame-enabled 代表客户端是否支持解码 B 帧。不代表服务端是否支持发送 B 帧。

  1. OfferSDP中BFrame-enabled=0,源流带 B 帧,则服务器把源流B帧去除后再转发客户端。

  2. OfferSDP中BFrame-enabled=0,源流不带 B 帧,则服务器把源流直接转发客户端。

  3. OfferSDP中BFrame-enabled=1,源流带 B 帧,则服务器把源流直接转发客户端。

  4. OfferSDP中BFrame-enabled=1,源流不带 B 帧,则服务器把源流直接转发客户端。

视频 B 时间戳计算

视频 B 帧时间戳计算方式有 2 种。

  • 建议规范 1: 每个 RTP 包的 rtp timestamp 携带当前帧数据的采样时间即 PTS,解码顺序附着于 SequenceNumber 顺序, 客户端不能直接计算出 DTS 的值,此种规范下在有 B 帧的时候不便于快速解码和出帧。

  • 建议规范 2:使用 RTP 私有扩展头携带 CTS 值,每个 RTP 包的 RTP timestamp 携带当前帧数据的采样时间即 PTS, 每一帧首个 RTP 包和 VPS/SPS/PPS 包通过 RFC5285-Header-Extension 扩展头携带该帧的 CTS 值,通过 DTS = PTS - CTS * 90 公式计算出当前帧的解码时间戳。SDP extmap 示例如下所示。

...
a=rtpmap:96 H264/90000
a=fmtp:96 BFrame-enabled=1;
a=extmap:7 rtp-hrdext:video:CompistionTime
...
  • 以上两种方式可以兼容,当 offer sdp 有相应 extmap rtp-hrdext 字段时采用规范 2,否则采用规范 1。

在 RTM 推流立项之初,VolcEngineRTC 对推流视频 B 帧的支持也是欠缺的,我们也对 VolcEngineRTC 的代码仓库提交了相关修改的 MR,并推动 CDN 服务端进行开发、联调,最终通过灰度放量,验证了功能和稳定性问题,完成了对视频 B 帧的支持。

解决花屏问题

花屏的可能原因很多,从主播端到观众端的整个链路中,任何一个环节都可能出错导致花屏,下面是典型的视频全链路涉及到的环节:

ae066176283bd0e56ff8068972fd7e16.png

用户有两个环节会观察到花屏现象:主播的预览和观众的渲染。但问题不一定出在这两个环节,尤其是观众看到花屏时,就可能是编码器有 bug,推流传输过程丢失了视频参考帧,CDN 下发给观众端的数据出现了错误,解码器有 bug,或者渲染模块有 bug。

排查花屏问题最常用、也是最有效的手段,就是在一些关键环节的位置,保存视频码流数据,用可信的程序(比如 ffmpeg)验证到这个环节的数据是否正常,比如在推流端把编码器输出的数据写入到本地,抓取发送的数据包,或者在服务端抓包。

除了直接用 ffplay 播放观察是否花屏(或者 ffplay 控制台是否打印了错误日志),我们还可以用下面的 ffmpeg 命令,把视频的每一帧都导出为图片:

ffmpeg -i test.flv frames/$filename%03d.bmp

比如我们某次排查花屏问题时,就发现是从第 30 帧开始出现花屏:

100fcc5825329d43599da3d7b0da4432.png

而这个 flv 文件是 QA 同学在测试过程中使用 wget 命令保存的拉流 url 的数据,并且推流端的抓包码流播放并不会花屏,所以就实锤是 CDN 的问题了。

在 RTM 推流的联调和灰度放量过程中,多次遇到过花屏问题,每次出问题的环节都不一样,可以说基本上把坑都趟了个遍,这里就不一一展开介绍了,感兴趣的同学欢迎线下交流。

卡顿优化

功能和稳定性问题解决之后,我们在线下使用公司内部的 ByNet 弱网模拟工具测试发现,RTM 推流在弱网下的表现很差(测试基于 iOS 系统,视频编码格式为 H.265,分辨率 720p,码率自适应范围为 440kbps~1833kbps):

15a7114340b8bbfdabec4cfc2e940726.png

5% 丢包 150ms rtt 的情况,RTM 推流就已经卡得无法播放了(表格中的 -- 表示基本无法播放,数据无法统计)。

经过和各家 CDN 服务端的联合分析,我们发现了几个问题:

  • 某云 CDN 发送的音频 NACK 包没有携带正确的 sender ssrc,导致丢失的音频包没有重传;

  • VolcEngineRTC 发送 RTCP XR 报文时 DLRR block 有问题,导致 CDN 无法正常估算网络 rtt,视频重传次数很快用完,进而导致视频重传也基本无效;

  • CDN 推流边缘节点视频组帧之前的 buffer 过小,导致客户端重传的视频包也基本没有生效;

  • CDN 没有启用 TCC 算法(之前用的 REMB 算法),推流端对网络状态的适应能力差;

在技术架构上,火山引擎直播 CDN 采用的是上文介绍的第一种技术架构,即边缘的收流节点会把 RTP 包组帧,转换成 RTMP/FLV 流推到源站,这里我们展开介绍火山引擎直播 CDN 在组帧环节做的两个优化。

jitter buffer:针对抖动、乱序、丢包重传场景,如果 CDN 接收组帧 buffer 设置得太小,就会导致帧丢失和 GOP 丢失,从而影响用户观看直播的流畅度并引起卡顿感;如果 CDN 接收组帧 buffer 设置太大,则由于组帧引入的延迟就很大,降低直播的交互性。为了解决这个问题,我们参考 WebRTC 的 NetEQ,引入了网络自适应的 buffer,即通过估算推流侧的网络抖动设置接收组帧 buffer 大小。对于大部分网络较好的推流,组帧 buffer 引入的延时极小;对于抖动、乱序、丢包重传的推流,又可以保障流畅性同时尽可能少引入延时。

组帧交织:UDP 数据包不保证到达顺序、视频组帧抖动等因素,会引起转换出 RTMP/FLV 流中的音视频不严格交织,有的视频连续 3~4s 都没有音频(或反过来)。在拉流端到端延时低至 2~3s 的背景下,播放端会因为音画同步机制引入卡顿,影响用户看播体验。对于这个问题,我们在 CDN 接收组帧的 jitter buffer 出帧时,结合音视频 jitter buffer 的长度,做了音视频交织,确保音视频帧尽量均匀,dts 差距不能过大。经过线上验证,不交织引起的播放卡顿显著下降。

上述问题都解决之后,再次进行模拟弱网测试,结果有了很大的改善:

60988b0ce3404d01e76eb7717836153b.png

可以看到在 10% 丢包 150ms rtt 时,推流仍保持在自适应的最高码率进行推流,并且拉流也没有任何卡顿。不过在丢包率增加到 15% 甚至 20% 时,RTM 推流的效果也基本就不行了,但我们分析线上数据发现,丢包率超过 10% 的情况占比很少,所以就没有继续优化了。

最后我们请视频云团队的音视频实验室对 RTM 推流和 RTMP 推流在抖音上进行了权威的测评,测评结果为:

「抖音推流」RTM vs RTMP 评测报告

  • 弱网下:各指标均优于 RTMP

  • 正常网络下:视频首帧、视频延时、音频延时优于 RTMP,视频卡顿、音频卡顿、音画同步和画质基本持平 RTMP

7cd9ac7d33888d921ba50ed6ed1e08aa.png

算法优化

经过上述一系列工程优化,最后开启线上 AB 实验,相比基线算法 RTMP,结果却不如预期:QoE 开播场次无明显趋势,开播时长稳定偏负,被看播指标无明显趋势,QoS 音频渲染百秒卡顿时长/次数 -3.641%/-4.649%,视频渲染百秒卡顿时长/次数 -2.926%/-8.044%。

直观的疑问是:为什么 QoS 卡顿有收益了却没有 QoE 收益,甚至 QoE 还是负向?

为了探寻原因和更好的进行下一步迭代优化,我们开始深入到 RTM 算法部分进行研究。

问题分析

黑盒测评分析

基于抖音 app 测试推流,拉流影响则使用了拉流 demo

无网损场景、相同直播推流内容下,测试发现,RTM 比 RTMP 目标码率更加保守。e.g.


RTM(TCC 开启)RTMP(TCP)
1080p(1088x1920)

db110618211b33d7a8a258f4d3928a03.png

728cb2b1b22a8e3ba6b0f348282dd9b6.png

2Mbps 网损下,RTM 带宽利用率仅 50%,对于拉流侧的影响则是画质损伤严重,e.g.

a811ea91e9ab495c764b962a2aa0465f.png

RTM(TCC 开启)的 2Mbps 网损下画面质量(左)无网损画面质量(右)

5fd822a710d262b08491a8c9ac9a3d8f.png

这意味着 RTM 在部分场景下通过牺牲画质体验置换来了卡顿收益。

基于线上大规模数据分析

我们基于抖音的数据集,分析出了以下 3 类关键问题:

1、bwe 周期性震荡问题

红色线 bwe 震荡波动,大概率会导致黄色线目标码率震荡波动;bwe 的波动不是因为高丢包率,rtt 也是在绝对值较小(100ms 以内)范围内波动。

f5ccd6cfb66924e625b6d436f2a60bc9.png

2、目标码率周期性震荡问题

目标码率自身震荡波动,不是受 bwe 影响的(bwe 是稳态的)

d22a018c7704ea6a861afb8d1841df97.png

3、传输能力足够,固定式码表限制了画质提升

bwe 高达 8Mbps 以上,而 max bitrate 才3Mbps 左右

2a21bcdc8316679aa2f0d06f077ffe67.png

我们还量化识别了问题类型在全部数据集中的重要程度情况:

  • bwe 波动较普遍(19.7%),且 bwe 波动几乎都会引起目标码率波动

  • 目标码率波动更普遍(28.3%),但不一定是由 bwe 波动引起的

  • 在低带宽场景下更容易产生 bwe 波动

1cb7ccf855b3f016ed40f1fd618669dd.png

689b6a533fa2fe7fa25f3cbdade10591.png

白盒测试复现问题及根因分析

我们选取了 典型的非稳态网络场景进行上述问题复现实验,并对算法内部原理进行分析,发现:

在非弱网比如只是 rtt 较小范围(150 以内)抖动的网络场景下,VolcEngineRTC TCC 带宽估计算法中,delay_based_bwe 部分,trendline estimator 对时延信号太过敏感,经常误判弱网,导致周期性下调估计的带宽值,从而降低了带宽利用率。

具体分析过程如下:

首先是复现问题场景,这里举例2个场景来说明。4Mbps 带宽+时延波动场景(左图)的实验表现和前面线上埋点(5 秒级别)的波动现象吻合,当bwe波动在码表范围内,该测试场景复现了线上 bwe 波动的问题场景;带宽泊松波动场景(右图)周期性波动问题复现更加明显。

adb774a399965764ef60ae6bb9f5f9f0.png

其次,进行问题根因定位。bwe 波动的根因在于算法频繁置位 overuse (左图)来降低所估计的带宽,而 overuse 的判别逻辑在 delay_based_bwe 部分,trendline estimator(基于趋势线的时延估计器)这里把时延抖动误判成了弱网(注:误判是指实际的rtt和丢包情况均不表现为弱网特征,如右图的子图4和子5)。

ad81f8b5f07f772c88e76981b3572433.png

解决方案

带宽估计算法

1、调优已有 VolcEngineRTC bwe 算法模型参数

无须写代码、等待发版周期,以最快速度缓解问题

我们梳理了 VolcEngineRTC 代码逻辑以及 bwe 算法参数。好处是可以很方便的通过线上配置直接修改做实验,但是缺点是参数太多、调参太耗费精力且很大可能是收益非常有限(理论上参数的默认值应该就是一个推荐的最优值了),最终我们决定先凭借经验挑选了几个关键参数作为一期方案优化,离线验证调参的收益后就开展一期方案线上 AB 实验,期间也为我们留下了相对充足的时间去做后期优化。

757243d2fea37c3d487bbd8387e6b447.png

2、Beyond VolcEngineRTC bwe 算法,进行线上问题模式检测与 bwe 模型纠正

最小化对 VolcEngineRTC 代码/bwe 算法模型的入侵修改,同时达到解决问题的目的

我们在 bwe 算法之上,引入周期性震荡场景识别及平滑策略,以改善带宽估计的准确性、提升带宽利用率,进而提升视频画质。

码控算法

1、解耦码控算法与带宽估计算法

在原来 RTM 推流的架构下,没有单独的码率控制算法,码控的上下界由 LiveCore 的码表决定,在上下界之间如何变化则完全是由 VolcEngineRTC bwe 算法决定。

上述架构存在以下 2 个问题:

A. bwe 算法的问题会直接体现在码控层面,e.g. 前面的问题类型(bwe 震荡波动几乎一定会引起码率震荡波动,进而导致画质问题,e.g. 业务方反馈的推流码率突降导致画面模糊的问题)

22626e4c7201a0529d705e1001e0f2ed.png

B. 码控算法很好地利用了 VolcEngineRTC 弱网感知优势,却忘记了利用 VolcEngineRTC 的强网感知优势,e.g. 当带宽估计值超过码表码率上界时,还可以超越码表上界再进一步提升码率(非中国区码表上界比中国区低很多),从而提升画质。

因此,我们将传输层的 bwe 算法和应用层的码控算法进行了解耦。在 RTM SDK 层面设计实现单独的码控算法,可以更加灵活的根据业务场景/需求设计码控策略。

2、目标码率波动在线识别和平滑策略

与 bwe 算法的震荡波动识别和平滑思路类似,设计在线检测算法识别码率周期性波动并进行码率平滑。码控算法不一定要听从 bwe 算法,因为 bwe 算法也可能误判,此外,非实时通讯的直播场景下,秒级的端到端延时、推流拉流均有buffer情况下,不一定要立即响应带宽的波动,码控算法可以选择性的在清晰度和流畅度(卡顿)之间平衡,根据线上实验用户体验偏好进行迭代。

9404b37f9d73b32a8630da6703b35d04.png

算法优化离线效果评估

在有限的测试场景下

  • 弱网场景

    • bwe 波动识别与平滑方案开启 vs 该方案关闭

      bwe 波动识别与平滑方案对 bw、rtt 抖动场景的 bwe 进行了有效的平滑,特别是 rtt jitter 场景下有效去除了部分不必要的码率下调,有约 10% 的码率收益;

    • 码控码率波动识别与平滑开启 vs 该方案关闭

      码控优化点 2 即使在 bwe 波动识别与平滑方案关闭的情况下也可平滑一定的网络震荡(特别是 bwe 波动场景下);码控优化方案整体在强网下 PSNR 有约 6% 的收益(720p);

    • bwe 波动识别与平滑方案叠加码率波动识别与平滑效果

         两者无冲突,在带宽剧烈波动场景下叠加生效有带宽利用收益;

  • 强网场景

    • 相比对照组无负向效果,以上实验中拉流侧均未出现卡顿。

942807fe7cad61269d861c5b2d7f332c.png

综上,在有限测试场景下,bwe 波动识别与平滑方案在 rtt jitter 场景有更明显的码率收益,而码率波动识别与平滑方案在 bwe jitter 场景有明显的画质收益,两者叠加在两种场景下均有较好的码率收益。

优化结果

目前为止,我们的 RTM 方案在抖音已经落地以及完成放量,在抖音的指标收益主要在主播人均被看播时长/被关注/被评论显著正向,拉流音频/视频卡顿 -22.2%/-7.8%,端到端延迟 -1.6%。

未来展望

目前 RTM 推流在抖音秀场完成了 10% 左右的常规放量,但 RTM 推流的效果远远没有达到最佳状态,仍有很多优化工作需要推进。

从工程优化角度,下一步工作考虑以下几方面:

  • 更多家 CDN 的支持,目前只有三家 CDN 完成了接入和灰度放量,覆盖率还需要提高;

  • 目前 RTM 推流和 CDN 服务端交换 SDP 使用的是 HTTP/HTTPS 信令,在网络较差的情况下有一定的失败率,使用数据压缩、基于 UDP 的 MiniSDP 信令,可以提升推流建立连接的成功率;

  • 在 RTT 很高、丢包率较低的弱网场景,使用 FEC 的效率要比重传更高,预期可以进一步提升弱网抗性;

  • 目前 RTM 推流的 CPU 占用是比 RTMP 要高一点的,而且 RTMP 推流本身功耗也是比较高的,所以性能功耗方面也需要做一些优化,改进主播的开播耗电和发热体验;

从算法优化和创新角度,我们考虑以下几点:

  • 虽然通过这次优化我们解决了 VolcEngineRTC 的 bwe 算法在一些场景下的问题,但是在另一些场景下相比 RTMP over TCP 方案,RTM 并不拥有绝对优势。未来还要继续努力针对这些场景进行优化,进一步提高网络带宽的利用率以及弱网抗性,从而提升 bwe 算法的核心竞争力;

  • RTM 码控算法方面,颠覆现有/传统的只以码率为锚的控制方式,面向最小化码率最大化画质体验做策略控制,向体验和成本极致优化方向演进;

  • 目前看到工业界宣传文章中有类似 RTM 推流的技术在应用,但在多媒体和网络领域的顶级会议上较少看到相关创新算法的文献,未来考虑将我们的更多创新技术转化成论文的形式,弥补学术界空白,提升公司在多媒体和网络领域的影响力;

  • RTM 的码控算法优化思路,在 RTMP over QUIC 的场景也是适用的,后续我们会把码控算法和传输协议代码进行解耦,以便码控算法的优化也能在 RTMP over QUIC 场景落地,并通过 AB 实验探索不同传输协议各自更适用的场景。

加入我们

字节跳动视频架构是字节跳动的视频中台部门,支持字节跳动旗下产品的点播、直播、实时通信、图片、多媒体业务发展,目标成为业界多媒体解决方案领先者,构建极致的视频技术/产品服务体验。

扫描下方二维码 or 点击文末阅读原文进行简历投递,加入我们,让我们一起做多媒体领域的领军者!

6470f76c3f0e08c853cbe91b8206be58.png

Windows 直播研发工程师-视频架构(北京/上海/深圳职位开放)

8cb08d145eafe50d690f915b6304d686.png 点击「阅读原文」即刻投递

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

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

相关文章

有什么办法恢复格式后的u盘数据?5个方法,赶紧收藏起来

随着科技的不断进步,U盘已经成为了我们重要的移动存储设备之一,但是在使用过程中,很多人都可能会不小心将U盘格式化导致数据丢失。那么有什么办法恢复格式后的U盘数据?本文将会为您介绍恢复U盘格式化后数据的5种方法,如…

MT6761/MT6762/MT6765核心板模块 demo串口调试

串口调试 如果正在进行lk(little kernel ) 或内核开发,USB 串口适配器( USB 转串口 TTL 适配器的简称)对于检查系统启动日志非常有用,特别是在没有图形桌面显示的情况下。 1. 选购适配器 常用的许多 USB 转串口的适配器&#x…

SpringCloud:分布式事务Seata实践优化

1.极致性能优化 1.1. 同库模式 通常,一个TM会产生一笔主事务日志,一个RM会产生一条分支事务日志,每个分布式事务由一个TM和若干 RM组成,一个分布式事务总共会有1N条事务日志(N为RM个数)。 在默认情况下&…

万物的算法日记|第五天

笔者自述: 一直有一个声音也一直能听到身边的大佬经常说,要把算法学习搞好,一定要重视平时的算法学习,虽然每天也在学算法,但是感觉自己一直在假装努力表面功夫骗了自己,没有规划好自己的算法学习和总结&am…

CTFshow-pwn入门-前置基础pwn5 - pwn12

pwn5-pwn12的题目全是关于汇编语言的知识,pwn5-pwn12的汇编文件的代码都是一样的。 我们将可执行文件和汇编文件托到ctfshow-pwn专用虚拟机里,给可执行文件加上执行权限并查看其信息。 32位的,直接扔到ida中去。 在虚拟机中使用cat命令读取下…

SpringBoot的配置文件

SpringBoot的配置文件 🔎配置文件的作用🔎配置文件的格式🔎properties配置文件properties的基本语法读取配置文件 🔎yml配置文件yml的基本语法读取配置文件Tips关于 \n🍭配置对象🍭配置集合🍭 &…

网络知识点之-DNS协议

域名系统(Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用TCP和UDP端口53。当前,对于每一级域名长度的限制是63个…

4.13 ReentrantLock

相对于 synchronized 它具备如下特点 可中断可以设置超时时间可以设置为公平锁支持多个条件变量 与 synchronized 一样,都支持可重入 基本语法// 获取锁reentrantLock.lock();try{// 临界区} finally{// 释放锁reentrantLock.unlock();}1、可重入 可重入是指同一个…

小程序 抽象节点 selectable 与slot区别

比较 了解了微信小程序的抽象节点组件封装方式之后,觉得与vue的slot使用类似,但也有些区别 : 抽象节点 和 slot 有什么不同: slot只需要你传入一段代码抽象节点需要你传入一个自定义组件,,不是让你只传递…

Kubernetes集群本地连接调试工具KtConnect

一、简介 KtConnect(Kt为Kubernetes Toolkit集群工具包的简写)是一款基于Kubernetes环境用于提高本地测试联调效率的小工具 Connect:建立数据代理通道,实现本地服务直接访问Kubernetes集群内网(包括Pod IP和Service域…

Jetpack Compose教程-水位控制小部件

Jetpack Compose教程-水位控制小部件 Apple的应用程序和小部件一直是设计的典范,也给我们的"复制系列:活动应用"和"卡片应用"提供了灵感。当他们发布了新款苹果手表Ultra时,它里面深度测量小部件的设计引起了我们的兴趣&…

加快奔向“国际数字之都” CDEC2023中国数字智能生态大会走进上海

数智闪耀长三角,风云际会上海滩。 6月14日上午,以汇聚数字产业动能、打造区域合作为主旨的 CDEC2023中国数字智能生态大会上海站活动在浦东软件园创新体验中心举行。 大会以“共建AI智能生态”为主题,吸引致远互联、SAP、浪潮等龙头企业&…

2022年山东省职业院校技能大赛网络搭建与应用赛项网络搭建与安全部署服务器配置及应用

2022年山东省职业院校技能大赛 网络搭建与应用赛项 第二部分 网络搭建与安全部署&服务器配置及应用 竞赛说明: 一、竞赛内容分布 竞赛共分二个模块,其中: 第一模块:网络搭建及安全部署项目 第二模块:服务器…

C#里的var和dynamic区别到底是什么,你真的搞懂了嘛

前言 这个var和dynamic都是不确定的初始化类型,但是这两个本质上的不同。不同在哪儿呢?var编译阶段确定类型,dynamic运行时阶段确定类型。这种说法对不对呢?本篇看下,文章原文地址:在这里 概括 以下详细叙述下这两个(var,dynamic…

CVE-2023-33246命令执行复现分析

简介 RocketMQ是一款低延迟、高并发、高可用、高可靠的分布式消息中间件。既可为分布式应用系统提供异步解耦和削峰填谷的能力&#xff0c;同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性。 影响版本 <RocketMQ 5.1.0 <RocketMQ 4.9.5 环境搭建 docker…

Leetcode 剑指 Offer II 031. 最近最少使用缓存

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 运用所掌握的数据结构&#xff0c;设计和实现一个 LRU (Least Re…

Python 类型检测:isinstance() 与 type()

文章目录 参考描述面向对象编程概念类与实例继承super() 与代理对象方法的自动继承属性的继承 isinstance 与 type 内置函数isinstance()可迭代对象仅能为元组可能产生的 TypeError嵌套的元组 typeisinstance() 与 type() 的区别 参考 项目描述Python 官方文档https://docs.py…

【C语言初阶】分支语句If与switch的具体用法,有这篇博客就够了

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,这里是君兮_,今天又来给大家更新0基础学习C语言中的文章啦&#xff01; 今天带来的是对分支语句的详解&#xff0c;初学者建议先看看总集哦, 这里是链接: 【C语言初阶】万字解析,带你0基础快速入门C语言(上) 【C语…

图片转excel表格算法之霍夫变换法原理浅析

大家伙都知道&#xff0c;图片转excel表格是金鸣识别中一项非常重要的功能&#xff0c;金鸣识别的OCR在识别图片中的表格时&#xff0c;会用到一种叫霍夫变换法的算法&#xff0c;那这个算法到底是怎么回事&#xff1f;它的原理又是什么呢&#xff1f; 一、霍夫变换法的概念 …

深入了解模板知识(c++)

前言 在c中模板是很重的&#xff0c;泛型编程就是模板最好的体现&#xff0c;模板的出现就是为了更好的复用代码&#xff0c;有了它&#xff0c;我们不必写各种逻辑相同只是逻辑中的数据的类型的不同的代码&#xff0c;使得我们编写代码变得更加高效&#xff0c;下面让我们一起…