一个测试OOM killer的程序未触发OOM所带来的问题
概述
我们知道,由于MMU实现了虚拟地址到物理地址的转换,所以我们在申请虚拟地址时往往可以申请一大块内存,这实际上是对资源的有效利用,毕竟只有内存真正被投入使用时(如memset)才会实际分配物理内存,虚拟内存需要物理内存作为支撑,当分配了太多虚拟内存,导致物理内存不够时,就发生了Out Of Memory。
介绍下overcommit-memory机制
Linux 内核支持以下内存过度承诺处理模式:
vm.overcommit_memory = 0
启发式内存过度承诺处理。显而易见的地址空间过度承诺会被拒绝。适用于典型系统。它确保严重的过度承诺会失败,同时允许过度承诺减少交换使用量。在此模式下,root 用户可以分配略多一些内存。这是默认设置。(太明显的overcommit会被拒绝,比如malloc一次性申请的内存大小就超过了系统总内存,会上报给应用程序申请失败)
vm.overcommit_memory = 1
总是过度承诺。适用于某些科学应用程序。经典示例是使用稀疏数组的代码,并依赖几乎完全由零页面组成的虚拟内存。(malloc申请内存可以被申请到,但是内存耗光会触发oom killer)
vm.overcommit_memory = 2
不过度承诺。系统的总地址空间承诺不得超过交换空间加上可配置数量(默认为物理内存的 50%)。根据您使用的数量,在大多数情况下,这意味着进程在访问页面时不会被杀死,但在内存分配时会适当地收到错误信息。(通过overcommit_ratio,overcommit_kbytes可以修改这个比率,来限制可以申请的内存)
适用于希望保证其内存分配将来可用而无需初始化每个页面的应用程序。
内存过度承诺策略通过 sysctl 的 vm.overcommit_memory 来设置。
过度承诺数量可以通过 vm.overcommit_ratio(百分比)或 vm.overcommit_kbytes(绝对值)来设置。
当前的过度承诺限制和已承诺的数量可以通过 /proc/meminfo 中的 CommitLimit 和 Committed_AS 查看。
接下来举个例子:
当vm.overcommit_memory = 2时;
//系统默认情况如下:
# freetotal used free shared buff/cache available
Mem: 196732 33028 141076 60 22628 156752
Swap: 0 0 0cat /proc/meminfo | grep ommit
CommitLimit: 98364 kB
Committed_AS: 5832 kB# cat /proc/sys/vm/overcommit_ratio
50
# cat /proc/sys/vm/overcommit_memory
0
# cat /proc/sys/vm/overcommit_kbytes
0
//cat test_50M.c 申请50M空间的测试程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main()
{long *p = NULL;while(1) {p = (long *)malloc(0x3200000);if(!p){printf("p is null\n");return 0;}memset(p, 0x55, 0x3200000);printf("50M success\n");usleep(10000);}return 0;
}
//执行,结果发现,申请第二个50M的时候申请失败
./test_50M
50M success
p is null/ # echo 30 > /proc/sys/vm/overcommit_ratio
/ # cat /proc/meminfo | grep ommit
CommitLimit: 59016 kB
Committed_AS: 5432 kB
//上述操作可以看到过度承诺的内存限制变化了,变小了/ # echo 70 > /proc/sys/vm/overcommit_ratio
/ # cat /proc/meminfo | grep ommit
CommitLimit: 137712 kB
Committed_AS: 5408 kB
/ # ./test_50M
50M success
50M success
p is null
//上述操作可以看到申请第二个50M的时候申请成功了,第三个失败了
介绍下panic_on_oom
该选项用于启用或禁用内存耗尽时的系统紧急处理功能。
- 若设置为 0,内核将终止某些恶意进程,称为 oom_killer。通常情况下,oom_killer 能够终止恶意进程,系统将能够继续运行。
- 若设置为 1,当内存耗尽发生时,内核会发生紧急情况。然而,如果一个进程受到内存策略/内存掩码的限制,并且这些节点出现内存耗尽状态,oom-killer 可能会终止一个进程。在这种情况下不会发生紧急情况。因为其他节点的内存可能是空闲的。这意味着系统整体状态可能还未达到灾难性程度。
- 若设置为 2,即使在上述情况下也会强制发生内核紧急情况。即使在内存控制组下发生内存耗尽,整个系统也会发生紧急情况。
系统默认值为 0。
1 和 2 是用于集群容错的故障切换。请根据您的故障切换策略选择其中一种。
panic_on_oom=2+kdump 可以提供非常强大的工具来调查内存耗尽的原因。您可以获得快照。
介绍下oom_kill_allocating_task
该选项用于启用或禁用在内存耗尽情况下终止触发OOM的任务。
- 若设置为零,OOM killer 将扫描整个任务列表,并根据启发式选择一个任务进行终止。通常情况下,它会选择一个占用大量内存的恶意任务,在被终止时释放大量内存。
- 若设置为非零值,OOM killer 将直接终止触发内存耗尽条件的任务。这避免了昂贵的任务列表扫描操作。
如果选择了 panic_on_oom,它将优先于 oom_kill_allocating_task 中使用的任何值。
默认值为 0。
总结panic_on_oom和oom_kill_allocating_task关系
当系统发生OOM的时候,根据panic_on_oom配置,走系统奔溃还是杀进程
panic_on_oom=0:杀进程,此时根据oom_kill_allocating_task的配置选择进程赴死
- oom_kill_allocating_task=0,扫描所有进程,根据算法对进程打分,分高者赴死,此时可以通过oom_score_adj选项控制进程oom_score,手动干预算法。
早期选项(已失效):文件在/proc//oom_adj。范围是[-17 ~ 15],数值越大表示越容易被oom
killer杀死。如果进程的oom_adj配置为-17,表示进程禁止被OOM killer杀死。
现在选项:文件在/proc//oom_score_adj。范围是[-1000 ~ 1000],数值越大表示越容易被oom
killer杀死。oom_score_adj=-1000,表示完全禁止进程被oom杀死。 - oom_kill_allocating_task非0,直接杀死触发OOM的进程;
如果panic_on_oom的配置不为0,那么oom_kill_allocating_task的配置就没什么用了;
======================================================================
说了这么多我们还没有进入正题,接下来我们说下标题的问题
问题描述
测试给了一段下面的代码,说为什么没有报OOM killer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main()
{long *p = NULL;while(1) {p = (long *)malloc(0x3200000);usleep(10000);}return 0;
}
分析如下,我们发现内存并没有被真正的使用,印证了文章开头的一句话”只有内存真正被投入使用时(如memset)才会实际分配物理内存“
/ # freetotal used free shared buff/cache available
Mem: 196732 33084 143756 60 19892 156700
Swap: 0 0 0
/ #
/ # ./test &
/ # freetotal used free shared buff/cache available
Mem: 196732 33676 143156 60 19900 156108
Swap: 0 0 0
修改代码为
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main()
{long *p = NULL;while(1) {p = (long *)malloc(0x3200000);memset(p, 0x55, 0x3200000);usleep(10000);}return 0;
}
执行如下,出现了Segmentation fault,有经验的工程师就会知道可能是malloc失败,p=NULL了,memset操作空指针了,导致的Segmentation fault (core dumped)。
./test
Segmentation fault (core dumped)
在这里再转移下注意力,linux内核的core dumped如何生成和分析的,可以参考如下帖子
https://zhuanlan.zhihu.com/p/582051703
https://zhuanlan.zhihu.com/p/661430797
我们再改下代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main()
{long *p = NULL;while(1) {p = (long *)malloc(0x3200000);if(!p){printf("p is null\n");return 0;}memset(p, 0x55, 0x3200000);usleep(10000);}return 0;
}执行结果是分配内存失败,并没有触发OOM Killer
```c
# ./test
p is null
/ # freetotal used free shared buff/cache available
Mem: 196732 33668 155988 72 7076 156828
Swap: 0 0 0
# 介绍min_free_kbytes
min_free_kbytes 是 Linux 内核参数,用于强制系统保持一定数量的空闲内存(以千字节为单位)。系统会根据这个数值为系统中每个低内存区域计算一个水印值(watermark)。每个低内存区域会根据其大小比例获得一定数量的保留空闲页。一定量的内存是需要用于满足 PF_MEMALLOC 分配需求的;如果将 min_free_kbytes 设置得低于 1024KB,系统可能会出现隐性问题,并在高负载下容易发生死锁。而将 min_free_kbytes 设置得过高可能会导致系统立即发生 Out Of Memory(OOM)情况。因此,在调整 min_free_kbytes 参数时,需要谨慎设置,避免设置过低导致系统问题,同时也要注意不要设置得过高导致系统内存不足。根据系统的实际情况和需求来合理配置这个参数,以确保系统的稳定性和性能表现。```c# cat /proc/sys/vm/min_free_kbytes
1771
我们按照1M内存分配,改下代码,执行发现可以触发oom killer
/ # ./test
[ 2991.645179] [King]: out_of_memory, oom_killer_disabled:0
[ 2991.650513] CPU: 1 PID: 1618 Comm: test Tainted: G O 4.19.125 #1
[ 2991.657822] Hardware name: axera,ax620e (DT)
[ 2991.662091] Call trace:
[ 2991.664547] dump_backtrace+0x0/0x120
[ 2991.668212] show_stack+0x14/0x20
[ 2991.671529] dump_stack+0x98/0xbc
[ 2991.674845] out_of_memory+0x3c/0x350
[ 2991.678509] __alloc_pages_nodemask+0x7cc/0x928
[ 2991.683043] __handle_mm_fault+0x5d4/0x1058
[ 2991.687227] handle_mm_fault+0x70/0xb8
[ 2991.690979] do_page_fault+0x178/0x488
[ 2991.694729] do_translation_fault+0x44/0x4c
[ 2991.698913] do_mem_abort+0x3c/0xc8
[ 2991.702402] el0_da+0x20/0x24
[ 2991.705448] test invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), nodemask=(null), order=0, oom_score_adj=0
[ 2991.716299] CPU: 1 PID: 1618 Comm: test Tainted: G O 4.19.125 #1
[ 2991.723619] Hardware name: axera,ax620e (DT)
[ 2991.727899] Call trace:
[ 2991.730369] dump_backtrace+0x0/0x120
[ 2991.734048] show_stack+0x14/0x20
[ 2991.737380] dump_stack+0x98/0xbc
[ 2991.740708] dump_header.isra.0+0x54/0x1f0
[ 2991.744815] oom_kill_process+0xa8/0x484
[ 2991.748751] out_of_memory+0x328/0x350
[ 2991.752511] __alloc_pages_nodemask+0x7cc/0x928
[ 2991.757057] __handle_mm_fault+0x5d4/0x1058
[ 2991.761251] handle_mm_fault+0x70/0xb8
[ 2991.765014] do_page_fault+0x178/0x488
[ 2991.768775] do_translation_fault+0x44/0x4c
[ 2991.772970] do_mem_abort+0x3c/0xc8
[ 2991.776471] el0_da+0x20/0x24
[ 2991.779487] Mem-Info:
[ 2991.781777] active_anon:39528 inactive_anon:9 isolated_anon:0
[ 2991.781777] active_file:32 inactive_file:48 isolated_file:0
[ 2991.781777] unevictable:0 dirty:2 writeback:0 unstable:0
[ 2991.781777] slab_reclaimable:1076 slab_unreclaimable:4176
[ 2991.781777] mapped:19 shmem:18 pagetables:135 bounce:0
[ 2991.781777] free:467 free_pcp:53 free_cma:0
[ 2991.813537] Node 0 active_anon:158112kB inactive_anon:36kB active_file:140kB inactive_file:212kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:148kB dirty:8kB writeback:0kB shmem:72kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 0kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no
[ 2991.840178] Normal free:1868kB min:1768kB low:2208kB high:2648kB active_anon:158108kB inactive_anon:36kB active_file:224kB inactive_file:212kB unevictable:0kB writepending:8kB present:229108kB managed:196732kB mlocked:0kB kernel_stack:1344kB pagetables:540kB bounce:0kB free_pcp:148kB local_pcp:0kB free_cma:0kB
[ 2991.867702] lowmem_reserve[]: 0 0
[ 2991.871038] Normal: 82*4kB (UMEH) 39*8kB (UMEH) 12*16kB (UMEH) 11*32kB (UMEH) 3*64kB (MH) 2*128kB (H) 1*256kB (H) 0*512kB 0*1024kB 0*2048kB 0*4096kB = 1888kB
[ 2991.885166] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[ 2991.893615] 100 total pagecache pages
[ 2991.897320] 57277 pages RAM
[ 2991.900125] 0 pages HighMem/MovableOnly
[ 2991.904011] 8094 pages reserved
[ 2991.907212] 0 pages hwpoisoned
[ 2991.910407] Tasks state (memory values in pages):
[ 2991.915195] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name
[ 2991.923891] [ 1345] 0 1345 930 42 40960 0 0 syslogd
[ 2991.932308] [ 1349] 0 1349 930 50 40960 0 0 klogd
[ 2991.941037] [ 1369] 0 1369 631 31 45056 0 0 tee-supplicant
[ 2991.950091] [ 1390] 0 1390 930 39 45056 0 0 crond
[ 2991.958355] [ 1398] 0 1398 1721 139 53248 0 -1000 sshd
[ 2991.966529] [ 1403] 0 1403 930 27 40960 0 0 telnetd
[ 2991.974959] [ 1405] 0 1405 930 27 45056 0 0 ifplugd
[ 2991.983384] [ 1443] 0 1443 506 32 40960 0 0 axsyslogd
[ 2991.992003] [ 1447] 0 1447 506 31 40960 0 0 axklogd
[ 2992.001507] [ 1449] 0 1449 930 41 40960 0 0 sh
[ 2992.009459] [ 1569] 0 1569 930 30 40960 0 0 getty
[ 2992.017646] [ 1618] 0 1618 39533 39059 352256 0 0 test
[ 2992.025752] Out of memory: Kill process 1618 (test) score 795 or sacrifice child
[ 2992.033157] Killed process 1618 (test) total-vm:158132kB, anon-rss:156232kB, file-rss:4kB, shmem-rss:0kB
[ 2992.065409] oom_reaper: reaped process 1618 (test), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
总结,当前内存剩余余量小于min_free_kbytes时就会触发OOM Killer,我们通过malloc 1M内存(相对小颗粒度)可以把内存耗到1771KB以下;
相关文章:
一个测试OOM killer的程序未触发OOM所带来的问题
概述 我们知道,由于MMU实现了虚拟地址到物理地址的转换,所以我们在申请虚拟地址时往往可以申请一大块内存,这实际上是对资源的有效利用,毕竟只有内存真正被投入使用时(如memset)才会实际分配物理内存&…...

SanctuaryAI推出Phoenix: 专为工作而设计的人形通用机器人
文章目录 1. Company2. Main2.1 关于凤凰™ (Phoenix)2.2 关于碳™(Carbon)2.3 商业化部署2.4 关于 Sanctuary Corporation 3. My thoughtsReference彩蛋:将手机变为桌面小机器人 唯一入选《时代》杂志 2023 年最佳发明的通用机器人。 称机器人自主做家务的速度和灵…...

李沐动手学习深度学习——4.2练习
1. 在所有其他参数保持不变的情况下,更改超参数num_hiddens的值,并查看此超参数的变化对结果有何影响。确定此超参数的最佳值。 通过改变隐藏层的数量,导致就是函数拟合复杂度下降,隐藏层过多可能导致过拟合,而过少导…...
CYQ.Data 支持 DaMeng 达梦数据库
DaMeng 达梦数据库介绍: 达梦数据库(DMDB)是中国自主研发的关系型数据库管理系统,由达梦科技股份有限公司开发。 达梦数据库提供了企业级的数据库解决方案,广泛应用于金融、电信、政府、制造等行业领域。 达梦数据库具有以下特点和优势: 高性能:具备高性能的并发处理…...

计网面试题整理上
1. 计算机网络的各层协议及作用? 计算机网络体系可以大致分为一下三种,OSI七层模型、TCP/IP四层模型和五层模型。 OSI七层模型:大而全,但是比较复杂、而且是先有了理论模型,没有实际应用。TCP/IP四层模型:…...

code: 500 ] This subject is anonymous - it does not have any identifying
项目场景: 相关背景: 使用idea 开发java 项目,前端页面请求 页面中相关的接口时,idea 控制台有报错信息出现,前端请求失败。 问题描述 问题: 使用idea 开发java 项目,前端页面请求 页面中相…...

FC-AE-1553 协议
FC-AE-1553 协议 MIL-STD-1553B总线协议总线结构字格式消息传输方式 FC协议FC协议栈拓扑结构服务类型帧/序列/交换FC帧格式 FC-AE-1553网络构成帧类型命令帧状态帧数据帧 Information UnitsNC1NC2NC3-4NC5-7NT1-7 传输模式1. NC-NT2. NT-NC3. NT-NT4. 无数据字的模式命令5. 带数…...
代码随想录算法训练营day38|理论基础、509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
理论基础 代码随想录 视频:从此再也不怕动态规划了,动态规划解题方法论大曝光 !| 理论基础 |力扣刷题总结| 动态规划入门_哔哩哔哩_bilibili 动态规划:如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态…...
夫妻一方名下股权到底归谁?
生效判决摘要:1.夫妻一方在婚姻关系存续期间投资的收益,为夫妻的共同财产,归夫妻共同所有,但是并不能据此否定股权本身可能成为夫妻共同财产。婚姻关系存续期间登记在配偶一方名下的股权能否成为夫妻共同财产,可由司法…...

git根据文件改动将文件自动添加到缓冲区
你需要修改以下脚本中的 use_cca: false 部分 #!/bin/bash# 获取所有已修改但未暂存的文件 files$(git diff --name-only)for file in $files; do# 检查文件中是否存在"use_cca: false"if grep -q "use_cca: false" "$file"; thenecho "Ad…...
SystemVerilog Constants、Processes
SystemVerilog提供了三种类型的精化时间常数: •参数:与最初的Verilog标准相同,可以以相同的方式使用。 •localparameter:与参数类似,但不能被上层覆盖模块。 •specparam:用于指定延迟和定时值&#x…...

交易平台开发:构建安全/高效/用户友好的在线交易生态圈
在数字化浪潮的推动下,农产品现货大宗商品撮合交易平台已成为连接全球买家与卖家的核心枢纽。随着电子商务的飞速发展,一个安全、高效、用户友好的交易平台对于促进交易、提升用户体验和增加用户黏性至关重要。本文将深入探讨交易平台开发的关键要素&…...
Linux系统之部署复古游戏平台
Linux系统之部署复古游戏平台 前言一、项目介绍1.1 项目简介1.2 项目特点1.3 游戏平台介绍二、本次实践介绍二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 安装Docker环境3.2 检查Docker服务状态3.3 检查Docker版本3.4 检查docker compose 版本四、构建…...
开源计算机视觉库opencv-python详解
开源计算机视觉库opencv-python详解 OpenCV-Python的核心功能:安装OpenCV-Python:使用OpenCV-Python的基本步骤:OpenCV-Python的高级应用:注意事项:OpenCV-Python的高级应用示例:1. 人脸识别2. 目标跟踪3. …...

Vue开发实例(十)Tabs标签页打开、关闭与路由之间的关系
创建标签页 一、创建标签页二、点击菜单展示新标签页1、将标签数据作为全局使用2、菜单点击增加标签页3、处理重复标签4、关闭标签页 三、点击标签页操作问题1:点击标签页选中菜单进行高亮展示问题2:点击标签页路由也要跳转 四、解决bug 先展示最终效果 …...
基于51单片机的智能火灾报警系统
基于51单片机的智能火灾报警系统 摘要: 本文提出了一种基于51单片机的智能火灾报警系统。该系统采用烟雾传感器和温度传感器来检测火灾的发生,并通过单片机进行数据处理和报警控制。此外,该系统还具有无线通信功能,可以实时将火灾…...

【数据结构】堆的TopK问题
大家好,我是苏貝,本篇博客带大家了解堆的TopK问题,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 一. 前言二. TopK三. 代码 一. 前言 TOP-K问题:即求数据结合中前K个最大的元…...
Vue后台管理系统笔记-01
npm(Node Package Manager)和 yarn 是两个常用的包管理工具,用于在 Node.js 项目中安装、管理和更新依赖项。它们有以下几个区别: 性能和速度:在包的安装和下载方面,yarn 通常比 npm 更快速。yarn 使用了并…...

飞天使-学以致用-devops知识点3-安装jenkins
文章目录 构建带maven环境的jenkins 镜像安装jenkinsjenkins yaml 文件安装插件jenkins 配置k8s创建用户凭证 构建带maven环境的jenkins 镜像 # 构建带 maven 环境的 jenkins 镜像 docker build -t 192.168.113.122:8858/library/jenkins-maven:jdk-11 .# 登录 harbor docker …...

08、MongoDB -- MongoDB 的 集合关联($lookup 和 DBRef 实现集合关联)
目录 MongoDB 的 集合关联演示前提:登录单机模式的 mongodb 服务器命令登录【test】数据库的 mongodb 客户端命令登录【admin】数据库的 mongodb 客户端命令 SQL 术语 与 Mongodb 的对应关系使用 $lookup 实现集合关联语法格式添加测试数据1、查询出订单数量大于6&a…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...