Day29:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作
目录
JS原生开发-DOM树-用户交互
JS导入库开发-编码加密-逆向调试
思维导图
JS知识点:
功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等
技术:原生开发,DOM,常见库使用,框架开发(Vue,NodeJS),打包器(Webpack)等
安全:原生开发安全,NodeJS安全,Vue安全,打包器Webpack安全,三方库安全问题等
JS原生开发-DOM树-用户交互
DOM :文档操作对象浏览器提供的一套专门用来操作网页代码内容的功能,实现自主或用户交互动作反馈
- 在Web开发中,浏览器将HTML文档解析为DOM树的结构。DOM树由节点(Nodes)组成,节点可以是元素节点、文本节点、注释节点等。每个节点都有与之相关联的属性、方法和事件。
- 通过使用DOM,您可以通过JavaScript或其他支持DOM的编程语言来访问和操作HTML文档的内容、结构和样式。您可以使用DOM提供的方法和属性来选择元素、修改元素的属性和内容、添加或删除元素,以及响应用户交互等。
安全问题:本身的前端代码通过DOM技术实现代码的更新修改,但是更新修改如果修改的数据可以由用户来指定,就会造成DOM-XSS攻击!
1、获取对象
标签:直接写
Class:加上符号.
id:加上符号#
<h1 id="myHeader" onclick="getValue()">这是标题</h1> document.querySelector('h1') document.querySelector('.id') document.querySelector('#myHeader')2、获取对象属性
<h1 id="myHeader" onclick="getValue()">这是标题</h1> const h1=document.querySelector('h1') const id=h1.id console.log(id)2、操作元素数据
innerHTML 解析后续代码
innerText 不解析后续代码
3、操作元素属性
可以通过 js 修改页面元素的内容属性文本等,如下修改了页面中图片的 src,实现了图片的变换
className src id等 <img src="iphone.jpg" width="300" height="300"></img> const src=document.querySelector('img') src.src='huawei.png
随便下载两张照片放到之前的 js 目录下
创建 dom.html, 内容如下:演示获取图片 src 和标签文本
<h1 id="myHeader" onclick="update1()">这是H1</h1>
<img src="iphone.jpg" width="300" height="300"><br>
<button onclick="update()">刷新</button>
<script>function update(){const img=document.querySelector('img');console.log(img.src);}function update1(){const h1=document.querySelector('h1');console.log(h1.innerText);}
</script>


这里开始演示点击刷新修改图片和点击文本修改标签文本
<!--<h1 id="myHeader" onclick="update1()">这是标题</h1>--><!--<img src="iphone.jpg" width="300" height="300"><br>--><!--<button onclick="update()">刷新</button>--><!--<script>-->
<!-- function update(){-->
<!-- const s=document.querySelector('img')-->
<!-- s.src="javascript:alert(‘XSS’);"-->
<!-- //如果这里huawei.png为一个变量由用户传递决定,那么就会造成DOM XSS-->
<!-- }--><!-- function update1(){-->
<!-- const s=document.querySelector('h1')-->
<!-- //s.innerText="这是小迪<br>"-->
<!-- s.innerHTML='<img src=# onerror="alert(1)">'-->
<!-- console.log(str)-->
<!-- }-->
<!--</script>--><!--<h1 id="myHeader" onclick="update1()">这是H1</h1>--><!--<img src="iphone.jpg" width="300" height="300"><br>--><!--<button onclick="update1()">刷新</button>--><!--<script>-->
<!-- function update(){-->
<!-- const img=document.querySelector('img');-->
<!-- console.log(img.src);-->
<!-- }-->
<!-- function update1(){-->
<!-- const h1=document.querySelector('h1');-->
<!-- console.log(h1.innerText);-->
<!-- }--><!--</script>-->
<h1 id="myHeader" onclick="update1()">这里是SuYou</h1><img src="iphone.jpg" width="300" height="300"><br><button onclick="update()">刷新</button><script>function update(){const img=document.querySelector('img');img.src = 'huawei.png';console.log(img.src);}function update1(){const h1=document.querySelector('h1');const str = h1.innerText;console.log(str);// 迪总是置换了文本,我让它点一下左移一下,小把戏,见笑见笑const first = str[0];var remain = str.substring(1,str.length);var new_str = remain + first;h1.innerText = new_str; // innerText不解析后续代码,只是当文本// h1.innerHTML = '<h3>' + new_str + '</h3>'; // innerHTML不解析后续代码,只是当文本}</script>
此时点击 h1 刷新标题内容,点击刷新按钮,刷新照片

安全问题:本身的前端代码通过DOM技术实现代码的更新修改,但是更新修改如果修改的数据可以由用户来指定,就会造成DOM-XSS攻击!
如 update 中的 img.src, 如果这里的 huawei.png 为一个变量,可以由用户传递决定,那么就可能会造成 DOM XSS, 如下
<h1 id="myHeader" onclick="update1()">这是标题</h1><img src="iphone.jpg" width="300" height="300"><br><button onclick="update()">刷新</button><script>function update(){const s=document.querySelector('img')s.src="javascript:alert(‘XSS’);"//如果这里huawei.png为一个变量由用户传递决定,那么就会造成DOM XSS}function update1(){const s=document.querySelector('h1')//s.innerText="这是小迪<br>"s.innerHTML='<img src=# onerror="alert(1)">'console.log(str)}
</script>
点击刷新:可见浏览器进行了过滤拦截

点击标题,绕过
update1 函数通过 innerHTML 插入带有 onerror 事件的 img 元素,这可能导致 XSS(跨站脚本攻击)漏洞。在实际应用中,需要谨慎处理用户提供的内容,以防止安全漏洞。

实测:网易云翻译:可以使用带外dns,造成数据库ip泄露
发现输入后即使不点翻译,页面仍然发生变化,猜测有 js
参数可控,并且做了替换,怀疑可以是DOM XSS
测试时使用 dnslog,在输入内容中添加。dnslog.cn 是 dnslog 生成的域名,自行替换
<img src="http://dnslog.cn">在浏览器开发者工具 network 中发现页面确实向 dnslog.cn 发送了请求。
在 source 中搜索关键字 querySelector 发现可疑 js 文件 translate.js
直接在翻译中输入 img 标签会被实体化,即被过滤,但是当鼠标放到右侧滑过之后,左侧 img 标签成功执行,可能是使用了 js 鼠标滑过事件 (盲猜一波类似 mouseover 之类的事件),从左到右被过滤了,从右到左没有,所以导致了成功执行
JS导入库开发-编码加密-逆向调试
md5
<!-- 引入 md5.js 脚本 --> <script src="js/md5.js"></script><!-- JavaScript 代码 --> <script>// 定义字符串变量var str1 = 'xiaodi jichu No1';// 使用 md5.js 中的 md5 函数对字符串进行加密var str_encode = md5(str1);// 输出加密后的字符串到控制台console.log(str_encode); </script>输出:afe5119ec0ab46b55432fc5e24f1dc62
SHA1
<!-- 引入 crypto-js.js 脚本 --> <script src="js/crypto-js.js"></script><!-- JavaScript 代码 --> <script>// 定义字符串变量var str1 = 'xiaodisec';// 使用 CryptoJS.SHA1 函数对字符串进行 SHA-1 加密,并将结果转为字符串var str_encode = CryptoJS.SHA1(str1).toString();// 输出加密后的字符串到控制台console.log(str_encode); </script>输出:ce22eaa1c5ebd3dfb3f4474b66f6d3612d4cb3ee
HMAC
<!-- 引入 crypto-js.js 脚本 --> <script src="js/crypto-js.js"></script><!-- JavaScript 代码 --> <script>// 定义密钥和字符串变量var key = 'key';var str1 = 'xiaodisec';// 使用 CryptoJS.HmacSHA256 函数生成 HMAC-SHA256 散列var hash = CryptoJS.HmacSHA256(key, str1);// 将散列结果转为十六进制字符串var str_encode = CryptoJS.enc.Hex.stringify(hash);// 输出加密后的字符串到控制台console.log(str_encode);// 输出示例:'11a7960cd583ee2c3f1ed910dbc3b6c3991207cbc527d122f69e84d13cc5ce5c' </script>输出:08ac6dc8773bd34dcadeffb2b90a8b8f5be9453a9dce7cf09d4da2fcb363d9e7
AES
<script src="js/crypto-js.js"></script> <script type="text/javascript">var aseKey = "12345678" // 定制秘钥,长度必须为:8/16/32位, 长度不一致也没问题var message = "xiaodisec"; // 需要加密的内容// 加密 DES/AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DESvar encrypt = CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=加密内容{mode: CryptoJS.mode.ECB, // 为DES的工作方式padding: CryptoJS.pad.Pkcs7 // 当加密后密文长度达不到指定整数倍(8个字节、16个字节)则填充对应字符}).toString(); // toString=转字符串类型console.log(encrypt);var decrypt = CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=解密内容{mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8); // toString=转字符串类型,并指定编码console.log(decrypt); // "xiaodisec" </script>输出:g4ohopaiYA34XXLsV92Udw== xiaodisec
DES
<script src="js/crypto-js.js"></script> <script type="text/javascript">var aseKey = "12345678" // 定制秘钥,长度必须为:8/16/32位, 长度不一致也没问题var message = "xiaodisec"; // 需要加密的内容// 加密 DES/AES切换只需要修改 CryptoJS.AES <=> CryptoJS.DESvar encrypt = CryptoJS.DES.encrypt(message, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=加密内容{mode: CryptoJS.mode.ECB, // 为DES的工作方式padding: CryptoJS.pad.Pkcs7 // 当加密后密文长度达不到指定整数倍(8个字节、16个字节)则填充对应字符}).toString(); // toString=转字符串类型console.log(encrypt); // 控制台打印 CDVNwmEwDRM//解密var decrypt = CryptoJS.DES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), // 参数1=密钥, 参数2=解密内容{mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8); // toString=转字符串类型,并指定编码console.log(decrypt); // 控制台打印 "i am xiaozhou ?"</script>输出:WVSwdlodMcV2n1FH72uXgw== xiaodisec
RSA
<script src="js/jsencrypt.js"></script> <script type="text/javascript">// 公钥 私匙是通过公匙计算生成的,不能盲目设置var PUBLIC_KEY = '-----BEGIN PUBLIC KEY-----MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyBJ6kZ/VFJYTV3vOC07jqWIqgyvHulv6us/8wzlSBqQ2+eOTX7s5zKfXY40yZWDoCaIGk+tP/sc0D6dQzjaxECAwEAAQ==-----END PUBLIC KEY-----';//私钥var PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvIEnqRn9UUlhNXe84LTuOpYiqDK8e6W/q6z/zDOVIGpDb545NfuznMp9djjTJlYOgJogaT60/+xzQPp1DONrEQIDAQABAkEAu7DFsqQEDDnKJpiwYfUE9ySiIWNTNLJWZDN/Bu2dYIV4DO2A5aHZfMe48rga5BkoWq2LALlY3tqsOFTe3M6yoQIhAOSfSAU3H6jIOnlEiZabUrVGqiFLCb5Ut3Jz9NN+5p59AiEA0xQDMrxWBBJ9BYq6RRY4pXwa/MthX/8Hy+3GnvNw/yUCIG/3Ee578KVYakq5pih8KSVeVjO37C2qj60d3Ok3XPqBAiEAqGPvxTsAuBDz0kcBIPqASGzArumljkrLsoHHkakOfU0CIDuhxKQwHlXFDO79ppYAPcVO3bph672qGD84YUaHF+pQ-----END PRIVATE KEY-----';//使用公钥加密var encrypt = new JSEncrypt();//实例化加密对象encrypt.setPublicKey(PUBLIC_KEY);//设置公钥var message = 'xiaodisec' // 需要加密的数据var encrypted = encrypt.encrypt(message);//对指定数据进行加密console.log(encrypted) // 'JQ83h8tmJpsSZcb4BJ3eQvuqIAs3ejepcUUnoFhQEvum8fA8bf1Y/fG+DO1bSIVNJF6EOZKe4wa0njv6aOar9w=='//使用私钥解密var decrypt = new JSEncrypt(); // 创建解密对象decrypt.setPrivateKey(PRIVATE_KEY); //设置私钥var uncrypted = decrypt.decrypt(encrypted); //解密 'xiaodisec'console.log(uncrypted); </script>输出:Fw1H5KoC6zZnwAzLee8z5ubmQYSqaVqu711VI+NBavYT9bkWpzxUtZHmbSUvLbuCblPO96NdfoQHtPe9TURo6A== xiaodisec
‘admin’ OR 1=1 — ‘的含义
首先,让我们逐步解析这个语句的含义。在MySQL中,’admin’表示一个字符串常量,OR关键字表示逻辑或运算符,而1=1是一个恒定为真的条件。最后的’– ‘表示注释,使得引号后的内容成为注释而不被解析。
换句话说,这个语句在条件中使用了1=1,这个条件总是为真,因此结果总是返回真。这就可以绕过许多条件验证,让用户以admin的身份执行相关操作。
举个例子,假设SQL语句如下:
SELECT * FROM users WHERE username = 'admin' OR 1=1 -- ' AND password = '123456'这个语句的意图是从users表中选择username为’admin’且password为’123456’的记录。然而,由于’admin’ OR 1=1 — ‘这个条件恒为真,实际上会选择所有的记录,而不仅仅是admin账户。
若 payload 的测试数据为 admin ‘1=1, 但网站接受的是加密数据,你直接发明文过去,肯定是没用效果的,需要将 payload 也以相同的加密算法加密发送才会有效
逆向调试加密算法
打开页面,选择密码右击鼠标打开检查,找到相关id值edtPassWord,并进行搜索$("#btnPost").click(function() 加#后证明是想取id值中的edtPassWord
加密方式
分析代码过程:发出疑问如果加密格式不显示出来,怎样判断加密的方式是什么?
可以借助检查的控制台,尝试输入获取加密后的密码值,再和提交表单的加密值进行比对,若一致则证明识别出。(一般安全防护比较强的,不会把运行的所以东西全加载到浏览器上)
断点调试:一般安全防护比较强的,不会把运行的所有东西全加载到浏览器上,所以要执行断点调试
https://my.sto.cn/
打开页面,选择密码右击鼠标打开检查找到相关id值numPassword并进行搜索
找到密码的加密格式,但是没有明文展现出来
采用之前的方式在控制台中输入相应的代码encodeURI(encrypt.encrypt(numPassword))报错encrypt is not defined,有一些文件只在服务器本地执行,不会加载到浏览器中
说明这部分文件是放在浏览器上的,并不是在本地的,只有用到的时候才会传输到本地执行
必须采用调试断点的方式来,通过服务器获取其执行文件,然后修改对应的返回密文即可
对应地方打上断点,点击登录,进入断点调试,发现右侧出现输入的账号密码内容
点击最右侧按钮,进入调试,再次打开控制台,并输入encodeURI(encrypt.encrypt(numPassword))发现成功回显加密后的密码
这时候可以执行是因为加密的文件已经被放入浏览器的内存中
思维导图

相关文章:
Day29:安全开发-JS应用DOM树加密编码库断点调试逆向分析元素属性操作
目录 JS原生开发-DOM树-用户交互 JS导入库开发-编码加密-逆向调试 思维导图 JS知识点: 功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等 技术:原生开发&#x…...
Python爬虫——scrapy-4
目录 免责声明 目标 过程 先修改配置文件 再修改pipelines.py 最后的结果是这样的 read.py pipelines.py items.py settings.py scrapy日志信息以及日志级别 settings.py文件设置 用百度实验一下 指定日志级别 WARNING 日志文件 注意 scrapy的post请求 简介 …...
美团春招编程第一场第三题
美团春招编程第一场第三题 题目 解答 思路-暴力解法 pair中存储从原点到包含当前元素的0,1数量,得到二维数组mat; 从头到尾遍历尺寸为i*i的矩形,计算完美矩形数量 #include <iostream> #include <vector> using namespace std;int main()…...
BulingBuling - 《金钱心理学》 [ The Psychology of Money ]
金钱心理学 摩根-豪泽尔 关于财富、贪婪和幸福的永恒课程 The Psychology of Money Morgan Housel Timeless Lessons on Wealth, Greed, and Happiness 内容简介 [ 心理学 ] [ 金钱与投资 ] Whats it about? [ Psychology ] [ Money & Investments ] 《金钱心理学》&…...
急速建立网站方法
急速建立网站方法 WordPress: 简介: WordPress是一种广泛用于建设博客、网站的免费开源内容管理系统(CMS)。它具有友好的用户界面和丰富的插件生态系统,使得用户可以轻松创建和管理网站。特点: 主题和插件支…...
Java EE之wait和notify
一.多线程的执行顺序 由于多个线程执行是抢占式执行,就会导致顺序不同,同时就会导致出现问题,就比如俩个线程同时对同一个变量进行修改,我们难以预知执行顺序。 但在实际开发中,我们希望代码按一定的逻辑顺序执行&am…...
PostgreSQL中In, Exists在SQL查询中到底有无区别
前言 SQL查询当中,In和Exists子查询到底有无区别?记得很多年以前,确实是有相关的使用戒条的,或者说存在一些使用的惯用法。试图完全抹开两者的区别,就有点过了。 两者的主要区别: 从目的上讲,…...
Netty Review - 探究Netty服务端主程序无异常退出的背后机制
文章目录 概述故障场景尝试改进问题分析铺垫: Daemon线程Netty服务端启动源码分析逻辑分析 如何避免Netty服务端意外退出最佳实践 概述 在使用Netty进行服务端程序开发时,初学者可能会遇到各种问题,其中之一就是服务端意外退出的问题。这种问…...
【兔子机器人】修改GO电机id(软件方法、硬件方法)
一、硬件方法 利用上位机直接修改GO电机的id号: 打开调试助手,点击“调试”,查询电机,修改id号,即可。 但先将四个GO电机连接线拔掉,不然会将连接的电机一并修改。 利用24V电源给GO电机供电。 二、软件方…...
Spring MVC | Spring MVC 的“核心类” 和 “注解”
目录: Spring MVC 的“核心类” 和 “注解” :1.DispatcherServlet (前端控制器)2.Controller 注解3.RequestMapping 注解3.1 RequestMapping 注解的 “使用”标注在 “方法” 上标注在 “类” 上 3.2 RequestMapping 注解的 “属性” 4.组合注解4.1 请求处理方法的…...
Python 创建PPT
本篇为如何使用Python来创建ppt文件。 创建PPT 安装必要的库 命令如下: pip install python-pptx 安装过程: 创建ppt文件 在当前目录下创建一个test的ppt文件。其中包含两页,分别使用了不同的布局。 第一页设置了标题和内容。第二页只设…...
【工具】Git的24种常用命令
相关链接 传送门:>>>【工具】Git的介绍与安装<< 1.Git配置邮箱和用户 第一次使用Git软件,需要告诉Git软件你的名称和邮箱,否则无法将文件纳入到版本库中进行版本管理。 原因:多人协作时,不同的用户可…...
rabbitmq 基本总结
rabbitmq 的基本概念 vhost、broker、producer、 consumer、 exchange、 queue、 routing key rabbitmq 常用的队列类型,工作队列(简单队列),pub/sub, routing key, topic 模式 <dependency><groupId>com.rabbitmq&l…...
7、Copmose自定义颜色和主题切换
Copmose自定义颜色和主题切换 一起颜色的设置的都是在res/values/colors里面去做颜色, 但是当使用compose的时候,抛弃了使用了ui.theme底下的Color.kt和Theme.kt 但是默认使用的是MaterialTheme主题,里面的颜色字段不能定义,因此…...
js-判断变量是否定义
if (typeof myVar undefined) {// myVar (未定义) 或 (已定义但未初始化) } else {// myVar (已定义和已初始化) } 参考 https://www.cnblogs.com/redFeather/p/17662966.html...
视频远程监控平台EasyCVR集成后播放只有一帧画面的原因排查与解决
智慧安防视频监控平台EasyCVR能在复杂的网络环境中(专网、局域网、广域网、VPN、公网等)将前端海量的设备进行统一集中接入与视频汇聚管理,平台可支持的接入协议包括:国标GB28181、RTSP/Onvif、RTMP,以及厂家的私有协议…...
Pulsar 社区周报 | No.2024.03.08 Pulsar-Spark Connector 助力实时计算
关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用计算与存储分离架构设计,支持多租户、持久化存储、多机房跨区域数据复制,…...
Redis--线程模型详解
Redis线程模型 Redis内部使用的文件事件处理器(基于Reactor模式开发的)file event handler是单线程的,所以Redis线程模型才叫单线程模型,它采用IO多路复用机制同时监听多个socket,当被监听的socket准备好执行accep、r…...
[备赛笔记]——5G大唐杯(5G考试等级考考试基础试题)
个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…...
【解读】OWASP 大语言模型(LLM)安全测评基准V1.0
大语言模型(LLM,Large Language Model)是指参数量巨大、能够处理海量数据的模型, 此类模型通常具有大规模的参数,使得它们能够处理更复杂的问题,并学习更广泛的知识。自2022 年以来,LLM技术在得到了广泛的应…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
Tauri2学习笔记
教程地址:https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引:https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多,我按照Tauri1的教程来学习&…...
如何做好一份技术文档?从规划到实践的完整指南
如何做好一份技术文档?从规划到实践的完整指南 🌟 嗨,我是IRpickstars! 🌌 总有一行代码,能点亮万千星辰。 🔍 在技术的宇宙中,我愿做永不停歇的探索者。 ✨ 用代码丈量世界&…...
Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...
Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...














