一种路径敏感的数据依赖分析算法

Falcon

  • 1.方法
    • 1.1.Basic Rule
    • 1.2.改进算法
    • 1.3.跨函数分析
  • 2.Evaluation
    • 2.1.设置
    • 2.2.value-flow分析
    • 2.3.Thin Slicing
    • 2.4.Bug Detection
  • 参考文献

这篇工作发表于PLDI 24,提出了一种context- 以semi-path-sensitive的数据依赖分析算法,解决path-sensitive的内存模型中存在的aliasing-path-explosion问题。

1.方法

现有sparse flow-sensitive pointer analysis缺点:

  • 1.auxiliary pre-analysis的精度缺失会导致后续分析大量冗余错误pointer-information的传播。

  • 2.auxiliary pre-analysis只用到了一个point-to集合,而随后的flow-sensitive分析在处理path-sensitive问题时后point-to集合会出现路径爆炸。

为了解决这些问题作者提出了Falcon,Falcon处理的程序语法如下:

请添加图片描述

1.1.Basic Rule

作者定义了两个集合 E E E S S S,还定义了对应的查询方式 ∏ φ \prod_{\varphi} φ

  • E [ p → { . . . } ] E[p \rightarrow \{...\}] E[p{...}] 表示top-level variable p p p 的指向环境集合,每一个环境为 ( φ , o ) (\varphi, o) (φ,o) 表示一个address-taken object及其对应的路径条件。

  • S [ o → { . . . } ] S[o \rightarrow \{...\}] S[o{...}],每一个元素 ( π , l , q ) (\pi, l, q) (π,l,q) 表示top-level variable q q q 在语句 l l l 处路径条件为 π \pi π 时赋值给了 o o ostore 指令)。比如语句 l : ∗ x = q l: *x = q l:x=q,该路径条件 π \pi π x x x 只指向 o o o,那么有 S ( o ) = S ( o ) ∪ ( π , l , q ) S(o) = S(o) \; \cup \; (\pi, l, q) S(o)=S(o)(π,l,q)

  • ∏ φ ( S ( o ) ) = { ( π ∧ φ , l , v ) ∣ ( π , l , v ) ∈ S ( o ) } \prod_{\varphi}(S(o)) = \{(\pi \land \varphi, l, v) \; | \; (\pi, l, v) \in S(o)\} φ(S(o))={(πφ,l,v)(π,l,v)S(o)} 表示address-taken variable o o o 在路径条件 φ \varphi φ 下可能的值。这里值用top-level variable表示,也就是存在value-flow v → φ o v \stackrel{\varphi}{\rightarrow} o vφo

  • ∏ φ ( E ( v ) ) = { ( π ∧ φ , o ) ∣ ( π , o ) ∈ E ( v ) } \prod_{\varphi}(E(v)) = \{(\pi \land \varphi, o)\ \; | \; (\pi, o) \in E(v)\} φ(E(v))={(πφ,o) (π,o)E(v)} 表示top-level variable 在路径条件 π \pi π 下的指向集合。

  • E ( v ) ⨄ E ′ ( v ′ ) = { ( π ∨ π ′ , o ) ∣ ∀ ( π , o ) ∈ E ( v ) , ∀ ( π ′ , o ) ∈ E ′ ( v ′ ) } E(v) \biguplus E^{'}(v^{'}) = \{(\pi \; \vee \; \pi^{'}, o) \; | \; \forall (\pi, o) \in E(v), \forall(\pi^{'}, o) \in E^{'}(v^{'})\} E(v)E(v)={(ππ,o)(π,o)E(v),(π,o)E(v)},表示两个 E E E 集合合并,一个应用的地方就是 Φ \Phi Φ 指令处合并不同的value时,不过关于具体操作paper里说的不是很明确,个人理解是如果 o o o 在两个 E E E 集合处都出现了,那么合并路径条件 π ∨ π ′ \pi \; \vee \; \pi^{'} ππ,反之则相当于 π ∨ f a l s e \pi \; \vee \; false πfalse 或者 f a l s e ∨ π ′ false \vee \; \pi^{'} falseπ

基础的transfer function如下, E , S ⊢ l , φ : s t m t : E ′ , S ′ E, S \vdash l, \varphi : stmt : E^{′}, S^{′} E,Sl,φ:stmt:E,S 表示 E , S E, S E,S 集合经过路径条件 φ \varphi φ 下的语句 l l l 后更新为 E ′ , S ′ E^{′}, S^{′} E,S,其中:

  • alloca 指令 KaTeX parse error: Expected 'EOF', got '&' at position 5: p = &̲a p p p E E E 集合添加 { φ , a l l o c a a } \{\varphi, alloca_a\} {φ,allocaa}

  • store 指令 ∗ x = q *x = q x=q 更新了 p t s ( x ) pts(x) pts(x) 每个address-taken variable的 S S S 集合。往已有的 S ( o ) S(o) S(o) 集合中添加 ( π , l , q ) (\pi, l, q) (π,l,q) 表示value-flow关系 q → π o q \stackrel{\pi}{\rightarrow} o qπo。同时只有 store 指令会更新 S S S 集合的值,其它只更新 E E E 集合。

  • SequencingBranching 规则表明Falcon可能通过遍历CFG实现(paper没有明说),由于CFG遍历很费时,为了跳过不必要的CFG node,作者后面提出了一个优化方案。

  • load, phi, copy 指令则负责传播指针集合 E E E 的值。其中 load 的最为复杂,个人理解是对于 l , φ : p = ∗ y l, \varphi: p = *y l,φ:p=y,首先 ∏ φ ( E ( y ) ) = { ( π , o ) , . . . } \prod_\varphi(E(y)) = \{(\pi, o),...\} φ(E(y))={(π,o),...} 查询出满足路径条件的所有指向address-taken variable ( π , o ) (\pi, o) (π,o)(此时存在value-flow o → π p o \stackrel{\pi}{\rightarrow} p oπp),由于 load 指令主要是更新 p p p 的指向集 E ( p ) E(p) E(p),因此需要先查询每个 ( π , o ) (\pi, o) (π,o) 的所有值 ∏ π ( S ( o ) ) \prod_\pi(S(o)) π(S(o))(找出所有的 v → φ o v \stackrel{\varphi}{\rightarrow} o vφo),这样找到了value-flow v → φ p v \stackrel{\varphi}{\rightarrow} p vφp,随后合并所有 v v v 的指向集合更新 E ( p ) E(p) E(p)

请添加图片描述

value flow的构建规则如下图所示(value-flow只存在于 store --> load),对于语句 l 1 l_1 l1 处路径条件为 φ 1 \varphi_1 φ1 store 指令 ∗ x = q *x = q x=q,以及语句 l 2 l_2 l2 处路径条件 φ 2 \varphi_2 φ2load 指令 p = ∗ y p = *y p=y,查询路径条件 φ 2 \varphi_2 φ2 y y y 指向的所有address-taken variable ( π i , o i ) (\pi_i, o_i) (πi,oi),通过 ∏ φ i ( S ( o i ) ) \prod_{\varphi_i}(S(o_i)) φi(S(oi)) 查找 φ i \varphi_i φi o i o_i oi 所有可能的值 ( ( φ i , l 1 , q ) (\varphi_i, l_1, q) (φi,l1,q)),也就是value-flow q → φ i o i q \stackrel{\varphi_i}{\rightarrow} o_i qφioi,最后合并所有同source value-flow的路径条件,也就是构造value-flow边 q → ∨ φ i p q \stackrel{\vee \varphi_i}{\rightarrow} p qφip

请添加图片描述
以下图为例,(b)为传统value-flow构建方法, (c)为Falcon,以处理从 store ∗ x = a *x = a x=aload d = ∗ x d = *x d=x 为例,存在 E ( x ) = { ( φ 1 , o 1 ) , ( ¬ φ 1 , o 2 ) } E(x) = \{(\varphi_1, o_1), (\lnot \varphi_1, o_2)\} E(x)={(φ1,o1),(¬φ1,o2)} S ( o 1 ) = { φ 1 , l 1 , a } S(o_1) = \{\varphi_1, l_1, a\} S(o1)={φ1,l1,a} S ( o 2 ) = { ¬ φ 1 , l 2 , a } S(o_2) = \{\lnot \varphi_1, l_2, a\} S(o2)={¬φ1,l2,a} l 1 , l 2 l_1, l_2 l1,l2是占位符)。处理 d = ∗ x d = *x d=x 时query ∏ ¬ φ 2 ( E ( x ) ) \prod_{\lnot \varphi_2}(E(x)) ¬φ2(E(x)),发现 φ 1 ∧ ¬ φ 2 \varphi_1 \land \lnot \varphi_2 φ1¬φ2 ¬ φ 1 ∧ ¬ φ 2 \lnot\varphi_1 \land \lnot \varphi_2 ¬φ1¬φ2 都能满足,因此得到 ∏ ¬ φ 2 ( E ( x ) ) = { ( φ 1 , o 1 ) , ( ¬ φ 1 , o 2 ) } \prod_{\lnot \varphi_2}(E(x)) = \{(\varphi_1, o_1), (\lnot \varphi_1, o_2)\} ¬φ2(E(x))={(φ1,o1),(¬φ1,o2)},接着分别query ∏ φ 1 ( S ( o 1 ) ) \prod_{\varphi_1}(S(o_1)) φ1(S(o1)) ∏ ¬ φ 1 ( S ( o 2 ) ) \prod_{\lnot \varphi_1}(S(o_2)) ¬φ1(S(o2)) 得到 { φ 1 ∧ ¬ φ 2 , l 1 , a } \{\varphi_1 \land \lnot \varphi_2, l_1, a\} {φ1¬φ2,l1,a} { ¬ φ 1 ∧ ¬ φ 2 , l 2 , a } \{\lnot \varphi_1 \land \lnot \varphi_2, l_2, a\} {¬φ1¬φ2,l2,a}。最后得到value-flow a ⟶ ¬ φ 2 d a \stackrel{\lnot \varphi_2}{\longrightarrow} d a¬φ2d(路径条件简化)。与之相比传统方法的value-flow边就多多了。

请添加图片描述

1.2.改进算法

不过目前上图的算法还有优化空间,主要原因包括:

  • 1.直接在CFG上按上面规则进行传播开销过大。而Sparse分析的pre-analysis构建的SVFG包括太多false def-use。因此也会降低性能。

  • 2.大量guard的路径条件需要更新,可能会引起路径爆炸问题,如果严格的对路径条件求解开销过大。

针对问题1作者提出了一个CFG优化方案,主要针对 storeload 的遍历。算法如下图所示(Algo1为 store,Algo2为 load)。优化的重点是 S S S 集合的访问,首先,store 会修改 S S S 的值而 load 会读取其值。

针对问题1,作者优化了 storeload 的遍历规则,其中将 S ( o ) S(o) S(o) 替换为一系列 S l ( o ) S_l(o) Sl(o),表示每个指令 l l l 处address-taken variable o o o 的值。改进后的算法如下图所示,红框为改变处,主要是处理 store 指令时会顺便处理其所有的支配边界,处理 load 时会沿着其直接支配节点回溯。这里需要先进行控制依赖分析。

请添加图片描述
一个示例如下图所示:

  • 在处理 store 语句 l 4 : ∗ x = d l_4: *x = d l4:x=d 时,更新完 S l 4 ( a l l o c m ) S_{l_4}(alloc_m) Sl4(allocm) { ( φ , l 4 , d ) } \{(\varphi, l_4, d)\} {(φ,l4,d)} 后,接着找到 l 4 l_4 l4 的支配边界 l 6 l_6 l6,更新 S l 6 ( a l l o c m ) = { φ , l 4 , d } S_{l_6}(alloc_m) = \{\varphi, l_4, d\} Sl6(allocm)={φ,l4,d}。同理,访问 l 5 l_5 l5 也会做对应的更新。

  • 在处理 load 语句 l 6 : f = ∗ x l_6: f = *x l6:f=x 时, x x x 指向 a l l o c m alloc_m allocm,首先读取 S l 6 ( a l l o c m ) S_{l_6}(alloc_m) Sl6(allocm) 的值,获的 ( φ , l 4 , d ) (\varphi, l_4, d) (φ,l4,d),表示value-flow d ⟶ φ f d \stackrel{\varphi}{\longrightarrow} f dφf;随后,追溯到 l 6 l_6 l6 的直接支配节点 l 3 l_3 l3,读取 ( t r u e , l 3 , c ) (true, l_3, c) (true,l3,c) 的值后,根据Algo2第9行 φ = π ∧ σ ∧ β \varphi = \pi \land \sigma \land \beta φ=πσβ 和第14行 σ = ¬ π ∧ β \sigma = \lnot \pi \land \beta σ=¬πβ 的规则更新为 ( ¬ φ , l 3 , c ) (\lnot \varphi, l_3, c) (¬φ,l3,c),表示value-flow c ⟶ ¬ φ f c \stackrel{\lnot \varphi}{\longrightarrow} f c¬φf c c c 会在 φ \varphi φ 下被kill掉)。根据这两个value-flow更新 E ( f ) E(f) E(f)

请添加图片描述

针对问题2,作者将程序的表达式都抽象为bool skeleton,比如将 x < 2, x >=2, y = 100/2 抽象为布尔谓词 p p p, ¬ p \lnot p ¬p, q q q。其次,Falcon并不使用功能齐全的SAT求解器,而是采用几种线性时间的半决策程序,如unit-propagation,用于识别“简单”的不可满足约束,并执行轻量级的逻辑简化,如消除重言式。在实验中,作者发现约70%的路径条件是可满足的。对于其余的路径条件,其中80%是简单约束,可以通过半决策程序解决。value-flow边的修剪和合并例子如下图所示。

请添加图片描述

1.3.跨函数分析

与SVF不同,作者依然采用采用一个按照call-graph的拓扑序自底向上先构造每个函数的Value-Flow Graph然后以summary-based方法先构造整体value-flow graph,也就是先独立分析每个函数生成summary,然后按需获取summary进行进一步分析。

通常summary需要注意的是side-effect,对于下图(a)所示代码片段,在对 foo 函数生成摘要时,通常会假设参数 y 指向一个address-taken variable o。按照作者的设定,foo 初始处有 E ( y ) = { ( t r u e , o ) } E(y) = \{(true, o)\} E(y)={(true,o)},分析完整个程序后, S ( o ) = { ( φ , l 2 , c ) , ( ¬ φ , l 3 , a ) } S(o) = \{(\varphi, l_2, c), (\lnot \varphi, l_3, a)\} S(o)={(φ,l2,c),(¬φ,l3,a)}。由于 y y yfoo 和其 caller 的接口,因此 foo 的side-effect只涉及到 y y y,因此 E ( y ) E(y) E(y) S ( o ) S(o) S(o) 就是需要的side-effect。

请添加图片描述
summary最终会在分析call语句的时候用到,这里 quxbar 函数都调用了 foo,同时 quxbar 的参数和 bar 一致,假设在 qux 的调用处, E ( x ) = { ( φ 1 ′ , o 1 ) , ( φ 2 ′ , o 2 ) , ( φ 3 ′ , o 3 ) } E(x) = \{(\varphi^{'}_1, o_1), (\varphi^{'}_2, o_2), (\varphi^{'}_3, o_3)\} E(x)={(φ1,o1),(φ2,o2),(φ3,o3)},那么将summary展开后就有了 S ( o 1 ) = { ( φ ∧ φ 1 ′ , l 2 , c ) , ( ¬ φ ∧ φ 1 ′ , l 3 , a ) } S(o_1) = \{(\varphi \land \varphi^{'}_1, l_2, c), (\lnot \varphi \land \varphi^{'}_1, l_3, a)\} S(o1)={(φφ1,l2,c),(¬φφ1,l3,a)}, S ( o 2 ) = { ( φ ∧ φ 2 ′ , l 2 , c ) , ( ¬ φ ∧ φ 2 ′ , l 3 , a ) } S(o_2) = \{(\varphi \land \varphi^{'}_2, l_2, c), (\lnot \varphi \land \varphi^{'}_2, l_3, a)\} S(o2)={(φφ2,l2,c),(¬φφ2,l3,a)}, S ( o 3 ) = { ( φ ∧ φ 3 ′ , l 2 , c ) , ( ¬ φ ∧ φ 3 ′ , l 3 , a ) } S(o_3) = \{(\varphi \land \varphi^{'}_3, l_2, c), (\lnot \varphi \land \varphi^{'}_3, l_3, a)\} S(o3)={(φφ3,l2,c),(¬φφ3,l3,a)}。如果调用有多层,那么摘要数量可能指数爆炸。

针对这个问题,作者引入了一个辅助变量 R R R,上面 foo 的摘要变成 E ( y ) = { ( t r u e , o ) } E(y) = \{(true, o)\} E(y)={(true,o)}, S ( o ) = { ( t r u e , l 4 , R ) } S(o) = \{(true, l_4, R)\} S(o)={(true,l4,R)}, R = { ( φ , l 2 , c ) , ( ¬ φ , l 3 , a ) } R = \{(\varphi, l_2, c), (\lnot \varphi, l_3, a)\} R={(φ,l2,c),(¬φ,l3,a)}。具体的构造方法如下图所示,在添加辅助变量的同时,对于 void 返回类型,算法还会添加一个额外返回值,示例如上图(b)所示

请添加图片描述
假设分析 foo

  • 独立分析完 foo 后有: E ( y ) = { ( t r u e , o ) } E(y) = \{(true, o)\} E(y)={(true,o)}, S ( o ) = { ( φ , l 2 , c ) , ( ¬ φ , l 3 , a ) } S(o) = \{(\varphi, l_2, c), (\lnot \varphi, l_3, a)\} S(o)={(φ,l2,c),(¬φ,l3,a)}, E ( c ) = { t r u e , j } E(c) = \{true, j\} E(c)={true,j}, E ( a ) = { t r u e , k } E(a) = \{true, k\} E(a)={true,k}。(此时 a a a, c c c 均为一阶指针,对其指向集进行指针分析意义不大,故忽略 k , j k, j k,j 的指向集)。value-flow edge包括: ( c = & j ) → ( ∗ y = c ) (c = \&j) \rightarrow (*y = c) (c=&j)(y=c) ( a = & k ) → ( ∗ y = a ) (a = \&k) \rightarrow (*y = a) (a=&k)(y=a) ( ∗ y = c ) ⟶ φ ( R = ∗ y ) (*y = c) \stackrel{\varphi}{\longrightarrow} (R = *y) (y=c)φ(R=y) ( ∗ y = a ) ⟶ ¬ φ ( R = ∗ y ) (*y = a) \stackrel{\lnot \varphi}{\longrightarrow} (R = *y) (y=a)¬φ(R=y)

  • 用Algo3分析后得到 E ( y ) = { t r u e , o y } E(y) = \{true, o_y\} E(y)={true,oy}( o y o_y oy 为新建object), S ( o y ) = { ( t r u e , , R ) } S(o_y) = \{(true, \; , R)\} S(oy)={(true,,R)} E ( R ) = { ( φ , j ) , ( ¬ φ , k ) } E(R) = \{(\varphi, j), (\lnot \varphi, k)\} E(R)={(φ,j),(¬φ,k)}

利用 f f f 的summary分析caller语句 l , φ : r = f ( u ) l, \varphi: r = f(u) l,φ:r=f(u) 的规则如下,以caller qux 中的 foo(x) 为例,假设 E ( x ) = { ( φ 1 , o 1 ) } E(x) = \{(\varphi_1, o_1)\} E(x)={(φ1,o1)}

  • (1).在callee的summary中替换形参( y y y)和返回值( R R R),构造中间变量 E f ′ ( y ) = { ( φ 1 , o 1 ) } E^{'}_f(y) = \{(\varphi_1, o_1)\} Ef(y)={(φ1,o1)}, S f ′ ( o 1 ) = { ( φ 1 , , R ) } S^{'}_f(o_1) = \{(\varphi_1, , R)\} Sf(o1)={(φ1,,R)} E ( R ) = { ( φ 1 ∧ φ , j ) , ( φ 1 ∧ ¬ φ , k ) } E(R) = \{(\varphi_1 \land \varphi, j), (\varphi_1 \land \lnot \varphi, k)\} E(R)={(φ1φ,j),(φ1¬φ,k)}

  • (2).合并后为 E ′ ( x ) = { ( φ 1 , o 1 ) } E^{'}(x) = \{(\varphi_1, o_1)\} E(x)={(φ1,o1)}, S f ′ ( o 1 ) = { ( φ 1 , , L 1 ) } S^{'}_f(o_1) = \{(\varphi_1, , L_1)\} Sf(o1)={(φ1,,L1)}, E ( L 1 ) = { ( φ 1 ∧ φ , j ) , ( φ 1 ∧ ¬ φ , k ) } E(L_1) = \{(\varphi_1 \land \varphi, j), (\varphi_1 \land \lnot \varphi, k)\} E(L1)={(φ1φ,j),(φ1¬φ,k)}

请添加图片描述在上述示例中,qux 的call语句后面还添加了 store 语句 *x = L1,接着 foo(x) 分析,那么更新了 S ( o 1 ) S(o_1) S(o1) 的值为 { ( φ 1 , l ′ , L 1 ) } \{(\varphi_1, l^{'}, L_1)\} {(φ1,l,L1)}。这里 l ′ l^{'} lstore 语句。

在call分析完后,value-flow中会添加summary edge,主要从callee的return value对应的 store(可能是已有的也可能是新添加的)连接到caller后面的 load 处,在上上张图示例(b)中,foo 结尾插入 R = *y 以及 return R,以及在 quxbar 的caller处添加返回值 L1(还有 L2)以及后面跟着 store 语句 *x = L1 (还有 *z = L2),那么会在新添加的callee的 load 和caller的 store 中间添加一个summary edge。(这里感觉首先需要对IR进行语义等价转换,可能方法和Pinpoint一样)。

2.Evaluation

2.1.设置

下游任务包括:(1).Thin Slicing for Program Understanding、(2).Value-flow Bug Finding: 主要是use-after-free。

baseline包括:

  • (a).指针分析的比较对比:(1).SVF (主要是SVF实现的Andersen算法)、(2).SFS(稀疏值流分析)、(3).DSA (unionfication-based, flow-insensitive, context-sensitive算法,实现采用sea-dsa)

  • (b).slicing与SUPA-FSCS进行对比

  • ©.bug finding与CRED、clang-static-analyzer (CSA) 进行对比。

benchmark采用了6个SPEC INT 2010程序以及10个开源程序。

2.2.value-flow分析

value-flow分析主要对比时间开销,结果如下表和下图所示,SVF、SFS、DSA为baseline,Falcon(PI)和Falcon(SAT)为消融实验,分别表示采用path-insensitive和采用全量SAT进行约束求解的开销。可以看到Falcon的时间开销相比其它方法有着巨大优势。

请添加图片描述

请添加图片描述

2.3.Thin Slicing

为了生成真实的slicing query,作者使用typestate分析提得到的bug report。从对应程序位置的问题变量开始backward分析,结果可以帮助开发人员理解这些报告。主要比较每个slicing query的处理时间(排除value-flow graph的时间),precison和recall。后两者有两位作者进行了人工验证。

时间开销:Falcon对每个slicing query的处理时间少于240ms。总的来说,它比SUPA-FSCS快302倍,平均加速54倍。这一性能提升归因于Falcon生成的value-flow graph比SUPA-FSCS更紧凑。

Precision:Falcon生成的slicing平均大小比SVF、SFS、DSA和SUPA-FSCS分别小5.5倍、1.9倍、2.6倍和1.3倍。表示过滤了很多错误的语句。

Recall:Falcon假设函数参数之间不存在别名,这一不sound的假设对超过90%的query没有影响,经过手动检查结果得到了验证。两项先前的研究也表明,真实世界的C/C++程序中的函数参数往往具有很少的别名关系。

2.4.Bug Detection

use-after-free bug检测的结果如下图所示,分别对比了时间开销和误报率。可以看出,Falcon在大多数大规模程序中超越了CRED和CSA,平均速度提升分别达到10.3倍和1620.8倍(以工具完成的项目为基准)。尽管表中未显示,但作者观察到,如果允许10个线程并发分析,Falcon可以在两小时内完成每个程序的检查。CRED、CSA和Falcon的虚假正例率分别为40.0%、33.3%和27.8%。我们注意到,CSA报告的警告明显少于CRED和Falcon,部分原因是频繁超时和在跨编译单元分析路径时能力有限。Falcon符合工业界对30%误报率的常见要求。

请添加图片描述

参考文献

[1].Yao P, Zhou J, Xiao X, et al. Falcon: A Fused Approach to Path-Sensitive Sparse Data Dependence Analysis[J]. Proceedings of the ACM on Programming Languages, 2024, 8(PLDI): 567-592.

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

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

相关文章

大数据毕业设计选题推荐-广东旅游数据分析系统-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

【牛Y】3DMAX快速构建低多边形城市建筑和道路插件CityBlocks教程

3DMAX快速构建低多边形城市建筑和道路插件CityBlocks&#xff0c;该插件功能主要分为两部分&#xff1a;一键城市建筑生成和一键城市道路生成。可用于城市配景建模、地图三维建模等使用。内置多种建筑组合方式&#xff0c;可使生成的建筑配景更加丰富、富于变换&#xff01; 【…

C++友元和运算符重载

目录 一. 友元 friend 1.1 概念 1.2 友元函数 1.3 友元类 1.4 友元成员函数 二. 运算符重载 2.1 概念 2.2成员函数运算符重载 2.3 成员函数运算符重载 2.4 特殊运算符重载 2.4.1 赋值运算符重载 2.4.2 类型转换运算符重载 2.5 注意事项 三、std::string 字符串类…

sentinel原理源码分析系列(一)-总述

背景 微服务是目前java主流开发架构&#xff0c;微服务架构技术栈有&#xff0c;服务注册中心&#xff0c;网关&#xff0c;熔断限流&#xff0c;服务同学&#xff0c;配置中心等组件&#xff0c;其中&#xff0c;熔断限流主要3个功能特性&#xff0c;限流&#xff0c;熔断&…

基于单片机语音智能导盲仪仿真设计

文章目录 前言资料获取设计介绍设计程序具体实现截图设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们…

计算机毕业设计Python+Spark知识图谱微博舆情预测 微博推荐系统 微博可视化 微博数据分析 微博大数据 微博爬虫 Hadoop 大数据毕业设计

《PythonSpark知识图谱微博舆情预测》开题报告 一、课题背景与意义 随着互联网技术的飞速发展&#xff0c;社交媒体平台如微博已成为人们表达观点、交流信息的重要渠道。微博每天产生海量的数据&#xff0c;这些数据中蕴含着丰富的社会情绪、事件动态等信息&#xff0c;对于政…

AI周报(9.22-9.28)

AI应用-Siipet宠物沟通师 Siipet是一款由SiiPet公司推出的创新宠物行为分析相机&#xff0c;旨在通过尖端技术加深宠物与主人之间的情感联系。这款相机利用先进的AI算法&#xff0c;能够自动识别和分析家中宠物的行为&#xff0c;并提供定制化的护理建议。 SiiPet相机的核心功…

影院管理革新:小徐的Spring Boot应用

第二章开发技术介绍 2.1相关技术 小徐影城管理系统是在Java MySQL开发环境的基础上开发的。Java是一种服务器端脚本语言&#xff0c;易于学习&#xff0c;实用且面向用户。全球超过35&#xff05;的Java驱动的互联网站点使用Java。MySQL是一个数据库管理系统&#xff0c;因为它…

进程间通信(一)【管道通信(下)】

目录 3. 编码通信3.1 管道的四种情况3.2 管道的大小3.3 总结管道的五个特征 4. 管道的应用场景4.1 命令行中的管道4.2 进程池中的管道 3. 编码通信 // 创建管道文件的系统调用 // pipefd&#xff1a;输出型参数&#xff0c;将以读写方式分别打开的文件的文件描述符带出&#x…

2025 年 IT 前景:机遇与挑战并存,人工智能和云计算成重点

云计算de小白 投资人工智能&#xff1a;平衡潜力与实用性 到 2025 年&#xff0c;人工智能将成为 IT 支出的重要驱动力&#xff0c;尤其是在生成式人工智能领域。人工智能的前景在于它有可能彻底改变业务流程、增强决策能力并开辟新的收入来源。然而&#xff0c;现实情况更加微…

突发:OpenAI o1颠覆了人类,o1为什么超越了人类,sam万字长文解读

要点速读 2024 年 9 月 12 日&#xff0c;OpenAI 发布了其最新的人工智能模型——o1&#xff08;Learning to Reason with LLMs[1]&#xff09;&#xff0c;这是一款经过强化学习训练的大型语言模型&#xff0c;能够执行复杂的推理任务。相比于此前的 GPT-4o&#xff08;GPT-4…

上交所服务器崩溃:金融交易背后的技术隐患暴露杭州BGP高防服务器43.228.71.X

一、上交所宕机事件始末 2024 年 9 月 27 日&#xff0c;上交所交易系统突发崩溃&#xff0c;这一事件犹如一颗巨石投入平静的湖面&#xff0c;引起了轩然大波。当天上午&#xff0c;众多投资者反馈券商交易出现延迟问题&#xff0c;随后上交所发布了《关于股票竞价交易出现异常…

【中医智慧解糖忧】血糖高?中医调理有妙招,自然平衡血糖不是梦!

在快节奏的现代生活中&#xff0c;高血糖已成为困扰许多人的健康难题。面对这一挑战&#xff0c;许多人第一时间想到的是西医的药物治疗&#xff0c;却往往忽略了中医这一博大精深的宝库。事实上&#xff0c;中医以其独特的理论体系和丰富的实践经验&#xff0c;在调理血糖方面…

C++里的随机数

想用C做最基础的猜数字,肯定少不了随机数; srand(unsigned(time(NULL))); rand() //是生成一个随机数 rand()%1001//就是一个从一到一百的随机数 合体: #include <iostream> #include <cstdlib> #include <time.h> int main() { int g 0; while (g < …

NSSCTF [HDCTF 2023]easy_re

文件有壳 先用upx脱壳 upx -d 文件地址 将文件拖入IDA shiftF12查看可疑字符串 先进入主函数查看 继续跟进function函数 发现这就是一个base64解码 void __cdecl func(char *x, char *y) {unsigned __int8 *v3; // 用于暂存字符的指针unsigned __int8 v4; // 用于暂存单个字符…

MyBatis——Plus——入门

常用注解 MyBatis——Plus怎么知道他是访问哪张表 常用配置

前端常用动画 直接可以用的代码加详细流程和案例 能应付90%的开发场景

前端项目&#xff0c;特别是Toc的项目&#xff0c;一定少不了各种动效和动画效果。 葫芦七兄弟&#xff1a; CSS 动画 优点&#xff1a;兼容性强&#xff1b;浏览器针对的流畅度优化&#xff1b;语法简单&#xff1b;某些属性&#xff08;如 transform 和 opacity&#xff09;…

带您了解《人工智能机器视觉应用工程师》

人工智能机器视觉应用是指利用人工智能技术和机器视觉技术相结合&#xff0c;使机器能够像人类一样通过视觉感知和理解环境&#xff0c;从而实现各种应用。随着人工智能技术的不断发展&#xff0c;机器视觉应用在各个领域得到了广泛应用。 在工业制造领域&#xff0c;人工智能机…

电商系统之链动2+1模式开发

在电商领域&#xff0c;创新的商业模式是推动市场增长与用户粘性的关键。链动21模式&#xff0c;作为一种基于社交裂变的分销策略&#xff0c;以其独特的团队构建与激励机制&#xff0c;在电商系统中展现出巨大的潜力。从程序员的技术角度出发&#xff0c;本文将深入探讨链动21…

汇编语言 访问CMOS RAM并打印时间(未完)

题目:以"年/月/日 时:分:秒"的格式,显示当前的日期,时间 提示:在此代码的基础上加以改造 assume cs:code code segment start:mov al,9 ;年out 70h,al ;传入9号单元的地址in al,71h ;取9号单元的内容&#xff0c;高4位为十位、低4位为各位mov ah,almov cl,4shr ah,…