一星如月看多时:动手实现一下这些设计模式才能更好的理解作者总结的内容
0 点赞 评论 收藏
分享
201905011049420:Volatile 现在感觉不常用了吧
0 点赞 评论 收藏
分享
Joe_Hu:包含min函数的栈种给出的程序,不能通过leetcode的测试用例。 原因是在if(stack.peek()==minStack.peek())中使用的是==而不是equals方法进行对比。 使用==的话,对比的是两个Integer的对象,而这两个Integer的对象实际上不是一个,所以到时minStack中的值无法pop出去。 改成if(stack.peek().equals(minStack.peek()))后可以通过leetcode的测试。
0 点赞 评论 收藏
分享
楚天千里清秋:冒泡排序和选择排序的区别: 冒泡排序在一次遍历中,每次比较都可能发生交换;一旦某次遍历一次交换都没发生,就可以认为排序已经完成,可以提前终止(排序整体有序的数列存在优势);由于是两两之间的比较和交换,可以实现稳定性。 选择排序在一次遍历中维护了一个最小值,每次比较都可能更新最小值,一次遍历完成后获得未排序部分的最小值,并与第一个未排序的位置交换;选择排序必须遍历N次,不可以提前终止;由于存在跳跃性的交换,不能保证稳定性。
0 点赞 评论 收藏
分享
猿兄:打卡 一刷。 想分享之前 Git 的学习笔记的,但图片全都上传失败了🤣🤣🤣查看图片
0 点赞 评论 收藏
分享
猿兄:打卡 一刷。 顺便分享一下之前学习 Maven 时候做的笔记,希望对后来的朋友有帮助。 1. Maven 是什么? Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和依赖管理。 2. 为什么要用 Maven? 2.1 方便添加第三方 jar 包 在今天的 JavaEE 开发领域,有大量的第三方框架和工具可以供我们使用。要使用这些 jar 包最简单的方法就是复制粘贴到 WEB-INF/lib 目录下。但是这会导致每次创建一个新的工程就需要将 jar 包重复复制到 lib 目录下,从而造成工作区中存在大量重复的文件, 让我们的工程显得很臃肿。而使用 Maven 后每个 jar 包本身只在本地仓库中保存一份,需要 jar 包的工程只需要以坐标的方式简单的引用一下就可以了。不仅极大的节约了存储空间,让项目更轻巧,更避免了重复文件太多而造成的混乱。 2.2 方便解决 jar 包之间的依赖关系 jar 包往往不是孤立存在的,很多 jar 包都需要在其他 jar 包的支持下才能正常工作,这就是 jar 包之间的依赖关系。而这些依赖关系,我们不可能全部知道,特别是使用一个之前从未使用过的 jar 包,我们更难以知道它所要依赖的其他 jar 包。如果我们少引入了一个相关依赖的包,我们的程序将不可能正常工作。当然。你可能会说,提供这些 jar 包的作者会留有所需依赖 jar 包的信息。那么再考虑一下,我们一个大型项目中所需要的 jar 包可能有上百个,这个时候,你还要自己手动的一个个去查看并添加这些 jar 包所依赖的其他包吗? 而我们的 Maven可以自动的将当前 jar 包所依赖的相关其他 jar 包全部导入进来,而不用我们去查看并添加,极大了节省了我们的时间和精力。 2.3 方便获取第三方 jar 包 在我们的 Java 项目开发所要使用到的 jar 包种类繁多,而不同的 jar 包可能有不同的官网以及不同的获取方式。有时候得为查找一个 jar 包耗费大量时间和精力。并且,有可能辛苦所获取的 jar 包里并没有自己所需要的类或方法,因为有时候获取 jar 包的方式不规范,会造成获取到的 jar 包也是不规范的。 而 Maven 可以提供一个完全统一的且规范的 jar 包管理体系。我们所需要的 jar 包可以直接以坐标的方式获取,Maven 会自动从中央仓库中下载这些 jar 包,并且还会自动下载这些 jar 包所依赖的相关其他 jar 包。 2.4 将项目拆分成多个工程模块 现在 JavaEE 项目的开发规模越来越大,而如果一个项目非常庞大,就不适合使用package来划分模块,最好是每一个模块对应一个工程,利于分工协作。 而借助于maven就可以将一个项目拆分成多个工程,便于我们的协同开发。 3. 自动化构建 3.1 什么是构建? 首先要知道,构建并不是创建,创建了一个项目并不等于构建了一个项目。 构建的概念: 构建以我们编写的 Java 代码、框架配置文件、页面、图片等资源作为“原材料”,去“生产”出一个可运行的项目的过程。 3.2 构建过程的几个主要环节 清理: 删除以前的编译结果,为重新编译做好准备。 编译: 将 Java 源程序编译为字节码文件。 测试: 针对项目中的关键点进行测试,确保项目在迭***过程中关键点的正确性。 报告: 在每一次测试后以标准的格式记录和展示测试结果。 打包: 将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。 Java 工程对应 jar 包, Web工程对应 war 包。 安装: 在 Maven 环境下特指将打包的结果——jar 包或 war 包安装到本地仓库中。 部署: 将打包的结果部署到远程仓库或将 war 包部署到服务器上运行 3.3 自动化构建 其实构建过程中的这些环节,在 IDE 中都可以找到相应的操作,那为什么还要自动化构建呢? 因为这些操作都是固定且繁琐的,如果每次都需要我们自己去一步步操作,会很耗费时间。 这个时候,就可以使用 Maven 自动化构建了! Maven 自动化构建可以自动的从构建过程的起点一直执行到最后的终点。 4. 约定的目录结构 约定的目录结构对于 Maven 实现自动化构建而言是必不可少的。比如自动编译, Maven 必须能找到 Java 源文件, 下一步才能编译, 而编译之后也必须有一个准确的位置保持编译得到的字节码文件。我们在开发中如果需要让第三方工具或框架知道我们自己创建的资源在哪,那么基本上就是两种方式:①通过配置的形式明确告诉它②基于第三方工具或框架的约定Maven 对工程目录结构的要求就属于后面的一种,通过约定好的目录结构, Maven 就可以知道各种资源在哪。 Maven 约定的目录结构如下: 5. 仓库、坐标、pom 5.1 仓库 5.1.1 什么是仓库? 仓库是 Maven 用来管理插件和依赖,以及我们自己开发的项目的模块。 所有 Maven 项目都可以通过坐标从仓库中统一获取依赖 jar 包。 5.1.2 仓库的分类 本地仓库为当前电脑上的所有 Maven 工程服务。 远程仓库①***:架设在当前局域网环境下,为当前局域网范围内所有 Maven 工程服务。②中央仓库:架设在因特网上,为全世界所有 Maven 工程服务。 ③中央仓库的镜像: 架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。 5.2 坐标 我们已经知道了所有 Maven 项目都可以通过坐标从仓库中统一获取依赖 jar 包,那坐标是什么样的? <groupId>com.yuanxion.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version> 其中:groupid: 公司或组织的域名倒序+当前项目名称artifactId: 当前项目的模块名称version: 当前模块的版本 使用如上三个向量就可以在 Maven 的仓库中唯一的定位一个 Maven 工程。 那么如何通过这三个向量在仓库中查找对于 jar 包? 首先将三个向量连接起来。com.yuanxion.maven + Hello + 0.0.1-SNAPSHOT 然后根据连起来的字符串作为目录结构去仓库中查找com/yuanxion/maven/Hello/0.0.1-SNAPSHOT/Hello-0.0.1-SNAPSHOT.jar 5.3 pom pom:Project Object Model (项目对象模型) 将 Java 工程的相关信息封装为对象作为便于操作和管理的模型。 主要使用,在 Maven 工程中,通过在 pom.xml 文件中提供坐标,获取项目相关所需的依赖 jar 包。 pom 是 Maven 工程的核心配置。 6. 依赖管理 依赖管理是 Maven 中最关键的部分, 我们使用 Maven 最主要的就是使用它的依赖管理功能,下面看一下依赖管理相关的知识。 6.1 什么是依赖? 当 A jar 包用到了 B jar 包中的某些类时, A 对 B 就产生了依赖 。 6.2 Maven 中怎么使用依赖? 在 pom 文件中使用 dependency 标签指定被依赖的 jar 包的坐标就可。示例: <dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency> 有多个依赖时,可以在 dependency 标签最外层再加一个 dependencies标签。 示例: <dependencies>
<dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>Hey</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies> 6.3 依赖的范围 在上面的示例中,我们可以看到除了所需依赖 jar 包的坐标之外,还有一个 scope 配置,这个是用来设置依赖的范围的。 scope 配置中常用的 3 个可选值:compile、 test、 provided 。 三者的有效性的区别: compile test provided 主程序 √ × √ 测试程序 √ × √ 参与部署 √ × × 6.3 依赖的传递性 A 依赖 B,B 依赖 C,那么 A 能否使用 C 呢?这要看 B 依赖 C 的范围,如果 B 依赖 C 的范围是 compile ,那么 A 也能使用 C;否则不能使用。 6.4 依赖的排除 如果我们的工程中引入了依赖 A,而 A 又依赖 B,那么 Maven 会自动的将 A 依赖的 B 自动导入当前工程。 但是有少数情况下,这个 B 可能是一个不稳定版,或者对当前工程有不好的影响,那么这个时候,我们就得将这个 B 排除掉。 排除的方法:在引入依赖 A 的 dependency 标签内,用 exclusion 标签标记出来;有多个需要排除的依赖可在exclusion 标签外层再加一个 exclusions 标签。 示例: <dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>AAA</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
<exlusions>
<exclusion>
<groupId>com.yx.maven</groupId>
<artifactId>BBB</artifactId>
</exclusion>
<exlusions>
</dependency> 6.5 统一管理所依赖 jar 包的版本 对同一个框架的一组 jar 包最好使用相同的版本,并且统一版本还可以方便升级框架。 首先统一版本号 <properties>
<yx.Spring.version>4.3.4.RELEASE</yx.Spring.version>
</properties> 其中<yx.Spring.version> 是自定义标签。 在需要使用版本的地方使用:${标签名} <dependencies>
<dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>Hello</artifactId>
<version>${yx.Spring.version}</version>
</dependency>
</dependencies> 另外,这个 properties 里还可以设置项目中一些其它的相关配置,比如字符集: <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties> 6.6 解决 jar 包冲突(依赖的原则) 1. 路径最短者优先 项目A 依赖 B,B 又依赖 C。 并且 B 和 C 都依赖 D,不过依赖的版本不一样,B 依赖是 D-1.0 版本,C 依赖的是 D-2.0 版本。 因为项目 A 是先依赖的 B ;然后通过 B 依赖 C 的依赖传递,A 也依赖了 C 。 A 到 B 的路径相当于是 1,A 到 D-1.0 的路径相当于就是 2 ; A 到 C 的路径相当于是 2,A 到 D-2.0 的路径相当于就是 3 ; 所以 A 会根据最短路径优先的原则,会使用 D-1.0 。 2. 路径相同时,先声明者优先 这里“声明”的先后指的是在 pom 中的 dependency 标签的先后顺序。 比如: 项目A 依赖 B,B 依赖 D-1.0; 项目A 依赖 C,C 依赖 D-2.0。 因为 D-1.0 与 D-2.0 的路径相同,路径最短者优先原则就没用了。 这个时候应该看 B 和 C 在 pom 中声明的顺序,先声明的优先。 <dependencies>
<dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>B</artifactId>
<version>${yx.Spring.version}</version>
</dependency>
<dependency>
<groupId>com.yuanxion.maven</groupId>
<artifactId>C</artifactId>
<version>${yx.Spring.version}</version>
</dependency>
</dependencies> 上面的声明中,B 比 C 先声明,所以使用 B 的依赖:D-1.0 。 7. Maven 生命周期 7.1 什么是 Maven 的生命周期? Maven 生命周期定义了各个构建环节的执行顺序,有了这个清单, Maven就可以自动化的执行构建命令了。 Maven 有三套相互独立的生命周期: Clean Lifecycle 在进行真正的构建之前进行一些清理工作。 Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。 Site Lifecycle 生成项目报告,站点,发布站点。 这些生命周期是相互独立的,我们可以只调用 clean 来清理工作目录,或者只调用 site 来生成站点 ,当然也可以运行 mvn clean install site 一起运行这三套生命周期。 每套生命周期都由一组阶段(Phase)组成,我们平时在命令行输入的命令总会对应于一个特定的阶段。比如,运行 mvn clean,这个 clean 是 Clean 生命周期中的一个阶段。 7.2 Clean 生命周期的各阶段 pre-clean :执行一些需要在 clean 之前完成的工作; clean :移除所有上一次构建生成的文件; post-clean :执行一些需要在 clean 之后立刻完成的工作。 7.3 Site 生命周期的各阶段 pre-site :执行一些需要在生成站点文档之前完成的工作 site : 生成项目的站点文档 post-site : 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备 site-deploy :将生成的站点文档部署到特定的服务器上 这里面经常用到的是 site 阶段和 site-deploy 阶段,用于生成和发布 Maven 站点,这是 Maven 相当强大的功能,可以自动生成文档及统计数据。 7.4 Default 生命周期的各阶段 Default 生命周期是 Maven 生命周期中最重要的一个,绝大部分工作都发生在这个生命周期中。 下面这些阶段中黑体加粗的是比较重要和常用的阶段: validate generate-sources process-sources generate-resources process-resources :复制并处理资源文件,至目标目录,准备打包。 compile :编译项目的源代码。 process-classes generate-test-sources process-test-sources generate-test-resources process-test-resources :复制并处理资源文件,至目标测试目录。 test-compile :编译测试源代码。 process-test-classes test :使用合适的单元测试框架运行测试。这些测试代码不会被打包或部署。 prepare-package package :接受编译好的代码,打包成可发布的格式,如 JAR。 pre-integration-test integration-test post-integration-test verify install :将包安装至本地仓库,以让其它项目依赖。 deploy :将最终的包复制到远程的仓库,以让其它开发人员与项目共享或部署到服务器上运行。 7.5 生命周期与自动化构建 运行任何一个阶段的时候,它前面的所有阶段都会被运行。 比如我们运行 mvn install 的时候,代码将前面的 compile,test,package 都运行了。 这就是 Maven 为什么能够自动执行构建过程的各个环节的原因。 此外, Maven 的插件机制是完全依赖 Maven 的生命周期的,因此理解生命周期至关重要。 8. 插件和目标 Maven 的核心只定义了抽象的生命周期,具体的任务都是交由插件完成的。 每个插件都能实现多个功能,每个功能就是一个插件目标。 Maven 的生命周期与插件目标相互绑定,以完成某个具体的构建任务。比如compile 就是插件 maven-compiler-plugin 的一个目标;pre-clean 是插件 maven-clean-plugin 的一个目标。 9. 继承 9.1 为什么需要继承? 因为非 compile 范围的依赖信息是不能在“依赖链”中传递的, 所以有需要的工程只能单独配置。 例如: 很多模板都需要测试的 junit ,junit 的范围是 test,不能传递依赖,而此时如果需要将各个模板中的 junit 版本统一,那么手动设置和修改各个模板中的版本号是非常耗时的。 而这个时候使用继承机制,就可以将这样的依赖信息统一提取到父工程模块中进行统一管理。 9.2 继承的使用步骤 9.2.1 创建父工程 创建父工程和创建一般的 Java 工程操作一样,唯一需要注意的地方是: 打包方式要设置为 pom。 9.2.2 在子工程中引用父工程 <parent>
<!-- 父工程坐标 -->
<groupId>com.atguigu.maven</groupId>
<artifactId>Parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- 指定从当前子工程的pom.xml文件出发,查找父工程的pom.xml的路径 -->
<relativePath>../Parent/pom.xml</relativePath>
</parent> 此时如果子工程的 groupId 和 version 如果和父工程重复,则可以省略。 9.2.3 在父工程中管理依赖 将 父工程中 pom 文件中的 dependencies 标签,用 dependencyManagement 标签括起来。 <dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement> 9.2.4 在子工程中指定需要的依赖 无需范围和版本号,会从父工程统继承过来。 <dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies> 如果子工程中的依赖指定了版本号,则会使用子工程指定的版本号。 10. 聚合 10.1 为什么要使用聚合? 将多个工程拆分为模块后, 需要手动逐个安装到仓库后依赖才能够生效。 修改源码后也需要逐个手动进行 clean 操作。 而使用了聚合之后就可以批量进行 Maven 工程的安装、清理工作。 节省时间,提升效率。 10.2 聚合的配置 在总的聚合工程中使用 modules/module 标签组合, 指定模块工程的相对路径即可 。 <modules>
<module>../Hello</module>
<module>../HelloFriend</module>
<module>../MakeFriends</module>
</modules> 11. 其他类似的版本控制工具? Ant : 具有编译、测试、打包功能,不过没有依赖管理功能。 Gradle : Maven 的功能都有,并且支持 Groovy 语言。 Gradle 和 Maven 的区别: Gradle 使用 Groovy 这种特定领域语言(DSL)来管理构建脚本,而不再使用 XML 这种标记性语言。因为项目如果庞大的话,XML 很容易就变得臃肿。 12. Maven 依赖查询网站 https://mvnrepository.com/查看图片
0 点赞 评论 收藏
分享
猿兄:打卡 一刷。
0 点赞 评论 收藏
分享
牛客601154620号:“允许脏读取。如果一个事务已经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。”此处是不是应该是“另一个事务不允许同时”进行写操作呀?
0 点赞 评论 收藏
分享
Deer77:那个主键索引和普通索引第一行的3、7;23,27啥意思呐?
0 点赞 评论 收藏
分享
Shawn_Liu:'''
DNS解析:将域名解析成对应的服务器IP地址。
TCP连接:拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有httpd,nginx等)80端口发起TCP的连接请求。这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),还有可能要经过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终建立了TCP/IP的连接。
发送HTTP请求:建立了TCP连接之后,发起一个http请求。一个典型的 http request header 一般需要包括请求的方法,例如 GET 或者 POST 等,不常用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的浏览器只能发起 GET 或者 POST 请求。
客户端向服务器发起http请求的时候,会有一些请求信息,请求信息包含三个部分:
请求方法URI协议/版本
请求头(Request Header)
请求正文:
服务器处理请求并返回HTTP报文:后端从在固定的端口接收到TCP报文开始,它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。
HTTP报文;就是返回一个HTPP响应。 HTTP响应与HTTP请求相似,HTTP响应也由3个部分构成,分别是:
状态行
响应头(Response Header)
空行
响应正文
浏览器解析渲染页面:WebKit渲染的过程:构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树
连接结束:现在的页面为了优化请求的耗时,默认都会开启持久连接(keep-alive),那么一个TCP连接确切关闭的时机,是这个tab标签页关闭的时候。这个关闭的过程就是著名的四次挥手。关闭是一个全双工的过程,发包的顺序的不一定的。
'''
0 点赞 评论 收藏
分享
中都:<span style="color:#333333;">面试吉比特的时候就问了我http请求头响应头的知识,还有https,我的理解,服务器用明文的方式给客户端发送自己的公钥,客户端收到公钥之后,会生成一把密钥(对称加密用的),然后用服务器的公钥对这把密钥进行加密,之后再把密钥传输给服务器,服务器收到之后进行解密,最后服务器就可以安全着得到这把密钥了,而客户端也有同样一把密钥,他们就可以进行对称加密了(对象加密效率高)。(这中间为了保证这个公钥是服务端的需要服务端提供CA证书和数字签名,否则会有中间人劫持的情况出现);</span><br />
0 点赞 评论 收藏
分享
没有活给干:https://blog.csdn.net/weixin_38700769/article/details/106747977 自己对tcp/IP做了一个总结,看了楼主文章,部分没有写的内容可以参考我呀~
0 点赞 评论 收藏
分享
猿兄:打卡 一刷。 消息队列学了 RabbitMQ,回去复习了下。
0 点赞 评论 收藏
分享
创作者周榜
更多
关注他的用户也关注了: