├── .gitignore ├── LICENSE ├── README.md ├── interview-code ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── interview │ ├── Lesson1_1.java │ ├── Lesson1_2.java │ ├── Lesson1_3.java │ ├── Lesson1_4.java │ ├── Lesson1_5.java │ ├── Lesson1_6.java │ ├── Lesson1_7.java │ ├── Lesson2_1.java │ ├── Lesson2_2.java │ ├── Lesson2_3.java │ ├── Lesson2_4.java │ ├── Lesson3_1.java │ ├── Lesson3_2.java │ ├── Lesson3_3.java │ ├── Lesson3_4.java │ ├── Lesson4_1.java │ ├── Lesson4_2.java │ ├── Lesson5_1.java │ ├── Lesson5_2.java │ ├── Lesson5_4.java │ ├── Lesson5_5.java │ ├── Lesson5_6.java │ ├── Lesson5_7.java │ ├── Lesson6_1.java │ ├── Lesson7_3.java │ ├── Lesson7_4.java │ └── other │ ├── CustomDelayQueue.java │ ├── EnumTest.java │ ├── RocketMQDemo.java │ └── SynchronizedTest.java ├── mybatislearning-xml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── interview │ │ │ └── mybatislearning │ │ │ ├── MyBatisLearningApplication.java │ │ │ ├── mapper │ │ │ └── UserMapper.java │ │ │ └── model │ │ │ └── UserEntity.java │ └── resources │ │ ├── application.yml │ │ └── mybatis │ │ ├── mapper │ │ └── UserMapper.xml │ │ └── mybatis-config.xml │ └── test │ └── java │ └── com │ └── interview │ └── mybatislearning │ └── MybatislearningApplicationTests.java ├── mybatislearning ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── interview │ │ │ ├── MybatisApplication.java │ │ │ ├── mapper │ │ │ └── UserMapper.java │ │ │ └── model │ │ │ └── UserEntity.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── com │ └── interview │ └── MybatisApplicationTests.java ├── springbootlearning ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── interview │ │ │ └── java │ │ │ └── springbootlearning │ │ │ ├── HelloController.java │ │ │ └── SpringbootlearningApplication.java │ └── resources │ │ ├── application.properties │ │ └── application.yml │ └── test │ └── java │ └── com │ └── interview │ └── java │ └── springbootlearning │ └── SpringbootlearningApplicationTests.java └── springlearning ├── pom.xml └── src └── main ├── java └── com │ └── learning │ ├── aop │ ├── CarAop.java │ ├── Person.java │ └── PersonTest.java │ ├── config │ └── MyConfiguration.java │ ├── controller │ ├── HomeController.java │ └── PersonController.java │ ├── core │ └── MyInteceptor.java │ └── pojo │ └── PersonDTO.java ├── resource └── spring-mvc.xml └── webapp └── WEB-INF ├── views └── index.jsp └── web.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | /interview-code/out 25 | /interview-code/.idea 26 | /interview-code/*.iml 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java 面试全解析 2 | 3 | ### 知识树 4 | 5 | ![技能点图片](http://icdn.apigo.cn/blog/java-interview-mindmap.png) 6 | 7 | ### 课程亮点 8 | 9 | - **500道 Java 常见面试题 + 14万字核心知识解析** 10 | - **丰富的 Java 技术栈:基础和框架,线程池和锁优化,SpringBoot 和分布式消息队列,数据结构和常用算法,设计模式和 JVM 等** 11 | - **易学易会:提供了大量的图片说明和代码示例** 12 | 13 | ### 你会获得什么 14 | 15 | - **收获 Java 技术栈的核心知识点** 16 | 17 | 这个课程几乎涵盖了 Java 技术栈的大部分内容,不止对于面试,在日常的工作中也可以发挥很大的作用。 18 | 19 | - **详解 500 多道实用、权威、高频 Java 面试题** 20 | 21 | 这 500 多道面试题,都是目前主流企业使用最高频的面试题库,也都是 Java 版本升级之后,重新整理归纳的最新答案,会让面试者少走很多不必要的弯路。同时每道题都做到了详尽的描述,以确保每个阶段的读者都能看得懂,面试题中的专业短语也都确保提供了必要的介绍,部分难懂的题目也提供了题目解析和示例代码。 22 | 23 | - **理解技术背后的实现原理** 24 | 25 | 死记硬背的内容通常会随着时间的推移很快就忘记,所以在学习一门技术的时候,一定要了解其背后的实现原理,从而构建逻辑上的因果关系,这样才能够记的更久。这门课程会深入浅出地对技术背后的原理进行深入的分析,让读者“知其然,并知其所以然”。 26 | 27 | ### 适宜人群 28 | 29 | - 准备 Java 面试的在校生(大专或研究生) 30 | - 准备跳槽、正在找工作的 Java 工程师 31 | - 自学和准备转行到 Java 技术领域的人 32 | - 想巩固 Java 核心知识、查漏补缺的人 33 | 34 | ### 课程目录 35 | 36 | [开篇词|如何轻松获得Offer](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9/topic/5d493cfecb702a087ef935e5) 37 | 38 | ### 第一章 39 | 40 | [第1-1课:Java程序是如何执行的?](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9/topic/5d4d72a269004b174ccfff43) 41 | 42 | [第1-2课:你不知道的基础数据类型和包装类——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9/topic/5d4d775d69004b174ccfff5c) 43 | 44 | [第1-3课:深入理解字符串——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 45 | 46 | [第1-4课:Java中的运算符和流程控制——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 47 | 48 | [第1-5课:深入了解Java中的异常处理——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 49 | 50 | [第1-6课:玩转时间——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 51 | 52 | [第1-7课:数组和排序算法——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 53 | 54 | ### 第二章 55 | 56 | [第2-1课:类与Object——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 57 | 58 | [第2-2课:各种内部类和枚举类——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 59 | 60 | [第2-3课:抽象类和接口——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 61 | 62 | [第2-4课:克隆和序列化——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 63 | 64 | ### 第三章 65 | 66 | [第3-1课:集合详解(上)——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 67 | 68 | [第3-2课:集合详解(下)——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 69 | 70 | [第3-3课:泛型和迭代器——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 71 | 72 | [第3-4课:数据结构:队列详解——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 73 | 74 | ### 第四章 75 | 76 | [第4-1课:BIO、NIO、AIO详解——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 77 | 78 | [第4-2课:反射和动态代理——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 79 | 80 | ### 第五章 81 | 82 | [第5-1课:线程与死锁——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 83 | 84 | [第5-2课:线程池—ThreadPoolExecutor——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 85 | 86 | [第5-3课:线程池—Executors——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 87 | 88 | [第5-4课:ThreadLocal详解——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 89 | 90 | [第5-5课:线程安全—synchronized和ReentrantLock——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 91 | 92 | [第5-6课:Java并发包中的高级同步工具——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 93 | 94 | [第5-7课:Java中的各种锁和CAS——附面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 95 | 96 | ### 第六章 97 | 98 | [第6-1课:Spring核心和面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 99 | 100 | [第6-2课:SpringMVC核心和面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 101 | 102 | [第6-3课:SpringBoot核心和面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 103 | 104 | [第6-4课:MyBatis核心和面试题](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 105 | 106 | [第6-5课:消息队列面试题汇总](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 107 | 108 | [第6-6课:Java分布式框架面试题合集](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 109 | 110 | ### 第七章 111 | 112 | [第7-1课:MySQL面试题汇总](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 113 | 114 | [第7-2课:Redis面试题汇总](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 115 | 116 | [第7-3课:设计模式常见面试题汇总](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 117 | 118 | [第7-4课:算法常用面试题汇总](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 119 | 120 | [第7-5课:JVM面试题汇总](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 121 | 122 | [第7-6课:常见面试题翻车合集](https://gitbook.cn/gitchat/column/5d493b4dcb702a087ef935d9) 123 | -------------------------------------------------------------------------------- /interview-code/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | groupId 8 | interview-code 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 1.8 13 | 14 | 15 | 16 | 17 | 18 | com.alibaba 19 | fastjson 20 | 1.2.58 21 | 22 | 23 | 24 | org.apache.commons 25 | commons-lang3 26 | 3.9 27 | 28 | 29 | 30 | com.caucho 31 | hessian 32 | 4.0.60 33 | 34 | 35 | 36 | cglib 37 | cglib 38 | 3.2.12 39 | 40 | 41 | 42 | com.alibaba.rocketmq 43 | rocketmq-client 44 | 3.6.2.Final 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-compiler-plugin 53 | 54 | 1.8 55 | 1.8 56 | UTF-8 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_1.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.Calendar; 5 | 6 | public class Lesson1_1 { 7 | public static void main(String[] args) { 8 | // 获取明天此刻时间 9 | Calendar calendar = Calendar.getInstance(); 10 | calendar.add(Calendar.DATE, 1); 11 | System.out.println(calendar.getTime()); 12 | LocalDateTime today = LocalDateTime.now(); 13 | LocalDateTime tomorrow = today.minusDays(-1); 14 | //LocalDateTime tomorrow = today.plusDays(1); 15 | System.out.println(tomorrow); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_2.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class Lesson1_2 { 7 | public static void main(String[] args) { 8 | // 极值查询打印 9 | System.out.println(String.format("Byte:%d ~ %d", Byte.MIN_VALUE, Byte.MAX_VALUE)); // -128 ~ 127 10 | System.out.println(String.format("Int:%d ~ %d", Integer.MIN_VALUE, Integer.MAX_VALUE)); // -2147483648 ~ 2147483647 11 | // 高频区缓存范围 -128~127 测试 12 | Integer num1 = 127; 13 | Integer num2 = 127; 14 | System.out.println("Integer等于127时:" + (num1 == num2)); // true 15 | Integer num3 = 128; 16 | Integer num4 = 128; 17 | System.out.println("Integer等于128时:" + (num3 == num4)); // false 18 | System.out.println("Integer等于128时 equals:" + num3.equals(num4)); // true 19 | // Integer 高频区域的最大值演示 20 | Integer i1 = -128; 21 | Integer i2 = -128; 22 | System.out.println("值为-128 => " + (i1 == i2)); 23 | Integer i3 = 666; 24 | Integer i4 = 666; 25 | System.out.println("值为666 => " + (i3 == i4)); 26 | Integer i5 = 667; 27 | Integer i6 = 667; 28 | System.out.println("值为667 => " + (i5 == i6)); 29 | // 面试题示例代码 30 | Integer age1 = 10; 31 | Integer age2 = 10; 32 | Integer age3 = 133; 33 | Integer age4 = 133; 34 | Double d1 = 10d; 35 | Double d2 = 10d; 36 | Double d3 = 133d; 37 | Double d4 = 133d; 38 | System.out.println((age1 == age2) + "," + (age3 == age4)); 39 | System.out.println((d1 == d2) + "," + (d3 == d4)); 40 | // int 和 Integer 比较 41 | int a = 100; 42 | Integer b = new Integer(100); 43 | System.out.println(a == b); 44 | System.out.println(b.equals(a)); 45 | // Integer.MAX_VALUE + 1 46 | final int numMax = Integer.MAX_VALUE; 47 | System.out.println(numMax + 1); 48 | // short 类型升级为 int 49 | Set set = new HashSet<>(); 50 | for (short i = 0; i < 5; i++) { 51 | set.add(i); 52 | set.remove(i - 1); 53 | } 54 | System.out.println(set.size()); 55 | // new Integer(n) 和 Integer.valueOf(n) 的区别 56 | Integer v1 = new Integer(10); 57 | Integer v2 = new Integer(10); 58 | Integer v3 = Integer.valueOf(10); 59 | Integer v4 = Integer.valueOf(10); 60 | System.out.println(v1 == v2); 61 | System.out.println(v2 == v3); 62 | System.out.println(v3 == v4); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_3.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | public class Lesson1_3 { 4 | public static void main(String[] args) { 5 | // String 引用对比 6 | String s1 = "laowang"; 7 | String s2 = s1; 8 | String s3 = new String(s1); 9 | System.out.println(s1 == s2); 10 | System.out.println(s1 == s3); 11 | // java编译对String的优化 12 | String as1 = "hi," + "lao" + "wang"; 13 | String as2 = "hi,"; 14 | as2 += "lao"; 15 | as2 += "wang"; 16 | String as3 = "hi,laowang"; 17 | System.out.println(as1 == as3); // false 18 | System.out.println(as1 == as3); // true 19 | System.out.println(as2 == as3); // false 20 | // String参数传递 21 | String str = new String("laowang"); 22 | change(str); 23 | System.out.println(str); // laowang 24 | // StringBuffer参数传递 25 | StringBuffer sb = new StringBuffer("hi,"); 26 | changeBuffer(sb); 27 | System.out.println(sb); // hi,laowang 28 | // substring截取 29 | String subStr = "ABCDEF"; 30 | System.out.println(subStr.substring(2)); // CDEF 31 | System.out.println(subStr.substring(2, 4)); // CD(包含开始下标不包含结束下标) 32 | // String.format 33 | String sf = String.format("我叫%s,今年%d岁,喜欢%s", "老王", 30, "读书"); 34 | System.out.println(sf); 35 | // String equals 36 | String es1 = "hi," + "lao" + "wang"; 37 | String es2 = "hi,"; 38 | es2 += "lao"; 39 | es2 += "wang"; 40 | String es3 = "hi,laowang"; 41 | System.out.println(es1.equals(es2)); 42 | System.out.println(es1.equals(es3)); 43 | System.out.println(es2.equals(es3)); 44 | // String 大小写比较 45 | String eis1 = "Hi,laowang"; 46 | String eis2 = "hi,laowang"; 47 | System.out.println(eis1.equals(eis2)); // false 48 | System.out.println(eis1.equalsIgnoreCase(eis2)); // true 49 | // StringBuilder 用法 50 | StringBuilder stringBuilder = new StringBuilder("lao"); 51 | // 添加字符串到尾部 52 | stringBuilder.append("wang"); // laowang 53 | // 插入字符串到到当前字符串下标的位置 54 | stringBuilder.insert(0, "hi,"); // hi,laowang 55 | // 修改字符中某个下标的值 56 | stringBuilder.setCharAt(0, 'H'); // Hi,laowang 57 | System.out.println(stringBuilder); 58 | // String intern 用法 59 | String str1 = "hi"; 60 | String str2 = new String("hi"); 61 | String str3 = new String("hi").intern(); 62 | System.out.println(str1 == str2); // false 63 | System.out.println(str1 == str3); // true 64 | } 65 | 66 | public static void change(String s) { 67 | s = "xiaowang"; 68 | } 69 | 70 | public static void changeBuffer(StringBuffer sb) { 71 | sb.append("laowang"); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_4.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | public class Lesson1_4 { 4 | static int count = 0; 5 | 6 | public static void main(String[] args) { 7 | // 方式一,跳出多重循环 8 | myfor: 9 | for (int i = 0; i < 100; i++) { 10 | for (int j = 0; j < 100; j++) { 11 | System.out.println("J:" + j); 12 | if (j == 10) { 13 | // 跳出多重循环 14 | break myfor; 15 | } 16 | } 17 | } 18 | // 方式二,跳出多重循环 19 | boolean flag = true; 20 | for (int i = 0; i < 100 && flag; i++) { 21 | for (int j = 0; j < 100; j++) { 22 | System.out.println("J:" + j); 23 | if (j == 10) { 24 | // 跳出多重循环 25 | flag = false; 26 | break; 27 | } 28 | } 29 | } 30 | // 循环永远无法停下来 31 | // for (float i = 0; i != 1; i += 0.1) { 32 | // System.out.println(i); 33 | // } 34 | // ++i 在多线程下产生的混乱 35 | new Thread() { 36 | @Override 37 | public void run() { 38 | for (int i = 0; i < 100000; i++) { 39 | System.out.println("thread:" + this.getName() + ",count=" + (++count)); 40 | } 41 | } 42 | }.start(); 43 | new Thread() { 44 | @Override 45 | public void run() { 46 | for (int i = 0; i < 100000; i++) { 47 | System.out.println("thread:" + this.getName() + ",count=" + (++count)); 48 | } 49 | } 50 | }.start(); 51 | // ++i 基本使用 52 | int i = 1; 53 | int i2 = ++i; // ++i 同等于 i=n+i; 54 | System.out.println(i); // 2 55 | System.out.println(i2); // 2 56 | // 条件运算符 57 | String s = 3 > 1 ? "三大于一" : "三小于一"; 58 | System.out.println(s); 59 | // if 基础用法 60 | int num1 = 1; 61 | if (num1 > 1) { 62 | System.out.println("大于一"); 63 | } else if (num1 == 1) { 64 | System.out.println("等于一"); 65 | } else { 66 | System.out.println("其他"); 67 | } 68 | //while 使用 * 69 | int w = 0; 70 | while (w < 3) { 71 | if (w == 2) { 72 | return; 73 | } 74 | System.out.println(++w); 75 | } 76 | //do/while 使用 * 77 | int d = 0; 78 | do { 79 | System.out.println(++d); 80 | } while (d < 3); 81 | // for 使用 82 | for (int j = 0; j < 10; j++) { 83 | System.out.println("j:" + j); 84 | } 85 | // continue 使用 86 | for (int j = 1; j < 4; j++) { 87 | if (j == 2) continue; 88 | System.out.println("j:" + j); 89 | } 90 | //switch 无 break 代码 91 | switch (i) { 92 | case 1: 93 | System.out.println("等于1"); 94 | case 2: 95 | System.out.println("等于2"); 96 | case 3: 97 | System.out.println("等于3"); 98 | default: 99 | System.out.println("其他"); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_5.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import com.alibaba.fastjson.JSONArray; 4 | import com.alibaba.fastjson.JSONObject; 5 | 6 | import java.io.FileReader; 7 | import java.io.FileWriter; 8 | import java.io.IOException; 9 | 10 | public class Lesson1_5 { 11 | public static void main(String[] args) { 12 | // try-catch-finally 基本使用 13 | try { 14 | int i = 10 / 0; 15 | } catch (ArithmeticException e) { 16 | System.out.println(e); 17 | } finally { 18 | System.out.println("finally"); 19 | } 20 | // 多 catch 使用 21 | try { 22 | int i = Integer.parseInt(null); 23 | } catch (ArithmeticException ae) { 24 | System.out.println("ArithmeticException"); 25 | } catch (NullPointerException ne) { 26 | System.out.println("NullPointerException"); 27 | } catch (Exception e) { 28 | System.out.println("Exception"); 29 | } 30 | // 使用 try-catch 处理业务 31 | // 引用 com.alibaba.fastjson 32 | JSONArray array = new JSONArray(); 33 | String jsonStr = "{'name':'laowang'}"; 34 | try { 35 | array = JSONArray.parseArray(jsonStr); 36 | } catch (Exception e) { 37 | array.add(JSONObject.parse(jsonStr)); 38 | } 39 | System.out.println(array.size()); 40 | // ry-catch 处理业务的正确使用方式 41 | if (null != jsonStr && !jsonStr.equals("")) { 42 | String firstChar = jsonStr.substring(0, 1); 43 | if (firstChar.equals("{")) { 44 | array.add(JSONObject.parse(jsonStr)); 45 | } else if (firstChar.equals("[")) { 46 | array = JSONArray.parseArray(jsonStr); 47 | } 48 | } 49 | System.out.println(array.size()); 50 | try { 51 | array = JSONArray.parseArray(jsonStr); 52 | } catch (Exception e) { 53 | array.add(JSONObject.parse(jsonStr)); 54 | } 55 | System.out.println(array.size()); 56 | // Integer.parseInt 和 Double.parseDouble 的异常类型 57 | try { 58 | Integer.parseInt(null); 59 | } catch (Exception e) { 60 | System.out.println(e); 61 | } 62 | try { 63 | Double.parseDouble(null); 64 | } catch (Exception e) { 65 | System.out.println(e); 66 | } 67 | // try-with-resources 和 multiple catch 68 | try (FileReader fileReader = new FileReader(""); 69 | FileWriter fileWriter = new FileWriter("")) { // Try-with-resources 70 | System.out.println("try"); 71 | } catch (IOException | NullPointerException e) { // Multiple catch 72 | System.out.println(e); 73 | } 74 | // finally 中发生的异常 75 | try { 76 | System.out.println("try"); 77 | } catch (Exception e) { 78 | System.out.println("catch"); 79 | } finally { 80 | int k = 3 / 0; 81 | System.out.println("finally"); 82 | } 83 | // fiannly 返回值演示 84 | System.out.println(getNumber()); 85 | } 86 | 87 | public static int getNumber() { 88 | try { 89 | int number = 0 / 1; 90 | return 2; 91 | } finally { 92 | return 3; 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_6.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.sql.Timestamp; 4 | import java.text.ParseException; 5 | import java.text.SimpleDateFormat; 6 | import java.time.*; 7 | import java.time.format.DateTimeFormatter; 8 | import java.time.temporal.TemporalAdjusters; 9 | import java.util.Calendar; 10 | import java.util.Date; 11 | 12 | public class Lesson1_6 { 13 | public static void main(String[] args) throws ParseException, InterruptedException { 14 | // 【时间操作 JDK 8 之前】 15 | // 获得当前时间 16 | Date date = new Date(); 17 | System.out.println(date); 18 | Calendar calendar = Calendar.getInstance(); 19 | Date time = calendar.getTime(); 20 | System.out.println(time); 21 | // 获取当前时间戳 22 | long ts1 = new Date().getTime(); 23 | System.out.println(ts1); 24 | long ts2 = System.currentTimeMillis(); 25 | System.out.println(ts2); 26 | long ts3 = Calendar.getInstance().getTimeInMillis(); 27 | System.out.println(ts3); 28 | // 时间格式化 29 | SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 30 | System.out.println(sf.format(new Date())); // output:2019-08-16 21:46:22 31 | // String 转 Date 32 | String str = "2019-10-10 10:10:10"; 33 | System.out.println(sf.parse(str)); 34 | //时间戳的字符串 转 Date 35 | String tsString = "1556788591462"; 36 | // import java.sql 37 | Timestamp ts = new Timestamp(Long.parseLong(tsString)); // 时间戳的字符串 转 Date 38 | System.out.println(sf.format(ts)); 39 | // 获得昨天此刻的时间 40 | calendar.add(Calendar.DATE, -1); 41 | System.out.println(calendar.getTime()); 42 | // 【JDK 8 时间操作】 43 | // 相隔时间 44 | LocalDateTime dt1 = LocalDateTime.now(); 45 | LocalDateTime dt2 = dt1.plusSeconds(60); 46 | Duration duration = Duration.between(dt1, dt2); 47 | System.out.println(duration.getSeconds()); // output:60 48 | // 相隔日期 49 | LocalDate d1 = LocalDate.now(); 50 | LocalDate d2 = d1.plusDays(2); 51 | Period period = Period.between(d1, d2); 52 | System.out.println(period.getDays()); //output:2 53 | // 获取日期 54 | LocalDate localDate = LocalDate.now(); 55 | System.out.println(localDate); 56 | // 获取时间 57 | LocalTime localTime = LocalTime.now(); 58 | System.out.println(localTime); 59 | // 获取日期和时间 60 | LocalDateTime localDateTime = LocalDateTime.now(); 61 | System.out.println(localDateTime); 62 | // 获取时间戳 63 | long milli = Instant.now().toEpochMilli(); // 获取当前时间戳(精确到毫秒) 64 | long second = Instant.now().getEpochSecond(); // 获取当前时间戳(精确到秒) 65 | System.out.println(milli); // output:1565932435792 66 | System.out.println(second); // output:1565932435 67 | // 格式化时间① 68 | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 69 | String timeFormat = dateTimeFormatter.format(LocalDateTime.now()); 70 | System.out.println(timeFormat); // output:2019-08-16 21:15:43 71 | // 格式化时间② 72 | String timeFormat2 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 73 | System.out.println(timeFormat2); // output:2019-08-16 21:17:48 74 | // 获取昨天此刻时间 75 | LocalDateTime today = LocalDateTime.now(); 76 | LocalDateTime yesterday = today.plusDays(-1); 77 | System.out.println(yesterday); 78 | // 字符串转换为时间 79 | String timeStr = "2019-10-10 06:06:06"; 80 | LocalDateTime dateTime = LocalDateTime.parse(timeStr,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 81 | System.out.println(dateTime); 82 | // 获取本月的最后一天(JDK 8 之前) 83 | Calendar ca = Calendar.getInstance(); 84 | ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); 85 | System.out.println(ca.getTime()); 86 | // 获取本月的最后一天(JDK 8) 87 | System.out.println(today.with(TemporalAdjusters.lastDayOfMonth())); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson1_7.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | public class Lesson1_7 { 10 | public static void main(String[] args) { 11 | // 数组传参示例 12 | int[] intArray = {2, 3, 4, 8}; 13 | change(intArray); 14 | System.out.println(intArray[2]); 15 | // 字符串转数组 16 | String str = "laowang,stone,wanglei"; 17 | String[] strArray = str.split(","); // 字符串转数组 18 | System.out.println(strArray[0]); 19 | // String To Array 20 | String[] arr = {"laowang", "stone", "wanglei"}; 21 | // 方式一:遍历 22 | StringBuffer sb = new StringBuffer(); 23 | for (int i = 0; i < arr.length; i++) { 24 | sb.append(arr[i]); 25 | if (i != arr.length - 1) 26 | sb.append(","); 27 | } 28 | System.out.println(sb.toString()); 29 | // 方式二:Arrays.toString 30 | String str2 = Arrays.toString(arr); 31 | System.out.println(str2); 32 | // 方式三:StringUtils.join 33 | String str3 = StringUtils.join(Arrays.asList(arr), ","); // 使用英文逗号分隔 34 | System.out.println(str3); 35 | // 数组初始化 36 | // 初始化方式一 37 | int[] initArray = new int[5]; 38 | // 初始化方式二 39 | int[] initArray2 = new int[]{1, 2, 3, 4, 5}; 40 | // 初始化方式二的延伸版,可省略 new int[] 直接赋值 41 | int[] initArray3 = {1, 2, 3, 4, 5}; 42 | // 数组遍历 43 | Integer[] itArray = {2, 3, 6, 7, 9}; 44 | // 方式一:传统 for 45 | for (int i = 0; i < itArray.length; i++) { 46 | System.out.println(itArray[i]); 47 | } 48 | // 方式二:for each 49 | for (int i : itArray) { 50 | System.out.println(i); 51 | } 52 | // 方式三:jdk 8 Limbda 53 | Arrays.asList(itArray).forEach(x -> System.out.println(x)); 54 | // 初始化数组面试题 55 | int[] intArr = new int[3]; 56 | String[] StrArr = new String[3]; 57 | System.out.println(intArr[1]); 58 | System.out.println(StrArr[1]); 59 | // Arrays.fill 填充值 60 | int[] fillArray = new int[5]; 61 | // 给数组的所有元素分配一个值 62 | Arrays.fill(fillArray, 9); 63 | for (int i : fillArray) { 64 | System.out.println(i); 65 | } 66 | // Arrays.sort 排序 67 | String[] strArr = {"dog", "cat", "pig", "bird"}; 68 | Arrays.sort(strArr); 69 | System.out.println(Arrays.toString(strArr)); 70 | // 数组值比较 71 | String[] strArr1 = {"dog", "cat", "pig", "bird"}; 72 | String[] strArr2 = {"dog", "cat", "pig", "bird"}; 73 | System.out.println(Arrays.equals(strArr1, strArr2)); 74 | System.out.println(strArr1.equals(strArr2)); 75 | System.out.println(strArr1 == strArr2); 76 | // 二分法查询元素 Arrays.binarySearch 的正确使用方式 77 | String[] searchArray = {"dog", "cat", "pig", "bird"}; 78 | Arrays.sort(searchArray); 79 | // 使用二分法查询数组元素,查询到返回元素的索引位置,查找不到返回-1 80 | int result = Arrays.binarySearch(searchArray, "bird"); 81 | System.out.println(result == -1); 82 | // 二维数组的使用 83 | // 声明二维数组 84 | int[][] twoArray = new int[2][4]; 85 | //循环二维数组 86 | for (int i = 0; i < twoArray.length; i++) { 87 | for (int j = 0; j < twoArray[0].length; j++) { 88 | // 二维数组赋值 89 | twoArray[i][j] = j; 90 | } 91 | } 92 | // 二维数组取值 93 | System.out.println(twoArray[0][1]); 94 | // 打印二维数组 95 | System.out.println(Arrays.toString(twoArray[0])); 96 | System.out.println(Arrays.toString(twoArray[1])); 97 | // 数组拷贝 98 | int[] copyArray = {3, 4, 9}; 99 | int[] copyArray2 = Arrays.copyOf(copyArray, 5); 100 | System.out.println(Arrays.toString(copyArray2)); 101 | // 数组合并 102 | int[] addArray = {2, 8, 13, 11, 6, 7}; 103 | int[] addArray2 = {66, 88}; 104 | // 合并数组 105 | int[] addArray3 = org.apache.commons.lang3.ArrayUtils.addAll(addArray, addArray2); 106 | System.out.println(Arrays.toString(addArray3)); 107 | // 数组正序和逆序 108 | int[] reverseArray = {2, 8, 13, 11, 6, 7}; 109 | // 数组正序(排序) 110 | Arrays.sort(reverseArray); 111 | // 数组逆序 112 | org.apache.commons.lang3.ArrayUtils.reverse(reverseArray); 113 | System.out.println(Arrays.toString(reverseArray)); 114 | // 字符串数组某个值查询 115 | String[] findArray = {"doc", "pig", "cat"}; 116 | // 方式一:Arrays.asList(array).contains 117 | boolean bool = Arrays.asList(findArray).contains("cat"); 118 | System.out.println(bool); 119 | // 方式二:Arrays.binarySearch 120 | Arrays.sort(findArray); 121 | boolean bool2 = Arrays.binarySearch(findArray, "cat") > -1; 122 | System.out.println(bool2); 123 | // 冒泡排序 124 | int[] sortArray = {2, 8, 13, 11, 6, 7}; 125 | System.out.println("排序前:" + Arrays.toString(sortArray)); 126 | for (int i = 0; i < sortArray.length; i++) { 127 | for (int j = 0; j < sortArray.length; j++) { 128 | if (sortArray[i] > sortArray[j]) { 129 | // 元素交换 130 | int temp = sortArray[i]; 131 | sortArray[i] = sortArray[j]; 132 | sortArray[j] = temp; 133 | } 134 | } 135 | } 136 | System.out.println("排序后:" + Arrays.toString(sortArray)); 137 | // 选择排序 138 | int[] selArray = {2, 8, 13, 11, 6, 7}; 139 | System.out.println("排序前:" + Arrays.toString(selArray)); 140 | for (int i = 0; i < selArray.length; i++) { 141 | int lowerIndex = i; 142 | for (int j = i + 1; j < selArray.length; j++) { 143 | // 找出最小的一个索引 144 | if (selArray[j] < selArray[lowerIndex]) { 145 | lowerIndex = j; 146 | } 147 | } 148 | // 交换 149 | int temp = selArray[i]; 150 | selArray[i] = selArray[lowerIndex]; 151 | selArray[lowerIndex] = temp; 152 | } 153 | System.out.println("排序后:" + Arrays.toString(selArray)); 154 | // 数组转集合 155 | String[] listArray = {"cat", "dog"}; 156 | List list = Arrays.asList(listArray); 157 | System.out.println(list); 158 | // 集合转数组 159 | List strList = new ArrayList(); 160 | strList.add("cat"); 161 | strList.add("dog"); 162 | // 集合转换为数组 163 | String[] strArrays = strList.toArray(new String[strList.size()]); 164 | System.out.println(Arrays.toString(strArrays)); 165 | // 数组元素赋值 166 | int[] arrInt = new int[10]; 167 | Arrays.fill(arrInt, 2, 5, 6); 168 | System.out.println(Arrays.toString(arrInt)); 169 | for (int i = 0; i < arrInt.length; i++) { 170 | if (i >= 2 && i < 5) { 171 | arrInt[i] = 6; 172 | } 173 | } 174 | System.out.println(Arrays.toString(arrInt)); 175 | } 176 | 177 | private static void change(int[] arr) { 178 | for (int i = 0; i < arr.length; i++) { 179 | if (i % 2 == 0) { 180 | arr[i] *= i; 181 | } 182 | } 183 | } 184 | 185 | 186 | } 187 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson2_1.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | public class Lesson2_1 { 4 | public static void main(String[] args) throws CloneNotSupportedException { 5 | /********** 克隆 **********/ 6 | CloneInstance ct = new CloneInstance(); 7 | ct.num = 666; 8 | System.out.println(ct.num); 9 | CloneInstance ct2 = (CloneInstance) ct.clone(); 10 | System.out.println(ct2.num); 11 | /********** 继承 **********/ 12 | Animal cat = new Cat(); 13 | cat.eat(); 14 | } 15 | } 16 | 17 | /** 18 | * @Description 克隆实现 19 | **/ 20 | class CloneInstance implements Cloneable { 21 | int num; 22 | 23 | public static void main(String[] args) throws CloneNotSupportedException { 24 | CloneInstance ct = new CloneInstance(); 25 | ct.num = 666; 26 | System.out.println(ct.num); 27 | CloneInstance ct2 = (CloneInstance) ct.clone(); 28 | System.out.println(ct2.num); 29 | } 30 | 31 | @Override 32 | protected Object clone() throws CloneNotSupportedException { 33 | return super.clone(); 34 | } 35 | } 36 | 37 | class Animal { 38 | public void eat() { 39 | System.out.println("Animal"); 40 | } 41 | } 42 | 43 | class Cat extends Animal { 44 | 45 | } 46 | 47 | /********** 继承执行顺序面试题 **********/ 48 | class ExecTest { 49 | public static void main(String[] args) { 50 | Son son = new Son(); 51 | } 52 | } 53 | 54 | class Parent { 55 | { 56 | System.out.print("1"); 57 | } 58 | 59 | static { 60 | System.out.print("2"); 61 | } 62 | 63 | public Parent() { 64 | System.out.print("3"); 65 | } 66 | } 67 | 68 | class Son extends Parent { 69 | { 70 | System.out.print("4"); 71 | } 72 | 73 | static { 74 | System.out.print("5"); 75 | } 76 | 77 | public Son() { 78 | System.out.print("6"); 79 | } 80 | } 81 | 82 | /********* 继承面试题 **********/ 83 | class A { 84 | // public int x = 0; 85 | // public static int y = 0; 86 | public void m(A a) { 87 | System.out.println("AA"); 88 | } 89 | 90 | public void m(D d) { 91 | System.out.println("AD"); 92 | } 93 | 94 | // public void m(B b) { 95 | // System.out.println("AB"); 96 | // } 97 | } 98 | 99 | class B extends A { 100 | // public int x = 1; 101 | // public static int y = 2; 102 | @Override 103 | public void m(A a) { 104 | System.out.println("BA"); 105 | } 106 | 107 | public void m(B b) { 108 | System.out.println("BB"); 109 | } 110 | 111 | public static void main(String[] args) { 112 | A a = new B(); 113 | B b = new B(); 114 | C c = new C(); 115 | D d = new D(); 116 | a.m(a); 117 | a.m(b); 118 | a.m(c); 119 | a.m(d); 120 | // System.out.print(a.x); 121 | // System.out.print(a.y); 122 | } 123 | } 124 | 125 | class C extends B { 126 | } 127 | 128 | class D extends B { 129 | } 130 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson2_2.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | /*********** 1、成员内部类(可以使用任意修饰符) **********/ 4 | class InnerTest { 5 | public static void main(String[] args) { 6 | Outer.Inner inner = new Outer().new Inner(); 7 | inner.sayHi(); 8 | } 9 | } 10 | 11 | class Outer { 12 | private String name = "OuterClass"; 13 | int age = 18; 14 | 15 | public void sayHi() { 16 | System.out.println(new Inner().name); 17 | System.out.println("Hi, Outer."); 18 | } 19 | 20 | class Inner { 21 | String name = "InnerClass"; 22 | 23 | public void sayHi() { 24 | // 内部类访问外部类 25 | Outer.this.sayHi(); 26 | System.out.println(Outer.this.name); 27 | System.out.println("Hi, Inner."); 28 | } 29 | } 30 | } 31 | 32 | /*********** 2、静态内部类(可以使用任意修饰符) **********/ 33 | class OuterClass { 34 | String name = "OuterClass"; 35 | 36 | public OuterClass() { 37 | System.out.println("OuterClass Init."); 38 | } 39 | 40 | protected static class InnerClass { 41 | String name = "InnerClass"; 42 | 43 | public void sayHi() { 44 | System.out.println("Hi, InnerClass."); 45 | } 46 | } 47 | } 48 | 49 | class InnerClassTest { 50 | public static void main(String[] args) { 51 | OuterClass.InnerClass innerClass = new OuterClass.InnerClass(); 52 | innerClass.sayHi(); 53 | } 54 | } 55 | 56 | /*********** 3、局部内部类 **********/ 57 | class OutClass3 { 58 | int age = 18; 59 | 60 | public void sayHi() { 61 | class InnerClass3 { 62 | InnerClass3(String name) { 63 | System.out.println(age); 64 | System.out.println("InnerClass:" + name); 65 | } 66 | } 67 | System.out.println(new InnerClass3("Three")); 68 | System.out.println("Hi, OutClass"); 69 | } 70 | } 71 | 72 | class OutTest3 { 73 | public static void main(String[] args) { 74 | new OutClass3().sayHi(); 75 | } 76 | } 77 | 78 | /*********** 4、匿名内部类 **********/ 79 | interface AnonymityOuter { 80 | void hi(); 81 | } 82 | 83 | class AnonymityTest { 84 | public static void main(String[] args) { 85 | AnonymityOuter anonymityOuter = new AnonymityOuter() { 86 | @Override 87 | public void hi() { 88 | System.out.println("Hi, AnonymityOuter."); 89 | } 90 | }; 91 | anonymityOuter.hi(); 92 | } 93 | } 94 | 95 | /*********** 枚举使用 **********/ 96 | class EnumTest { 97 | public static void main(String[] args) { 98 | ColorEnum color = ColorEnum.GREEN; 99 | switch (color) { 100 | case RED: 101 | System.out.println("Red"); 102 | break; 103 | case BLUE: 104 | System.out.println("Blue"); 105 | break; 106 | case YELLOW: 107 | System.out.println("Yellow"); 108 | break; 109 | case GREEN: 110 | System.out.println("Green"); 111 | break; 112 | default: 113 | break; 114 | } 115 | /*********** 枚举比较 **********/ 116 | ColorEnum redColor = ColorEnum.RED; 117 | ColorEnum redColor2 = ColorEnum.RED; 118 | System.out.println(redColor == redColor2); 119 | System.out.println(redColor.equals(redColor2)); 120 | /*********** 枚举扩展方法 **********/ 121 | System.out.println(ColorsEnum.RED.getName()); 122 | System.out.println(ColorsEnum.RED.getIndex()); 123 | } 124 | } 125 | 126 | /*********** 无参数枚举类 **********/ 127 | enum ColorEnum { 128 | RED, 129 | BLUE, 130 | YELLOW, 131 | GREEN 132 | } 133 | 134 | /*********** 自定义参数的枚举类 **********/ 135 | enum ColorsEnum { 136 | RED("红色", 1), 137 | BLUE("蓝色", 2), 138 | YELLOW("黄色", 3), 139 | GREEN("绿色", 4); 140 | 141 | ColorsEnum(String name, int index) { 142 | this.name = name; 143 | this.index = index; 144 | } 145 | 146 | private String name; 147 | private int index; 148 | 149 | public String getName() { 150 | return name; 151 | } 152 | 153 | public void setName(String name) { 154 | this.name = name; 155 | } 156 | 157 | public int getIndex() { 158 | return index; 159 | } 160 | 161 | public void setIndex(int index) { 162 | this.index = index; 163 | } 164 | } 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson2_3.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | abstract class AbstractAnimal { 4 | public AbstractAnimal() { 5 | System.out.println("Init AbstractAnimal."); 6 | } 7 | 8 | protected static String animalName = "AbstractAnimal"; 9 | 10 | abstract void eat(); 11 | 12 | public void run() { 13 | System.out.println("AbstractAnimal Run."); 14 | } 15 | } 16 | 17 | class AbstractAnimalInstance extends AbstractAnimal { 18 | public static void main(String[] args) { 19 | AbstractAnimal animal = new AbstractAnimalInstance(); 20 | animal.run(); 21 | System.out.println(animalName); 22 | animal.eat(); 23 | } 24 | 25 | @Override 26 | void eat() { 27 | System.out.println("AbstractAnimalInstance Eat."); 28 | } 29 | } 30 | 31 | //@FunctionalInterface 32 | interface IAnimal { 33 | static String animalName = "Animal Name"; 34 | 35 | static void printSex() { 36 | System.out.println("Male Dog"); 37 | } 38 | 39 | default void printAge() { 40 | System.out.println("18"); 41 | } 42 | 43 | void run(String name); 44 | } 45 | 46 | //class FunctionInterfaceTest { 47 | // public static void main(String[] args) { 48 | // IAnimal animal = name -> System.out.println(name); 49 | // animal.run("WangWang"); 50 | // } 51 | //} 52 | 53 | class AnimalImpl implements IAnimal { 54 | static String animalName = new String("Animal Name"); 55 | 56 | public static void main(String[] args) { 57 | System.out.println(IAnimal.animalName == animalName); 58 | } 59 | 60 | @Override 61 | public void run(String name) { 62 | System.out.println("AnimalImpl:" + name); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson2_4.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.caucho.hessian.io.HessianInput; 5 | import com.caucho.hessian.io.HessianOutput; 6 | 7 | import java.io.*; 8 | import java.util.Arrays; 9 | 10 | class CloneTest { 11 | public static void main(String[] args) throws CloneNotSupportedException { 12 | // 等号赋值( 基本类型) 13 | int number = 6; 14 | int number2 = number; 15 | // 修改 number2 的值 16 | number2 = 9; 17 | System.out.println("number:" + number); 18 | System.out.println("number2:" + number2); 19 | Dog dog = new Dog(); 20 | dog.name = "旺财"; 21 | dog.age = 5; 22 | Dog dog2 = dog; 23 | // 修改 dog2 的值 24 | dog2.name = "大黄"; 25 | dog2.age = 3; 26 | System.out.println(dog.name + "," + dog.age + "岁"); 27 | System.out.println(dog2.name + "," + dog2.age + "岁"); 28 | // -------------------------- 克隆 ---------------------------- 29 | Dog dog3 = (Dog) dog.clone(); 30 | dog3.name = "小白"; 31 | dog3.age = 2; 32 | System.out.println(dog.name + "," + dog.age + "岁"); 33 | System.out.println(dog3.name + "," + dog3.age + "岁"); 34 | // -------------------------- 浅克隆 ---------------------------- 35 | DogChild dogChild = new DogChild(); 36 | dogChild.name = "二狗"; 37 | Dog dog4 = new Dog(); 38 | dog4.name = "大黄"; 39 | dog4.dogChild = dogChild; 40 | Dog dog5 = (Dog) dog4.clone(); 41 | dog5.name = "旺财"; 42 | dog5.dogChild.name = "狗二"; 43 | System.out.println("dog name 4:" + dog4.name); 44 | System.out.println("dog name 5:" + dog5.name); 45 | System.out.println("dog child name 4:" + dog4.dogChild.name); 46 | System.out.println("dog child name 5:" + dog5.dogChild.name); 47 | // -------------------------- 深克隆(序列化) ---------------------------- 48 | BirdChild birdChild = new BirdChild(); 49 | birdChild.name = "小小鸟"; 50 | Bird bird = new Bird(); 51 | bird.name = "小鸟"; 52 | bird.birdChild = birdChild; 53 | Bird bird2 = CloneUtils.clone(bird); 54 | bird2.name = "黄雀"; 55 | bird2.birdChild.name = "小黄雀"; 56 | System.out.println("bird name:" + bird.name); 57 | System.out.println("bird child name:" + bird.birdChild.name); 58 | System.out.println("bird name 2:" + bird2.name); 59 | System.out.println("bird child name 2:" + bird2.birdChild.name); 60 | // --------------------------深克隆(引用类型实现克隆)---------------------------- 61 | ParrotChild parrotChild = new ParrotChild(); 62 | parrotChild.name = "小鹦鹉"; 63 | Parrot parrot = new Parrot(); 64 | parrot.name = "大鹦鹉"; 65 | parrot.parrotChild = parrotChild; 66 | // 克隆 67 | Parrot parrot2 = (Parrot) parrot.clone(); 68 | parrot2.name = "老鹦鹉"; 69 | parrot2.parrotChild.name = "少鹦鹉"; 70 | System.out.println("parrot name:" + parrot.name); 71 | System.out.println("parrot child name:" + parrot.parrotChild.name); 72 | System.out.println("parrot name 2:" + parrot2.name); 73 | System.out.println("parrot child name 2:" + parrot2.parrotChild.name); 74 | 75 | // -------------------------- 面试题 ---------------------------- 76 | CloneObj cloneObj = new CloneObj(); 77 | cloneObj.name = "老王"; 78 | cloneObj.age = 30; 79 | cloneObj.sistersAge = new int[]{18, 19}; 80 | CloneObj cloneObj2 = (CloneObj) cloneObj.clone(); 81 | cloneObj2.name = "磊哥"; 82 | cloneObj2.age = 33; 83 | cloneObj2.sistersAge[0] = 20; 84 | System.out.println(cloneObj.name + "|" + cloneObj2.name); 85 | System.out.println(cloneObj.age + "|" + cloneObj2.age); 86 | System.out.println(Arrays.toString(cloneObj.sistersAge) + "|" + Arrays.toString(cloneObj2.sistersAge)); 87 | } 88 | } 89 | 90 | // 序列化和反序列化 91 | class SerializableTest { 92 | public static void main(String[] args) throws IOException, ClassNotFoundException { 93 | // 对象赋值 94 | User user = new User(); 95 | user.setName("老王"); 96 | user.setAge(30); 97 | System.out.println(user); 98 | 99 | // -------------------------- Java 原生序列化 ---------------------------- 100 | // 创建输出流(序列化内容到磁盘) 101 | ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.out")); 102 | // 序列化对象 103 | oos.writeObject(user); 104 | oos.flush(); 105 | oos.close(); 106 | 107 | // 创建输入流(从磁盘反序列化) 108 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.out")); 109 | // 反序列化 110 | User user2 = (User) ois.readObject(); 111 | ois.close(); 112 | System.out.println(user2); 113 | 114 | // -------------------------- JSON 序列化(fastjson) ---------------------------- 115 | String jsonSerialize = JSON.toJSONString(user); 116 | User user3 = (User) JSON.parseObject(jsonSerialize, User.class); 117 | System.out.println(user3); 118 | 119 | // -------------------------- Hessian 序列化 ---------------------------- 120 | // 序列化 121 | ByteArrayOutputStream bo = new ByteArrayOutputStream(); 122 | HessianOutput hessianOutput = new HessianOutput(bo); 123 | hessianOutput.writeObject(user); 124 | byte[] hessianBytes = bo.toByteArray(); 125 | // 反序列化 126 | ByteArrayInputStream bi = new ByteArrayInputStream(hessianBytes); 127 | HessianInput hessianInput = new HessianInput(bi); 128 | User user4 = (User) hessianInput.readObject(); 129 | System.out.println(user4); 130 | } 131 | } 132 | 133 | class Dog implements Cloneable { 134 | public String name; 135 | public int age; 136 | public DogChild dogChild; 137 | 138 | @Override 139 | protected Object clone() throws CloneNotSupportedException { 140 | return super.clone(); 141 | } 142 | } 143 | 144 | class DogChild { 145 | public String name; 146 | } 147 | 148 | class Bird implements Serializable { 149 | private static final long serialVersionUID = -8548202819636883145L; 150 | public String name; 151 | public BirdChild birdChild; 152 | } 153 | 154 | class BirdChild implements Serializable { 155 | private static final long serialVersionUID = -2767034691908202986L; 156 | public String name; 157 | } 158 | 159 | class Parrot implements Cloneable { 160 | public String name; 161 | public ParrotChild parrotChild; 162 | 163 | @Override 164 | protected Object clone() throws CloneNotSupportedException { 165 | Parrot bird = (Parrot) super.clone(); 166 | bird.parrotChild = (ParrotChild) parrotChild.clone(); 167 | return bird; 168 | } 169 | } 170 | 171 | class ParrotChild implements Cloneable { 172 | public String name; 173 | 174 | @Override 175 | protected Object clone() throws CloneNotSupportedException { 176 | return super.clone(); 177 | } 178 | } 179 | 180 | /** 181 | * 克隆工具类(通过序列化方式实现深拷贝) 182 | * 先将要拷贝对象写入到内存中的字节流中,然后再从这个字节流中读出刚刚存储的信息,作为一个新对象返回,那么这个新对象和原对象就不存在任何地址上的共享,自然实现了深拷贝。 183 | **/ 184 | class CloneUtils { 185 | public static T clone(T obj) { 186 | T cloneObj = null; 187 | try { 188 | //写入字节流 189 | ByteArrayOutputStream bo = new ByteArrayOutputStream(); 190 | ObjectOutputStream oos = new ObjectOutputStream(bo); 191 | oos.writeObject(obj); 192 | oos.close(); 193 | 194 | //分配内存,写入原始对象,生成新对象 195 | ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());//获取上面的输出字节流 196 | ObjectInputStream oi = new ObjectInputStream(bi); 197 | 198 | //返回生成的新对象 199 | cloneObj = (T) oi.readObject(); 200 | oi.close(); 201 | } catch (Exception e) { 202 | e.printStackTrace(); 203 | } 204 | return cloneObj; 205 | } 206 | } 207 | 208 | class CloneObj implements Cloneable { 209 | public String name; 210 | public int age; 211 | public int[] sistersAge; 212 | 213 | @Override 214 | protected Object clone() throws CloneNotSupportedException { 215 | return super.clone(); 216 | } 217 | } 218 | 219 | class User implements Serializable { 220 | private static final long serialVersionUID = 5132320539584511249L; 221 | private String name; 222 | private int age; 223 | 224 | @Override 225 | public String toString() { 226 | return "{name:" + name + ",age:" + age + "}"; 227 | } 228 | 229 | public String getName() { 230 | return name; 231 | } 232 | 233 | public void setName(String name) { 234 | this.name = name; 235 | } 236 | 237 | public int getAge() { 238 | return age; 239 | } 240 | 241 | public void setAge(int age) { 242 | this.age = age; 243 | } 244 | } -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson3_1.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.util.*; 4 | 5 | public class Lesson3_1 { 6 | public static void main(String[] args) { 7 | // -------------------------- Vector 使用代码 ---------------------------- 8 | Vector vector = new Vector(); 9 | vector.add("dog"); 10 | vector.add("cat"); 11 | vector.remove("cat"); 12 | System.out.println(vector); 13 | 14 | // -------------------------- ArrayList 使用代码 ---------------------------- 15 | ArrayList arrayList = new ArrayList(); 16 | arrayList.add("dog"); 17 | arrayList.add("cat"); 18 | arrayList.remove("cat"); 19 | System.out.println(arrayList); 20 | 21 | // -------------------------- LinkedList 使用代码 ---------------------------- 22 | LinkedList linkedList = new LinkedList(); 23 | // 添加元素 24 | linkedList.offer("bird"); 25 | linkedList.push("cat"); 26 | linkedList.push("dog"); 27 | // 获取第一个元素 28 | System.out.println(linkedList.peek()); 29 | // 获取第一个元素,并删除此元素 30 | System.out.println(linkedList.poll()); 31 | System.out.println(linkedList); 32 | 33 | // -------------------------- HashSet 使用代码 ---------------------------- 34 | HashSet hashSet = new HashSet(); 35 | hashSet.add("dog"); 36 | hashSet.add("camel"); 37 | hashSet.add("cat"); 38 | System.out.println(hashSet); 39 | 40 | // -------------------------- TreeSet 使用代码 ---------------------------- 41 | TreeSet treeSet = new TreeSet(); 42 | treeSet.add("dog"); 43 | treeSet.add("camel"); 44 | treeSet.add("cat"); 45 | treeSet.add("ant"); 46 | System.out.println(treeSet); 47 | 48 | // -------------------------- LinkedHashSet 使用代码 ---------------------------- 49 | LinkedHashSet linkedHashSet = new LinkedHashSet(); 50 | linkedHashSet.add("dog"); 51 | linkedHashSet.add("camel"); 52 | linkedHashSet.add("cat"); 53 | linkedHashSet.add("ant"); 54 | System.out.println(linkedHashSet); 55 | 56 | // -------------------------- 集合与数组的互相转换 ---------------------------- 57 | List list = new ArrayList(); 58 | list.add("cat"); 59 | list.add("dog"); 60 | // 集合转数组 61 | String[] arr = list.toArray(new String[list.size()]); 62 | // 数组转集合 63 | List list2 = Arrays.asList(arr); 64 | System.out.println(list2); 65 | 66 | // -------------------------- Stack 后进先出演示代码 ---------------------------- 67 | Stack stack = new Stack(); 68 | stack.push("a"); 69 | stack.push("b"); 70 | stack.push("c"); 71 | for (int i = 0; i < 3; i++) { 72 | // 移除并返回栈顶元素 73 | System.out.println(stack.pop()); 74 | } 75 | 76 | // -------------------------- 集合排序(Comparable/Comparator) ---------------------------- 77 | DogComp[] dogs = new DogComp[]{ 78 | new DogComp("老旺财", 10), 79 | new DogComp("小旺财", 3), 80 | new DogComp("二旺财", 5), 81 | }; 82 | // // Comparable 排序 83 | // Arrays.sort(dogs); 84 | // Comparator 排序 85 | Arrays.sort(dogs, new DogComparator()); 86 | for (DogComp d : dogs) { 87 | System.out.println(d.getName() + ":" + d.getAge()); 88 | } 89 | } 90 | 91 | static class DogComparator implements Comparator { 92 | @Override 93 | public int compare(DogComp o1, DogComp o2) { 94 | return o1.getAge() - o2.getAge(); 95 | } 96 | } 97 | 98 | static class DogComp implements Comparable { 99 | private String name; 100 | private int age; 101 | 102 | @Override 103 | public int compareTo(DogComp o) { 104 | return age - o.age; 105 | } 106 | 107 | public DogComp(String name, int age) { 108 | this.name = name; 109 | this.age = age; 110 | } 111 | 112 | public String getName() { 113 | return name; 114 | } 115 | 116 | public int getAge() { 117 | return age; 118 | } 119 | } 120 | 121 | } 122 | 123 | 124 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson3_2.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.util.*; 4 | 5 | public class Lesson3_2 { 6 | public static void main(String[] args) { 7 | 8 | Map hashMap = new HashMap(); 9 | // 增加元素 10 | hashMap.put("name", "老王"); 11 | hashMap.put(null, null); 12 | hashMap.put("age", "30"); 13 | hashMap.put("sex", "你猜"); 14 | // 删除元素 15 | hashMap.remove(null); 16 | // 查找单个元素 17 | System.out.println(hashMap.get("age")); 18 | // 循环所有的 key 19 | for (Object k : hashMap.keySet()) { 20 | System.out.println(k); 21 | } 22 | // 循环所有的值 23 | for (Object v : hashMap.values()) { 24 | System.out.println(v); 25 | } 26 | 27 | // -------------------------- TreeMap 自定义排序 ---------------------------- 28 | TreeMap treeMap = new TreeMap(new Comparator() { 29 | @Override 30 | public int compare(String s1, String s2) { 31 | return s2.compareTo(s1); // 倒序 32 | } 33 | }); 34 | treeMap.put("dog", "dog"); 35 | treeMap.put("camel", "camel"); 36 | treeMap.put("cat", "cat"); 37 | treeMap.put("ant", "ant"); 38 | // -------------------------- TreeMap 根据 value 倒序 ---------------------------- 39 | // map.entrySet() 转成 List 40 | List> list = new ArrayList<>(treeMap.entrySet()); 41 | // 通过比较器实现比较排序 42 | Collections.sort(list, new Comparator>() { 43 | public int compare(Map.Entry m1, Map.Entry m2) { 44 | return m2.getValue().compareTo(m1.getValue()); 45 | } 46 | }); 47 | for (Map.Entry item : list) { 48 | System.out.println(item.getKey() + ":" + item.getValue()); 49 | } 50 | 51 | // -------------------------- LinkedHashMap 使用 ---------------------------- 52 | LinkedHashMap linkedHashMap = new LinkedHashMap(); 53 | linkedHashMap.put("dog", "dog"); 54 | linkedHashMap.put("camel", "camel"); 55 | linkedHashMap.put("cat", "cat"); 56 | linkedHashMap.put("ant", "ant"); 57 | System.out.println(linkedHashMap); 58 | 59 | // -------------------------- hashCode 和 equals 测试 ---------------------------- 60 | HashMap map = new HashMap<>(); 61 | Person person = new Person(18); 62 | map.put(person, 1); 63 | System.out.println(map.get(new Person(18))); 64 | } 65 | } 66 | 67 | class Person { 68 | private Integer age; 69 | 70 | public boolean equals(Object o) { 71 | if (o == null || !(o instanceof Person)) { 72 | return false; 73 | } else { 74 | return this.getAge().equals(((Person) o).getAge()); 75 | } 76 | } 77 | 78 | // public int hashCode() { 79 | // return age.hashCode(); 80 | // } 81 | public Person(int age) { 82 | this.age = age; 83 | } 84 | 85 | public void setAge(int age) { 86 | this.age = age; 87 | } 88 | 89 | public Integer getAge() { 90 | return age; 91 | } 92 | 93 | public static void main(String[] args) { 94 | // HashMap hashMap = new HashMap<>(); 95 | Person p1 = new Person(18); 96 | Person p2 = new Person(18); 97 | System.out.println(p1.equals(p2)); 98 | System.out.println(p1.hashCode() + " : " + p2.hashCode()); 99 | // hashMap.put(person, 1); 100 | // System.out.println(hashMap.get(new Person(18))); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson3_3.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.util.*; 4 | 5 | public class Lesson3_3 { 6 | public static void main(String[] args) { 7 | // --------------------- Iterator 使用 --------------------- 8 | List list = new ArrayList<>(); 9 | list.add("Java"); 10 | list.add("Java虚拟机"); 11 | list.add("Java中文社群"); 12 | Iterator iter = list.iterator(); 13 | // 遍历 14 | while (iter.hasNext()) { 15 | String str = (String) iter.next(); 16 | if (str.equals("Java中文社群")) { 17 | iter.remove(); 18 | } 19 | } 20 | System.out.println(list); 21 | 22 | // --------------------- HashMap 的几种循环方式 --------------------- 23 | Map hashMap = new HashMap(); 24 | hashMap.put("name", "老王"); 25 | hashMap.put("sex", "你猜"); 26 | // 方式一:entrySet 遍历 27 | for (Map.Entry item : hashMap.entrySet()) { 28 | System.out.println(item.getKey() + ":" + item.getValue()); 29 | } 30 | // 方式二:iterator 遍历 31 | Iterator> iterator = hashMap.entrySet().iterator(); 32 | while (iterator.hasNext()) { 33 | Map.Entry entry = iterator.next(); 34 | System.out.println(entry.getKey() + ":" + entry.getValue()); 35 | } 36 | // 方式三:遍历所有的 key 和 value 37 | for (Object k : hashMap.keySet()) { 38 | // 循环所有的 key 39 | System.out.println(k); 40 | } 41 | for (Object v : hashMap.values()) { 42 | // 循环所有的值 43 | System.out.println(v); 44 | } 45 | // 方式四:通过 key 值遍历 46 | for (Object k : hashMap.keySet()) { 47 | System.out.println(k + ":" + hashMap.get(k)); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson3_4.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.text.DateFormat; 4 | import java.text.SimpleDateFormat; 5 | import java.util.*; 6 | import java.util.concurrent.*; 7 | 8 | public class Lesson3_4 { 9 | 10 | public static void main(String[] args) throws InterruptedException { 11 | // LinkedList 使用 12 | Queue linkedList = new LinkedList<>(); 13 | linkedList.add("Dog"); 14 | linkedList.add("Camel"); 15 | linkedList.add("Cat"); 16 | while (!linkedList.isEmpty()) { 17 | System.out.println(linkedList.poll()); 18 | } 19 | // PriorityQueue 使用 20 | Queue priorityQueue = new PriorityQueue(new Comparator() { 21 | @Override 22 | public int compare(Integer o1, Integer o2) { 23 | // 非自然排序,数字倒序 24 | return o2 - o1; 25 | } 26 | }); 27 | priorityQueue.add(3); 28 | priorityQueue.add(1); 29 | priorityQueue.add(2); 30 | while (!priorityQueue.isEmpty()) { 31 | Integer i = priorityQueue.poll(); 32 | System.out.println(i); 33 | } 34 | // DelayQueue 延迟队列使用 35 | DelayQueue delayQueue = new DelayQueue(); 36 | delayQueue.put(new DelayElement(1000)); 37 | delayQueue.put(new DelayElement(3000)); 38 | delayQueue.put(new DelayElement(5000)); 39 | System.out.println("开始时间:" + DateFormat.getDateTimeInstance().format(new Date())); 40 | while (!delayQueue.isEmpty()){ 41 | System.out.println(delayQueue.take()); 42 | } 43 | System.out.println("结束时间:" + DateFormat.getDateTimeInstance().format(new Date())); 44 | // ConcurrentLinkedQueue 使用 45 | ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue(); 46 | concurrentLinkedQueue.add("Dog"); 47 | concurrentLinkedQueue.add("Cat"); 48 | while (!concurrentLinkedQueue.isEmpty()) { 49 | System.out.println(concurrentLinkedQueue.poll()); 50 | } 51 | } 52 | 53 | static class DelayElement implements Delayed { 54 | // 延迟截止时间(单面:毫秒) 55 | long delayTime = System.currentTimeMillis(); 56 | 57 | public DelayElement(long delayTime) { 58 | this.delayTime = (this.delayTime + delayTime); 59 | } 60 | 61 | @Override 62 | // 获取剩余时间 63 | public long getDelay(TimeUnit unit) { 64 | return unit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); 65 | } 66 | 67 | @Override 68 | // 队列里元素的排序依据 69 | public int compareTo(Delayed o) { 70 | if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) { 71 | return 1; 72 | } else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) { 73 | return -1; 74 | } else { 75 | return 0; 76 | } 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return DateFormat.getDateTimeInstance().format(new Date(delayTime)); 82 | } 83 | } 84 | 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson4_1.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import javafx.scene.input.DataFormat; 4 | 5 | import java.io.*; 6 | import java.net.InetAddress; 7 | import java.net.InetSocketAddress; 8 | import java.net.Socket; 9 | import java.nio.ByteBuffer; 10 | import java.nio.channels.*; 11 | import java.nio.charset.Charset; 12 | import java.nio.file.*; 13 | import java.text.DateFormat; 14 | import java.util.Date; 15 | import java.util.Iterator; 16 | import java.util.Set; 17 | import java.util.concurrent.*; 18 | 19 | public class Lesson4_1 { 20 | public static void main(String[] args) throws IOException, InterruptedException, ExecutionException { 21 | // Writer使用 22 | Writer writer = new FileWriter("d:\\io.txt",false); 23 | writer.append("老王"); 24 | writer.close(); 25 | 26 | // Reader 使用 27 | Reader reader = new FileReader("d:\\io.txt"); 28 | BufferedReader bufferedReader = new BufferedReader(reader); 29 | String str = null; 30 | while (null != (str = bufferedReader.readLine())) { 31 | System.out.println(str); 32 | } 33 | bufferedReader.close(); 34 | reader.close(); 35 | 36 | // InputStream 使用 37 | InputStream inputStream = new FileInputStream(new File("d:\\io.txt")); 38 | byte[] bytes = new byte[inputStream.available()]; 39 | inputStream.read(bytes); 40 | String content = new String(bytes, "UTF-8"); 41 | inputStream.close(); 42 | System.out.println(content); 43 | 44 | // InputStream 使用 45 | OutputStream outputStream = new FileOutputStream(new File("d:\\io.txt"),true); 46 | outputStream.write("写入信息".getBytes()); 47 | outputStream.close(); 48 | 49 | // 读取文件 50 | byte[] rBytes = Files.readAllBytes(Paths.get("d:\\io.txt")); 51 | // 转换为字符串 52 | String rContent = new String(rBytes, "UTF-8"); 53 | // 写入文件 54 | Files.write(Paths.get("d:\\io.txt"), "追加内容".getBytes(), StandardOpenOption.APPEND); 55 | 56 | // NIO 多路复用 57 | int port = 6666; 58 | new Thread(new Runnable() { 59 | @Override 60 | public void run() { 61 | try (Selector selector = Selector.open(); 62 | ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();) { 63 | serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLocalHost(), port)); 64 | serverSocketChannel.configureBlocking(false); 65 | serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 66 | while (true) { 67 | selector.select(); // 阻塞等待就绪的 Channel 68 | Set selectionKeys = selector.selectedKeys(); 69 | Iterator iterator = selectionKeys.iterator(); 70 | while (iterator.hasNext()) { 71 | SelectionKey key = iterator.next(); 72 | try (SocketChannel channel = ((ServerSocketChannel) key.channel()).accept()) { 73 | channel.write(Charset.defaultCharset().encode("老王,你好~")); 74 | } 75 | iterator.remove(); 76 | } 77 | } 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | }).start(); 83 | 84 | 85 | new Thread(new Runnable() { 86 | @Override 87 | public void run() { 88 | // Socket 客户端(接收信息并打印) 89 | try (Socket cSocket = new Socket(InetAddress.getLocalHost(), port)) { 90 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream())); 91 | bufferedReader.lines().forEach(s -> System.out.println("客户端 1 打印:" + s)); 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | }).start(); 97 | 98 | new Thread(new Runnable() { 99 | @Override 100 | public void run() { 101 | // Socket 客户端(接收信息并打印) 102 | try (Socket cSocket = new Socket(InetAddress.getLocalHost(), port)) { 103 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream())); 104 | bufferedReader.lines().forEach(s -> System.out.println("客户端 2 打印:" + s)); 105 | } catch (IOException e) { 106 | e.printStackTrace(); 107 | } 108 | } 109 | }).start(); 110 | 111 | int port2 = 8888; 112 | new Thread(new Runnable() { 113 | @Override 114 | public void run() { 115 | AsynchronousChannelGroup group = null; 116 | try { 117 | group = AsynchronousChannelGroup.withThreadPool(Executors.newFixedThreadPool(4)); 118 | AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(group).bind(new InetSocketAddress(InetAddress.getLocalHost(), port2)); 119 | server.accept(null, new CompletionHandler() { 120 | @Override 121 | public void completed(AsynchronousSocketChannel result, AsynchronousServerSocketChannel attachment) { 122 | server.accept(null, this); // 接收下一个请求 123 | try { 124 | Future f = result.write(Charset.defaultCharset().encode("Hi, 老王")); 125 | f.get(); 126 | System.out.println("服务端发送时间:" + DateFormat.getDateTimeInstance().format(new Date())); 127 | result.close(); 128 | } catch (InterruptedException | ExecutionException | IOException e) { 129 | e.printStackTrace(); 130 | } 131 | } 132 | @Override 133 | public void failed(Throwable exc, AsynchronousServerSocketChannel attachment) { 134 | } 135 | }); 136 | group.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS); 137 | } catch (IOException | InterruptedException e) { 138 | e.printStackTrace(); 139 | } 140 | } 141 | }).start(); 142 | 143 | // Socket 客户端 144 | AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); 145 | Future future = client.connect(new InetSocketAddress(InetAddress.getLocalHost(), port2)); 146 | future.get(); 147 | ByteBuffer buffer = ByteBuffer.allocate(100); 148 | client.read(buffer, null, new CompletionHandler() { 149 | @Override 150 | public void completed(Integer result, Void attachment) { 151 | System.out.println("客户端打印:" + new String(buffer.array())); 152 | } 153 | 154 | @Override 155 | public void failed(Throwable exc, Void attachment) { 156 | exc.printStackTrace(); 157 | try { 158 | client.close(); 159 | } catch (IOException e) { 160 | e.printStackTrace(); 161 | } 162 | } 163 | }); 164 | Thread.sleep(10 * 1000); 165 | 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson4_2.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import net.sf.cglib.proxy.Enhancer; 4 | import net.sf.cglib.proxy.MethodInterceptor; 5 | import net.sf.cglib.proxy.MethodProxy; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | 10 | class ReflectTest { 11 | public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { 12 | Class myClass = Class.forName("com.interview.MyReflect"); 13 | // 调用静态方法 14 | Method method = myClass.getMethod("staticMd"); 15 | method.invoke(myClass); 16 | 17 | // 调用公共方法 18 | Object instance = myClass.newInstance(); 19 | Method method2 = myClass.getMethod("publicMd"); 20 | method2.invoke(instance); 21 | 22 | // 调用私有方法 23 | Object object = myClass.newInstance(); 24 | Method method3 = myClass.getDeclaredMethod("privateMd"); 25 | method3.setAccessible(true); 26 | method3.invoke(object); 27 | 28 | // cglib 动态代理调用 29 | CglibProxy proxy = new CglibProxy(); 30 | Panda panda = (Panda) proxy.getInstance(new Panda()); 31 | panda.eat(); 32 | } 33 | } 34 | 35 | class MyReflect { 36 | // 静态方法 37 | public static void staticMd() { 38 | System.out.println("Static Method"); 39 | } 40 | 41 | // 公共方法 42 | public void publicMd() { 43 | System.out.println("Public Method"); 44 | } 45 | 46 | // 私有方法 47 | private void privateMd() { 48 | System.out.println("Private Method"); 49 | } 50 | } 51 | 52 | 53 | class Panda { 54 | public void eat() { 55 | System.out.println("The panda is eating"); 56 | } 57 | } 58 | 59 | class CglibProxy implements MethodInterceptor { 60 | private Object target; // 代理对象 61 | 62 | public Object getInstance(Object target) { 63 | this.target = target; 64 | Enhancer enhancer = new Enhancer(); 65 | // 设置父类为实例类 66 | enhancer.setSuperclass(this.target.getClass()); 67 | // 回调方法 68 | enhancer.setCallback(this); 69 | // 创建代理对象 70 | return enhancer.create(); 71 | } 72 | 73 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { 74 | System.out.println("调用前"); 75 | Object result = methodProxy.invokeSuper(o, objects); // 执行方法调用 76 | System.out.println("调用后"); 77 | return result; 78 | } 79 | } -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson5_1.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.concurrent.Callable; 5 | 6 | class ThreadTest { 7 | public static void main(String[] args) throws Exception { 8 | // 创建方式一:继承 Thread 类 9 | MyThread thread = new MyThread(); 10 | thread.start(); 11 | // 创建方式二:实现 Runnable 接口 12 | MyRunnable runnable = new MyRunnable(); 13 | runnable.run(); 14 | // 创建方式三:实现 Callable 接口 15 | MyCallable callable = new MyCallable(); 16 | Object result = callable.call(); 17 | System.out.println(result); 18 | // JDK 8 lambda Thread 19 | new Thread(() -> System.out.println("Lambda Of Thread.")).start(); 20 | // 设置线程优先级 21 | Thread priorityThread = new Thread(() -> System.out.println("Java")); 22 | priorityThread.setPriority(10); 23 | priorityThread.start(); 24 | //线程休眠 25 | System.out.println(LocalDateTime.now()); 26 | Object lock = new Object(); 27 | Thread lockThread = new Thread(() -> { 28 | synchronized (lock) { 29 | try { 30 | // 1 秒钟之后自动唤醒 31 | lock.wait(1000); 32 | System.out.println(LocalDateTime.now()); 33 | } catch (InterruptedException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | }); 38 | lockThread.start(); 39 | // 休眠 1 秒 40 | Thread.sleep(1000); 41 | // join 使用 42 | Thread joinThread = new Thread(() -> { 43 | try { 44 | System.out.println("执行前"); 45 | Thread.sleep(1000); 46 | System.out.println("执行后"); 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | } 50 | }); 51 | joinThread.start(); 52 | joinThread.join(); 53 | System.out.println("主程序"); 54 | // yield 使用 55 | new Thread(){ 56 | @Override 57 | public void run() { 58 | for (int i = 1; i < 10; i++) { 59 | if (i == 5) { 60 | // 让同优先级的线程有执行的机会,但不能保证自己会从正在运行的状态迅速转换到可运行的状态 61 | this.yield(); 62 | } 63 | } 64 | } 65 | }.start(); 66 | // interrupt 使用 67 | Thread interruptThread = new Thread() { 68 | @Override 69 | public void run() { 70 | for (int i = 0; i < Integer.MAX_VALUE; i++) { 71 | System.out.println("i:" + i); 72 | if (this.isInterrupted()) { 73 | break; 74 | } 75 | } 76 | } 77 | }; 78 | interruptThread.start(); 79 | Thread.sleep(10); 80 | interruptThread.interrupt(); 81 | // 死锁演示 82 | Object obj1 = new Object(); 83 | Object obj2 = new Object(); 84 | // 线程1拥有对象1,想要等待获取对象2 85 | new Thread() { 86 | @Override 87 | public void run() { 88 | synchronized (obj1) { 89 | try { 90 | Thread.sleep(1000); 91 | } catch (InterruptedException e) { 92 | e.printStackTrace(); 93 | } 94 | synchronized (obj2) { 95 | System.out.println(Thread.currentThread().getName()); 96 | } 97 | } 98 | } 99 | }.start(); 100 | // 线程2拥有对象2,想要等待获取对象1 101 | new Thread() { 102 | @Override 103 | public void run() { 104 | synchronized (obj2) { 105 | try { 106 | Thread.sleep(1000); 107 | } catch (InterruptedException e) { 108 | e.printStackTrace(); 109 | } 110 | synchronized (obj1) { 111 | System.out.println(Thread.currentThread().getName()); 112 | } 113 | } 114 | } 115 | }.start(); 116 | } 117 | } 118 | 119 | class MyThread extends Thread { 120 | @Override 121 | public void run() { 122 | System.out.println("Thread"); 123 | } 124 | } 125 | 126 | class MyRunnable implements Runnable { 127 | @Override 128 | public void run() { 129 | System.out.println("Runnable"); 130 | } 131 | } 132 | 133 | class MyCallable implements Callable { 134 | @Override 135 | public Object call() throws Exception { 136 | System.out.println("Callable"); 137 | return "Success"; 138 | } 139 | } 140 | 141 | 142 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson5_2.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.time.LocalDateTime; 4 | import java.time.format.DateTimeFormatter; 5 | import java.util.concurrent.*; 6 | import java.util.concurrent.atomic.AtomicInteger; 7 | 8 | public class Lesson5_2 { 9 | public static void main(String[] args) throws InterruptedException, ExecutionException { 10 | // 创建线程池 11 | ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 10, 12 | 10L, TimeUnit.SECONDS, new LinkedBlockingQueue(100)); 13 | // execute 使用 14 | threadPoolExecutor.execute(new Runnable() { 15 | @Override 16 | public void run() { 17 | System.out.println("Hello, Java."); 18 | } 19 | }); 20 | // submit 使用 21 | Future future = threadPoolExecutor.submit(new Callable() { 22 | @Override 23 | public String call() throws Exception { 24 | System.out.println("Hello, 老王."); 25 | return "Success"; 26 | } 27 | }); 28 | System.out.println(future.get()); 29 | // shutdown 使用 30 | threadPoolExecutor.execute(() -> { 31 | for (int i = 0; i < 2; i++) { 32 | System.out.println("I'm " + i); 33 | try { 34 | Thread.sleep(1000); 35 | } catch (InterruptedException e) { 36 | System.out.println(e.getMessage()); 37 | } 38 | } 39 | }); 40 | threadPoolExecutor.shutdown(); 41 | threadPoolExecutor.execute(() -> { 42 | System.out.println("I'm Java."); 43 | }); 44 | // newFixedThreadPool 使用 45 | ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2); 46 | for (int i = 0; i < 3; i++) { 47 | fixedThreadPool.execute(() -> { 48 | System.out.println("CurrentTime - " + 49 | LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 50 | try { 51 | Thread.sleep(1000); 52 | } catch (InterruptedException e) { 53 | e.printStackTrace(); 54 | } 55 | }); 56 | } 57 | // newCachedThreadPool 使用 58 | ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); 59 | for (int i = 0; i < 10; i++) { 60 | cachedThreadPool.execute(() -> { 61 | System.out.println("CurrentTime - " + 62 | LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 63 | try { 64 | Thread.sleep(1000); 65 | } catch (InterruptedException e) { 66 | e.printStackTrace(); 67 | } 68 | }); 69 | } 70 | // newSingleThreadExecutor 使用 71 | ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); 72 | for (int i = 0; i < 3; i++) { 73 | singleThreadExecutor.execute(() -> { 74 | System.out.println("CurrentTime - " + 75 | LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); 76 | try { 77 | Thread.sleep(1000); 78 | } catch (InterruptedException e) { 79 | e.printStackTrace(); 80 | } 81 | }); 82 | } 83 | // newScheduledThreadPool 使用 84 | ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1); 85 | scheduledThreadPool.schedule(() -> { 86 | System.out.println("ThreadPool:" + LocalDateTime.now()); 87 | }, 1L, TimeUnit.SECONDS); 88 | System.out.println("CurrentTime:" + LocalDateTime.now()); 89 | // newSingleThreadScheduledExecutor 使用 90 | ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor(); 91 | singleThreadScheduledExecutor.schedule(() -> { 92 | System.out.println("ThreadPool:" + LocalDateTime.now()); 93 | }, 1L, TimeUnit.SECONDS); 94 | System.out.println("CurrentTime:" + LocalDateTime.now()); 95 | // newWorkStealingPool 使用 96 | ExecutorService workStealingPool = Executors.newWorkStealingPool(); 97 | for (int i = 0; i < 10; i++) { 98 | int finalNumber = i; 99 | workStealingPool.execute(() -> { 100 | System.out.println(finalNumber); 101 | }); 102 | } 103 | Thread.sleep(5000); 104 | // ThreadPoolExecutor 七个参数的使用示例 105 | ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1, 106 | 10L, TimeUnit.SECONDS, new LinkedBlockingQueue(2), 107 | new MyThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()); 108 | threadPool.allowCoreThreadTimeOut(true); 109 | for (int i = 0; i < 10; i++) { 110 | threadPool.execute(new Runnable() { 111 | @Override 112 | public void run() { 113 | System.out.println(Thread.currentThread().getName()); 114 | try { 115 | Thread.sleep(2000); 116 | } catch (InterruptedException e) { 117 | e.printStackTrace(); 118 | } 119 | } 120 | }); 121 | } 122 | } 123 | } 124 | 125 | class MyThreadFactory implements ThreadFactory { 126 | private AtomicInteger count = new AtomicInteger(0); 127 | 128 | @Override 129 | public Thread newThread(Runnable r) { 130 | Thread t = new Thread(r); 131 | String threadName = "MyThread" + count.addAndGet(1); 132 | t.setName(threadName); 133 | return t; 134 | } 135 | } 136 | 137 | class MyRejectedExecutionHandler implements RejectedExecutionHandler { 138 | 139 | @Override 140 | public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { 141 | // 记录异常、报警处理等 142 | System.out.println("Error Message."); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson5_4.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.List; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | 10 | class ThreadLocalTest { 11 | static Integer MOCK_MAX = 10000; 12 | static Integer THREAD_MAX = 100; 13 | 14 | public static void main(String[] args) throws InterruptedException { 15 | // ThreadLocal 使用 16 | ThreadLocal threadLocal = new ThreadLocal(); 17 | // 存值 18 | threadLocal.set(Arrays.asList("老王", "Java 面试题")); 19 | // 取值 20 | List list = (List) threadLocal.get(); 21 | System.out.println(list.size()); 22 | System.out.println(threadLocal.get()); 23 | //删除值 24 | threadLocal.remove(); 25 | System.out.println(threadLocal.get()); 26 | // InheritableThreadLocal 使用 27 | ThreadLocal inheritableThreadLocal = new InheritableThreadLocal(); 28 | inheritableThreadLocal.set("老王"); 29 | new Thread(() -> System.out.println(inheritableThreadLocal.get())).start(); 30 | inheritableThreadLocal.remove(); 31 | // ThreadLocal 模拟内存溢出 32 | ExecutorService executorService = Executors.newFixedThreadPool(THREAD_MAX); 33 | for (int i = 0; i < THREAD_MAX; i++) { 34 | executorService.execute(() -> { 35 | threadLocal.set(new ThreadLocalTest().getList()); 36 | System.out.println(Thread.currentThread().getName()); 37 | // threadLocal.remove(); // 不注释此行内存溢出 38 | }); 39 | try { 40 | Thread.sleep(1000); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | executorService.shutdown(); 46 | // InheritableThreadLocal and ThreadLocal 值比较 47 | ThreadLocal threadLocal1 = new InheritableThreadLocal(); 48 | threadLocal1.set("老王"); 49 | ThreadLocal threadLocal2 = new ThreadLocal(); 50 | threadLocal2.set("老王"); 51 | new Thread(() -> { 52 | System.out.println(threadLocal1.get().equals(threadLocal2.get())); 53 | }).start(); 54 | } 55 | 56 | List getList() { 57 | List list = new ArrayList(); 58 | for (int i = 0; i < MOCK_MAX; i++) { 59 | list.add("Version:JDK 8"); 60 | list.add("ThreadLocal"); 61 | list.add("Author:老王"); 62 | list.add("DateTime:" + LocalDateTime.now()); 63 | list.add("Test:ThreadLocal OOM"); 64 | } 65 | return list; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson5_5.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.concurrent.TimeUnit; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | public class Lesson5_5 { 9 | static int number = 0; 10 | 11 | public static void main(String[] args) throws InterruptedException { 12 | // ReentrantLock 基本使用 13 | Lock lock = new ReentrantLock(); 14 | Thread thread1 = new Thread(() -> { 15 | lock.lock(); 16 | try { 17 | addNumber(); 18 | } finally { 19 | lock.unlock(); 20 | } 21 | }); 22 | Thread thread2 = new Thread(() -> { 23 | lock.lock(); 24 | try { 25 | addNumber(); 26 | } finally { 27 | lock.unlock(); 28 | } 29 | }); 30 | thread1.start(); 31 | thread2.start(); 32 | thread1.join(); 33 | thread2.join(); 34 | System.out.println("number:" + number); 35 | // ReentrantLock tryLock 36 | Lock reentrantLock = new ReentrantLock(); 37 | // 线程一 38 | new Thread(() -> { 39 | try { 40 | reentrantLock.lock(); 41 | System.out.println(LocalDateTime.now()); 42 | Thread.sleep(2 * 1000); 43 | 44 | } catch (InterruptedException e) { 45 | e.printStackTrace(); 46 | } finally { 47 | reentrantLock.unlock(); 48 | } 49 | }).start(); 50 | // 线程二 51 | new Thread(() -> { 52 | try { 53 | Thread.sleep(1 * 1000); 54 | // System.out.println(reentrantLock.tryLock()); 55 | // Thread.sleep(2 * 1000); 56 | // System.out.println(reentrantLock.tryLock()); 57 | System.out.println(reentrantLock.tryLock(3, TimeUnit.SECONDS)); 58 | System.out.println(LocalDateTime.now()); 59 | } catch (InterruptedException e) { 60 | e.printStackTrace(); 61 | } 62 | }).start(); 63 | // synchronized 使用 64 | Object syn = new Object(); 65 | Thread sThread = new Thread(() -> { 66 | synchronized (syn) { 67 | addNumber(); 68 | } 69 | }); 70 | Thread sThread2 = new Thread(() -> { 71 | synchronized (syn) { 72 | addNumber(); 73 | } 74 | }); 75 | sThread.start(); 76 | sThread2.start(); 77 | sThread.join(); 78 | sThread2.join(); 79 | System.out.println("number:" + number); 80 | // ReentrantLock lockInterruptibly() vs lock() 81 | Lock interruptLock = new ReentrantLock(); 82 | interruptLock.lock(); 83 | Thread thread = new Thread(new Runnable() { 84 | @Override 85 | public void run() { 86 | try { 87 | interruptLock.lock(); 88 | // interruptLock.lockInterruptibly(); // java.lang.InterruptedException 89 | } catch (Exception e) { 90 | e.printStackTrace(); 91 | } 92 | } 93 | }); 94 | thread.start(); 95 | TimeUnit.SECONDS.sleep(1); 96 | thread.interrupt(); 97 | TimeUnit.SECONDS.sleep(3); 98 | System.out.println("Over"); 99 | System.exit(0); 100 | } 101 | 102 | public static void addNumber() { 103 | for (int i = 0; i < 10000; i++) { 104 | ++number; 105 | } 106 | } 107 | } 108 | 109 | /** 110 | * @Description 非线程安全代码演示 111 | **/ 112 | class ThreadSafeTest { 113 | static int number = 0; 114 | 115 | public static void main(String[] args) throws InterruptedException { 116 | Thread thread1 = new Thread(() -> addNumber()); 117 | Thread thread2 = new Thread(() -> addNumber()); 118 | thread1.start(); 119 | thread2.start(); 120 | thread1.join(); 121 | thread2.join(); 122 | System.out.println("number:" + number); 123 | } 124 | 125 | public static void addNumber() { 126 | for (int i = 0; i < 10000; i++) { 127 | ++number; 128 | } 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson5_6.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.Random; 5 | import java.util.concurrent.*; 6 | 7 | public class Lesson5_6 { 8 | public static void main(String[] args) throws InterruptedException { 9 | // CountDownLatch 使用 10 | CountDownLatch hospitalLatch = new CountDownLatch(1); // 医院闭锁 11 | CountDownLatch patientLatch = new CountDownLatch(5); // 患者闭锁 12 | System.out.println("患者排队"); 13 | ExecutorService executorService = Executors.newCachedThreadPool(); 14 | for (int i = 0; i < 5; i++) { 15 | final int j = i; 16 | executorService.execute(() -> { 17 | try { 18 | hospitalLatch.await(); 19 | } catch (InterruptedException e) { 20 | e.printStackTrace(); 21 | } 22 | System.out.println("体检:" + j); 23 | patientLatch.countDown(); 24 | }); 25 | } 26 | System.out.println("医生上班"); 27 | hospitalLatch.countDown(); 28 | patientLatch.await(); 29 | System.out.println("医生下班"); 30 | executorService.shutdown(); 31 | // CyclicBarrier 使用 32 | CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new Runnable() { 33 | @Override 34 | public void run() { 35 | System.out.println("发车了"); 36 | } 37 | }); 38 | for (int i = 0; i < 4; i++) { 39 | new Thread(new CyclicWorker(cyclicBarrier)).start(); 40 | } 41 | // Semaphore 使用 42 | Semaphore semaphore = new Semaphore(2); 43 | ThreadPoolExecutor semaphoreThread = new ThreadPoolExecutor(10, 50, 44 | 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); 45 | for (int i = 0; i < 7; i++) { 46 | semaphoreThread.execute(() -> { 47 | try { 48 | // 堵塞获取许可 49 | semaphore.acquire(); 50 | System.out.println("Thread:" + Thread.currentThread().getName() + " 时间:" + LocalDateTime.now()); 51 | TimeUnit.SECONDS.sleep(2); 52 | // 释放许可 53 | semaphore.release(); 54 | } catch (InterruptedException e) { 55 | e.printStackTrace(); 56 | } 57 | }); 58 | } 59 | // Phaser 使用 60 | Phaser phaser = new MyPhaser(); 61 | PhaserWorker[] phaserWorkers = new PhaserWorker[5]; 62 | for (int i = 0; i < phaserWorkers.length; i++) { 63 | phaserWorkers[i] = new PhaserWorker(phaser); 64 | // 注册 Phaser 等待的线程数,执行一次等待线程数 +1 65 | phaser.register(); 66 | } 67 | for (int i = 0; i < phaserWorkers.length; i++) { 68 | // 执行任务 69 | new Thread(new PhaserWorker(phaser)).start(); 70 | } 71 | } 72 | 73 | static class PhaserWorker implements Runnable { 74 | private final Phaser phaser; 75 | public PhaserWorker(Phaser phaser) { 76 | this.phaser = phaser; 77 | } 78 | @Override 79 | public void run() { 80 | System.out.println(Thread.currentThread().getName() + " | 到达" ); 81 | phaser.arriveAndAwaitAdvance(); // 集合完毕发车 82 | try { 83 | Thread.sleep(new Random().nextInt(5) * 1000); 84 | System.out.println(Thread.currentThread().getName() + " | 到达" ); 85 | phaser.arriveAndAwaitAdvance(); // 景点1集合完毕发车 86 | 87 | Thread.sleep(new Random().nextInt(5) * 1000); 88 | System.out.println(Thread.currentThread().getName() + " | 到达" ); 89 | phaser.arriveAndAwaitAdvance(); // 景点1集合完毕发车 90 | } catch (InterruptedException e) { 91 | e.printStackTrace(); 92 | } 93 | } 94 | } 95 | 96 | // Phaser 使用演示 97 | static class MyPhaser extends Phaser{ 98 | @Override 99 | protected boolean onAdvance(int phase, int registeredParties) { // 每个阶段执行完之后的回调 100 | switch (phase) { 101 | case 0: 102 | System.out.println("==== 集合完毕发车 ===="); 103 | return false; 104 | case 1: 105 | System.out.println("==== 景点1集合完毕,发车去下一个景点 ===="); 106 | return false; 107 | case 2: 108 | System.out.println("==== 景点2集合完毕,发车回家 ===="); 109 | return false; 110 | default: 111 | return true; 112 | } 113 | } 114 | } 115 | 116 | // 配合演示 CyclicBarrier 117 | static class CyclicWorker implements Runnable { 118 | private CyclicBarrier cyclicBarrier; 119 | 120 | CyclicWorker(CyclicBarrier cyclicBarrier) { 121 | this.cyclicBarrier = cyclicBarrier; 122 | } 123 | 124 | @Override 125 | public void run() { 126 | for (int i = 0; i < 2; i++) { 127 | System.out.println("乘客:" + i); 128 | try { 129 | cyclicBarrier.await(); 130 | } catch (InterruptedException e) { 131 | e.printStackTrace(); 132 | } catch (BrokenBarrierException e) { 133 | e.printStackTrace(); 134 | } 135 | } 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson5_7.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.util.concurrent.atomic.AtomicStampedReference; 4 | import java.util.concurrent.locks.Lock; 5 | import java.util.concurrent.locks.ReadWriteLock; 6 | import java.util.concurrent.locks.ReentrantReadWriteLock; 7 | 8 | public class Lesson5_7 { 9 | public static void main(String[] args) throws InterruptedException { 10 | // 共享锁演示 11 | final MyReadWriteLock rwLock = new MyReadWriteLock(); 12 | // 创建读锁 r1 和 r2 13 | Thread r1 = new Thread(new Runnable() { 14 | @Override 15 | public void run() { 16 | rwLock.read(); 17 | } 18 | }, "r1"); 19 | Thread r2 = new Thread(new Runnable() { 20 | @Override 21 | public void run() { 22 | rwLock.read(); 23 | } 24 | }, "r2"); 25 | r1.start(); 26 | r2.start(); 27 | // 等待同时读取线程执行完成 28 | r1.join(); 29 | r2.join(); 30 | // 开启写锁的操作 31 | new Thread(new Runnable() { 32 | @Override 33 | public void run() { 34 | rwLock.write(); 35 | } 36 | }, "w1").start(); 37 | new Thread(new Runnable() { 38 | @Override 39 | public void run() { 40 | rwLock.write(); 41 | } 42 | }, "w2").start(); 43 | // AtomicStampedReference(解决 ABA 问题)使用演示 44 | String name = "老王"; 45 | String newName = "Java"; 46 | AtomicStampedReference as = new AtomicStampedReference(name, 1); 47 | System.out.println("值:" + as.getReference() + " | Stamp:" + as.getStamp()); 48 | as.compareAndSet(name, newName, as.getStamp(), as.getStamp() + 1); 49 | System.out.println("值:" + as.getReference() + " | Stamp:" + as.getStamp()); 50 | } 51 | 52 | static class MyReadWriteLock { 53 | ReadWriteLock lock = new ReentrantReadWriteLock(); 54 | 55 | public void read() { 56 | try { 57 | lock.readLock().lock(); 58 | System.out.println("读操作,进入 | 线程:" + Thread.currentThread().getName()); 59 | Thread.sleep(3000); 60 | System.out.println("读操作,退出 | 线程:" + Thread.currentThread().getName()); 61 | } catch (InterruptedException e) { 62 | e.printStackTrace(); 63 | } finally { 64 | lock.readLock().unlock(); 65 | } 66 | } 67 | 68 | public void write() { 69 | try { 70 | lock.writeLock().lock(); 71 | System.out.println("写操作,进入 | 线程:" + Thread.currentThread().getName()); 72 | Thread.sleep(3000); 73 | System.out.println("写操作,退出 | 线程:" + Thread.currentThread().getName()); 74 | } catch (InterruptedException e) { 75 | e.printStackTrace(); 76 | } finally { 77 | lock.writeLock().unlock(); 78 | } 79 | } 80 | } 81 | 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson6_1.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import net.sf.cglib.proxy.Enhancer; 4 | import net.sf.cglib.proxy.MethodInterceptor; 5 | import net.sf.cglib.proxy.MethodProxy; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | public class Lesson6_1 { 10 | public static void main(String[] args) { 11 | 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson7_3.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import javax.crypto.NoSuchPaddingException; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.util.*; 6 | 7 | public class Lesson7_3 { 8 | public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException { 9 | // 单例模式 10 | Singleton singleton1 = Singleton.getInstance(); 11 | Singleton singleton2 = Singleton.getInstance(); 12 | System.out.println(singleton1 == singleton2); // output:true 13 | // 抽象工厂 14 | String result = (new CoffeeFactory()).createProduct("Latte"); 15 | System.out.println(result); // output:拿铁 16 | //-------------- 观察者模式 START -------------- 17 | // 定义发布者 18 | ConcreteSubject concreteSubject = new ConcreteSubject(); 19 | // 定义订阅者 20 | ConcrereObserver concrereObserver = new ConcrereObserver("老王"); 21 | ConcrereObserver concrereObserver2 = new ConcrereObserver("Java"); 22 | // 添加订阅 23 | concreteSubject.attach(concrereObserver); 24 | concreteSubject.attach(concrereObserver2); 25 | // 发布信息 26 | concreteSubject.notify("更新了"); 27 | //-------------- 观察者模式 END -------------- 28 | // 装饰器模式 29 | LaoWang laoWang = new LaoWang(); 30 | Jacket jacket = new Jacket(laoWang); 31 | Hat hat = new Hat(jacket); 32 | hat.show(); 33 | // 模板方法模式 34 | Refrigerator refrigerator = new Banana(); 35 | refrigerator.open(); 36 | refrigerator.put(); 37 | refrigerator.close(); 38 | // 代理模式 39 | IAirTicket airTicket = new ProxyAirTicket(); 40 | airTicket.buy(); 41 | // 策略模式 42 | Trip trip = new Trip(new Bike()); 43 | trip.doTrip(); 44 | // 适配器模式 45 | TypeC typeC = new TypeC(); 46 | MicroUSB microUSB = new AdapterMicroUSB(typeC); 47 | microUSB.charger(); 48 | } 49 | } 50 | 51 | //------------- 适配器模式 START ------------- 52 | /* 53 | * 传统的充电线 MicroUSB 54 | */ 55 | interface MicroUSB { 56 | void charger(); 57 | } 58 | 59 | /* 60 | * TypeC 充电口 61 | */ 62 | interface ITypeC { 63 | void charger(); 64 | } 65 | 66 | class TypeC implements ITypeC { 67 | @Override 68 | public void charger() { 69 | System.out.println("TypeC 充电"); 70 | } 71 | } 72 | 73 | /* 74 | * 适配器 75 | */ 76 | class AdapterMicroUSB implements MicroUSB { 77 | private TypeC typeC; 78 | 79 | public AdapterMicroUSB(TypeC typeC) { 80 | this.typeC = typeC; 81 | } 82 | 83 | @Override 84 | public void charger() { 85 | typeC.charger(); 86 | } 87 | } 88 | //------------- 适配器模式 END ------------- 89 | 90 | //------------- 策略模式 START ------------- 91 | /* 92 | * 声明旅行 93 | */ 94 | interface ITrip { 95 | void going(); 96 | } 97 | 98 | class Bike implements ITrip { 99 | @Override 100 | public void going() { 101 | System.out.println("骑自行车"); 102 | } 103 | } 104 | 105 | class Drive implements ITrip { 106 | @Override 107 | public void going() { 108 | System.out.println("开车"); 109 | } 110 | } 111 | 112 | /* 113 | * 出行类 114 | */ 115 | class Trip { 116 | private ITrip trip; 117 | 118 | public Trip(ITrip trip) { 119 | this.trip = trip; 120 | } 121 | 122 | public void doTrip() { 123 | this.trip.going(); 124 | } 125 | } 126 | //------------- 策略模式 END ------------- 127 | 128 | //------------- 代理模式 START ------------- 129 | /* 130 | * 定义售票接口 131 | */ 132 | interface IAirTicket { 133 | void buy(); 134 | } 135 | 136 | /* 137 | * 定义飞机场售票 138 | */ 139 | class AirTicket implements IAirTicket { 140 | @Override 141 | public void buy() { 142 | System.out.println("买票"); 143 | } 144 | } 145 | 146 | /* 147 | * 代理售票平台 148 | */ 149 | class ProxyAirTicket implements IAirTicket { 150 | 151 | private AirTicket airTicket; 152 | 153 | public ProxyAirTicket() { 154 | airTicket = new AirTicket(); 155 | } 156 | 157 | @Override 158 | public void buy() { 159 | airTicket.buy(); 160 | } 161 | } 162 | //------------- 代理模式 END ------------- 163 | 164 | //------------- 模板方法模式 START ------------- 165 | abstract class Refrigerator { 166 | public void open() { 167 | System.out.println("开冰箱门"); 168 | } 169 | 170 | public abstract void put(); 171 | 172 | public void close() { 173 | System.out.println("关冰箱门"); 174 | } 175 | } 176 | 177 | class Banana extends Refrigerator { 178 | 179 | @Override 180 | public void put() { 181 | System.out.println("放香蕉"); 182 | } 183 | } 184 | 185 | class Apple extends Refrigerator { 186 | 187 | @Override 188 | public void put() { 189 | System.out.println("放苹果"); 190 | } 191 | } 192 | //------------- 模板方法模式 END ------------- 193 | 194 | //------------- 装饰器模式 START ------------- 195 | // 顶级对象 196 | interface IPerson { 197 | void show(); 198 | } 199 | 200 | // 装饰器超类 201 | class DecoratorBase implements IPerson { 202 | IPerson iPerson; 203 | 204 | public DecoratorBase(IPerson iPerson) { 205 | this.iPerson = iPerson; 206 | } 207 | 208 | @Override 209 | public void show() { 210 | iPerson.show(); 211 | } 212 | } 213 | 214 | // 具体装饰器 215 | class Jacket extends DecoratorBase { 216 | public Jacket(IPerson iPerson) { 217 | super(iPerson); 218 | } 219 | 220 | @Override 221 | public void show() { 222 | // 执行已有功能 223 | iPerson.show(); 224 | System.out.println("穿上夹克"); 225 | } 226 | } 227 | 228 | class Hat extends DecoratorBase { 229 | public Hat(IPerson iPerson) { 230 | super(iPerson); 231 | } 232 | 233 | @Override 234 | public void show() { 235 | // 执行已有功能 236 | iPerson.show(); 237 | System.out.println("戴上帽子"); 238 | } 239 | } 240 | 241 | // 具体对象 242 | class LaoWang implements IPerson { 243 | @Override 244 | public void show() { 245 | System.out.println("什么都没穿"); 246 | } 247 | } 248 | //------------- 装饰器模式 END ------------- 249 | 250 | //------------- 观察者模式 START ------------- 251 | // 观察者(消息接收方) 252 | interface Observer { 253 | public void update(String message); 254 | } 255 | 256 | // 具体的观察者(消息接收方) 257 | class ConcrereObserver implements Observer { 258 | private String name; 259 | 260 | public ConcrereObserver(String name) { 261 | this.name = name; 262 | } 263 | 264 | @Override 265 | public void update(String message) { 266 | System.out.println(name + ":" + message); 267 | } 268 | } 269 | 270 | // 被观察者(消息发布方) 271 | interface Subject { 272 | // 增加订阅者 273 | public void attach(Observer observer); 274 | 275 | // 删除订阅者 276 | public void detach(Observer observer); 277 | 278 | // 通知订阅者更新消息 279 | public void notify(String message); 280 | } 281 | 282 | // 具体被观察者(消息发布方) 283 | class ConcreteSubject implements Subject { 284 | // 订阅者列表(存储信息) 285 | private List list = new ArrayList(); 286 | 287 | @Override 288 | public void attach(Observer observer) { 289 | list.add(observer); 290 | } 291 | 292 | @Override 293 | public void detach(Observer observer) { 294 | list.remove(observer); 295 | } 296 | 297 | @Override 298 | public void notify(String message) { 299 | for (Observer observer : list) { 300 | observer.update(message); 301 | } 302 | } 303 | } 304 | //------------- 观察者模式 END ------------- 305 | 306 | // 抽象工厂 307 | abstract class AbstractFactory { 308 | public abstract String createProduct(String product); 309 | } 310 | 311 | // 啤酒工厂 312 | class BeerFactory extends AbstractFactory { 313 | @Override 314 | public String createProduct(String product) { 315 | String result = null; 316 | switch (product) { 317 | case "Hans": 318 | result = "汉斯"; 319 | break; 320 | case "Yanjing": 321 | result = "燕京"; 322 | break; 323 | default: 324 | result = "其他啤酒"; 325 | break; 326 | } 327 | return result; 328 | } 329 | } 330 | 331 | // 咖啡工厂 332 | class CoffeeFactory extends AbstractFactory { 333 | @Override 334 | public String createProduct(String product) { 335 | String result = null; 336 | switch (product) { 337 | case "Mocca": 338 | result = "摩卡"; 339 | break; 340 | case "Latte": 341 | result = "拿铁"; 342 | break; 343 | default: 344 | result = "其他咖啡"; 345 | break; 346 | } 347 | return result; 348 | } 349 | } 350 | 351 | // 简单工厂 352 | class Factory { 353 | public static String createProduct(String product) { 354 | String result = null; 355 | switch (product) { 356 | case "Mocca": 357 | result = "摩卡"; 358 | break; 359 | case "Latte": 360 | result = "拿铁"; 361 | break; 362 | default: 363 | result = "其他"; 364 | break; 365 | } 366 | return result; 367 | } 368 | } 369 | 370 | // 单例模式 371 | class Singleton { 372 | private static Singleton instance = new Singleton(); 373 | 374 | public static Singleton getInstance() { 375 | return instance; 376 | } 377 | } 378 | 379 | // 单例模式-延迟加载 380 | class SingletonLazy { 381 | private static SingletonLazy instance; 382 | 383 | public static synchronized SingletonLazy getInstance() { 384 | if (instance == null) { 385 | instance = new SingletonLazy(); 386 | } 387 | return instance; 388 | } 389 | } 390 | 391 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/Lesson7_4.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * 算法 7 | */ 8 | public class Lesson7_4 { 9 | public static void main(String[] args) { 10 | // 二分法查找 11 | int[] binaryNums = {1, 6, 15, 18, 27, 50}; 12 | int findValue = 27; 13 | int binaryResult = binarySearch(binaryNums, 0, binaryNums.length - 1, findValue); 14 | System.out.println("元素第一次出现的位置(从0开始):" + binaryResult); 15 | 16 | // 斐波那契数列 17 | int fibonacciIndex = 7; 18 | int fibonacciResult = fibonacci(fibonacciIndex); 19 | System.out.println("下标(从0开始)" + fibonacciIndex + "的值为:" + fibonacciResult); 20 | 21 | // 兔子的总对数 22 | int rabbitNumber = fibonacci(12); 23 | System.out.println("第 12 个月兔子的总对数是:" + rabbitNumber); 24 | 25 | // 冒泡排序调用 26 | int[] bubbleNums = {132, 110, 122, 90, 50}; 27 | System.out.println("冒泡排序前:" + Arrays.toString(bubbleNums)); 28 | bubbleSort(bubbleNums); 29 | System.out.println("冒泡排序后:" + Arrays.toString(bubbleNums)); 30 | 31 | // 选择排序调用 32 | int[] selectNums = {18, 1, 6, 27, 15}; 33 | System.out.println("选择排序前:" + Arrays.toString(selectNums)); 34 | selectSort(selectNums); 35 | System.out.println("选择排序后:" + Arrays.toString(selectNums)); 36 | 37 | // 插入排序调用 38 | int[] insertNums = {18, 1, 6, 27, 15}; 39 | System.out.println("插入排序前:" + Arrays.toString(insertNums)); 40 | insertSort(insertNums); 41 | System.out.println("插入排序后:" + Arrays.toString(insertNums)); 42 | 43 | // 快速排序调用 44 | int[] quickNums = {18, 1, 6, 27, 15}; 45 | System.out.println("快速排序前:" + Arrays.toString(quickNums)); 46 | quickSort(quickNums, 0, quickNums.length - 1); 47 | System.out.println("快速排序后:" + Arrays.toString(quickNums)); 48 | 49 | // 堆排序调用 50 | int[] heapNums = {18, 1, 6, 27, 15}; 51 | System.out.println("堆排序前:" + Arrays.toString(heapNums)); 52 | heapSort(heapNums, heapNums.length); 53 | System.out.println("堆排序后:" + Arrays.toString(heapNums)); 54 | 55 | } 56 | 57 | /** 58 | * 斐波那契数列 59 | * @param index 斐波那契数列的下标(从0开始) 60 | * @return int 61 | */ 62 | private static int fibonacci(int index) { 63 | if (index == 0 || index == 1) { 64 | return index; 65 | } else { 66 | return fibonacci(index - 1) + fibonacci(index - 2); 67 | } 68 | } 69 | 70 | /** 71 | * 二分查找,返回该值第一次出现的位置(下标从0开始) 72 | * @param nums 查询数组 73 | * @param start 开始下标 74 | * @param end 结束下标 75 | * @param findValue 要查找的值 76 | * @return int 77 | */ 78 | private static int binarySearch(int[] nums, int start, int end, int findValue) { 79 | if (start <= end) { 80 | // 中间位置 81 | int middle = (start + end) / 2; 82 | // 中间的值 83 | int middleValue = nums[middle]; 84 | if (findValue == middleValue) { 85 | // 等于中值直接返回 86 | return middle; 87 | } else if (findValue < middleValue) { 88 | // 小于中值,在中值之前的数据中查找 89 | return binarySearch(nums, start, middle - 1, findValue); 90 | } else { 91 | // 大于中值,在中值之后的数据中查找 92 | return binarySearch(nums, middle + 1, end, findValue); 93 | } 94 | } 95 | return -1; 96 | } 97 | 98 | /** 99 | * 堆排序 100 | * @param nums 待排序数组 101 | * @param n 堆大小 102 | */ 103 | private static void heapSort(int[] nums, int n) { 104 | int i, j, k, temp; 105 | // 将 nums[0,n-1] 建成大根堆 106 | for (i = n / 2 - 1; i >= 0; i--) { 107 | // 第 i 个节点,有右子树 108 | while (2 * i + 1 < n) { 109 | j = 2 * i + 1; 110 | if ((j + 1) < n) { 111 | // 右左子树小于右子树,则需要比较右子树 112 | if (nums[j] < nums[j + 1]) { 113 | // 序号增加 1,指向右子树 114 | j++; 115 | } 116 | } 117 | if (nums[i] < nums[j]) { 118 | // 交换数据 119 | temp = nums[i]; 120 | nums[i] = nums[j]; 121 | nums[j] = temp; 122 | // 堆被破坏,重新调整 123 | i = j; 124 | } else { 125 | // 左右子节点均大,则堆未被破坏,不需要调整 126 | break; 127 | } 128 | } 129 | } 130 | for (i = n - 1; i > 0; i--) { 131 | // 与第 i 个记录交换 132 | temp = nums[0]; 133 | nums[0] = nums[i]; 134 | nums[i] = temp; 135 | k = 0; 136 | // 第 i 个节点有右子树 137 | while (2 * k + 1 < i) { 138 | j = 2 * k + 1; 139 | if ((j + 1) < i) { 140 | // 右左子树小于右子树,则需要比较右子树 141 | if (nums[j] < nums[j + 1]) { 142 | // 序号增加 1,指向右子树 143 | j++; 144 | } 145 | } 146 | // 比较 i 与 j 为序号的数据 147 | if (nums[k] < nums[j]) { 148 | // 交换数据 149 | temp = nums[k]; 150 | nums[k] = nums[j]; 151 | nums[j] = temp; 152 | // 堆被破坏,重新调整 153 | k = j; 154 | } else { 155 | // 左右子节点均大,则堆未被破坏,不需要调整 156 | break; 157 | } 158 | } 159 | // 输出每步排序结果 160 | System.out.println("第" + (n - i) + "步排序:"); 161 | System.out.println(Arrays.toString(nums)); 162 | } 163 | } 164 | 165 | /** 166 | * 快速排序 167 | * @param nums 待排序数组 168 | */ 169 | private static void quickSort(int[] nums, int left, int right) { 170 | int f, t; 171 | int ltemp = left; 172 | int rtemp = right; 173 | // 分界值 174 | f = nums[(left + right) / 2]; 175 | while (ltemp < rtemp) { 176 | while (nums[ltemp] < f) { 177 | ++ltemp; 178 | } 179 | while (nums[rtemp] > f) { 180 | --rtemp; 181 | } 182 | if (ltemp <= rtemp) { 183 | t = nums[ltemp]; 184 | nums[ltemp] = nums[rtemp]; 185 | nums[rtemp] = t; 186 | --rtemp; 187 | ++ltemp; 188 | } 189 | } 190 | if (ltemp == rtemp) { 191 | ltemp++; 192 | } 193 | if (left < rtemp) { 194 | // 递归调用 195 | quickSort(nums, left, ltemp - 1); 196 | } 197 | if (right > ltemp) { 198 | // 递归调用 199 | quickSort(nums, rtemp + 1, right); 200 | } 201 | } 202 | 203 | /** 204 | * 插入排序 205 | * @param nums 待排序数组 206 | */ 207 | private static void insertSort(int[] nums) { 208 | int j, k; 209 | for (int i = 1; i < nums.length; i++) { 210 | k = nums[i]; 211 | j = i - 1; 212 | while (j >= 0 && k < nums[j]) { 213 | nums[j + 1] = nums[j]; 214 | j--; 215 | } 216 | nums[j + 1] = k; 217 | System.out.println("I:" + i); 218 | System.out.println(Arrays.toString(nums)); 219 | } 220 | } 221 | 222 | /** 223 | * 选择排序 224 | * @param nums 待排序数组 225 | */ 226 | private static void selectSort(int[] nums) { 227 | int index; 228 | int temp; 229 | for (int i = 0; i < nums.length - 1; i++) { 230 | index = i; 231 | for (int j = i + 1; j < nums.length; j++) { 232 | if (nums[j] < nums[index]) { 233 | index = j; 234 | } 235 | } 236 | if (index != i) { 237 | temp = nums[i]; 238 | nums[i] = nums[index]; 239 | nums[index] = temp; 240 | } 241 | System.out.println("I:" + i); 242 | System.out.println(Arrays.toString(nums)); 243 | } 244 | } 245 | 246 | /** 247 | * 冒泡排序 248 | * @param nums 待排序数组 249 | */ 250 | private static void bubbleSort(int[] nums) { 251 | int temp; 252 | for (int i = 1; i < nums.length; i++) { 253 | for (int j = 0; j < nums.length - i; j++) { 254 | if (nums[j] > nums[j + 1]) { 255 | temp = nums[j]; 256 | nums[j] = nums[j + 1]; 257 | nums[j + 1] = temp; 258 | } 259 | } 260 | System.out.println("I:" + i); 261 | System.out.println(Arrays.toString(nums)); 262 | } 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/other/CustomDelayQueue.java: -------------------------------------------------------------------------------- 1 | package com.interview.other; 2 | 3 | import java.text.DateFormat; 4 | import java.util.Date; 5 | import java.util.Random; 6 | import java.util.concurrent.DelayQueue; 7 | import java.util.concurrent.Delayed; 8 | import java.util.concurrent.TimeUnit; 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | 11 | /* 12 | * 如何使用Java原生方式,手撸一个延迟队列(MQ)?多生产者版本 13 | **/ 14 | public class CustomDelayQueue { 15 | // 消息编号 16 | static AtomicInteger MESSAGENO = new AtomicInteger(1); 17 | 18 | public static void main(String[] args) throws InterruptedException { 19 | DelayQueue delayQueue = new DelayQueue<>(); 20 | // 生产者1 21 | producer(delayQueue, "生产者1"); 22 | 23 | // 生产者2 24 | producer(delayQueue, "生产者2"); 25 | 26 | // 消费者 27 | consumer(delayQueue); 28 | 29 | /* 执行结果 30 | 生产者1,消息编号:1 发送时间:2019-6-12 20:38:37 延迟:2 秒 |执行时间:2019-6-12 20:38:39 31 | 生产者2,消息编号:2 发送时间:2019-6-12 20:38:37 延迟:2 秒 |执行时间:2019-6-12 20:38:39 32 | 生产者1,消息编号:3 发送时间:2019-6-12 20:38:41 延迟:4 秒 |执行时间:2019-6-12 20:38:45 33 | 生产者1,消息编号:5 发送时间:2019-6-12 20:38:43 延迟:2 秒 |执行时间:2019-6-12 20:38:45 34 | .... 35 | */ 36 | } 37 | 38 | //生产者 39 | private static void producer(DelayQueue delayQueue, String name) { 40 | new Thread(new Runnable() { 41 | @Override 42 | public void run() { 43 | while (true) { 44 | // 产生 1~5 秒的随机数 45 | long time = 1000L * (new Random().nextInt(5) + 1); 46 | try { 47 | Thread.sleep(time); 48 | } catch (InterruptedException e) { 49 | e.printStackTrace(); 50 | } 51 | // 组合消息体 52 | String message = String.format("%s,消息编号:%s 发送时间:%s 延迟:%s 秒", 53 | name, MESSAGENO.getAndIncrement(), DateFormat.getDateTimeInstance().format(new Date()), time / 1000); 54 | // 生产消息 55 | delayQueue.put(new DelayedElement(message, time)); 56 | } 57 | } 58 | }).start(); 59 | } 60 | 61 | //消费者 62 | private static void consumer(DelayQueue delayQueue) { 63 | new Thread(new Runnable() { 64 | @Override 65 | public void run() { 66 | while (true) { 67 | DelayedElement element = null; 68 | try { 69 | // 消费消息 70 | element = delayQueue.take(); 71 | System.out.println(element); 72 | } catch (InterruptedException e) { 73 | e.printStackTrace(); 74 | } 75 | } 76 | } 77 | }).start(); 78 | } 79 | 80 | // 延迟队列对象 81 | static class DelayedElement implements Delayed { 82 | // 过期时间(单位:毫秒) 83 | long time = System.currentTimeMillis(); 84 | // 消息体 85 | String message; 86 | // 参数:delayTime 延迟时间(单位毫秒) 87 | public DelayedElement(String message, long delayTime) { 88 | this.time += delayTime; 89 | this.message = message; 90 | } 91 | @Override 92 | // 获取过期时间 93 | public long getDelay(TimeUnit unit) { 94 | return unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS); 95 | } 96 | @Override 97 | // 队列元素排序 98 | public int compareTo(Delayed o) { 99 | if (this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) 100 | return 1; 101 | else if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) 102 | return -1; 103 | else 104 | return 0; 105 | } 106 | @Override 107 | public String toString() { 108 | // 打印消息 109 | return message + " |执行时间:" + DateFormat.getDateTimeInstance().format(new Date()); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/other/EnumTest.java: -------------------------------------------------------------------------------- 1 | package com.interview.other; 2 | 3 | enum DBEnum { 4 | ORACLE, 5 | DB2, 6 | MYSQL, 7 | SQLSERVER 8 | } 9 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/other/RocketMQDemo.java: -------------------------------------------------------------------------------- 1 | package com.interview.other; 2 | 3 | import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer; 4 | import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; 5 | import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; 6 | import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently; 7 | import com.alibaba.rocketmq.client.exception.MQBrokerException; 8 | import com.alibaba.rocketmq.client.exception.MQClientException; 9 | import com.alibaba.rocketmq.client.producer.DefaultMQProducer; 10 | import com.alibaba.rocketmq.common.message.Message; 11 | import com.alibaba.rocketmq.common.message.MessageExt; 12 | import com.alibaba.rocketmq.remoting.exception.RemotingException; 13 | 14 | import java.util.List; 15 | 16 | public class RocketMQDemo { 17 | static final String MQ_NAMESRVADDR = "localhost:9876"; 18 | 19 | public static void main(String[] args) { 20 | // 分组名 21 | String groupName = "myGroup-1"; 22 | // 主题名 23 | String topicName = "myTopic-1"; 24 | // 标签名 25 | String tagName = "myTag-1"; 26 | 27 | new Thread(() -> { 28 | try { 29 | producer(groupName, topicName, tagName); 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } catch (RemotingException e) { 33 | e.printStackTrace(); 34 | } catch (MQClientException e) { 35 | e.printStackTrace(); 36 | } catch (MQBrokerException e) { 37 | e.printStackTrace(); 38 | } 39 | }).start(); 40 | 41 | new Thread(() -> { 42 | try { 43 | consumer(groupName, topicName, tagName); 44 | } catch (MQClientException e) { 45 | e.printStackTrace(); 46 | } 47 | }).start(); 48 | } 49 | 50 | /** 51 | * @Description 生产者 52 | * @Author wanglei 53 | * @Param [groupName 分组名, topicName 主题名, tagName 标签名] 54 | **/ 55 | public static void producer(String groupName, String topicName, String tagName) throws InterruptedException, RemotingException, MQClientException, MQBrokerException { 56 | DefaultMQProducer producer = new DefaultMQProducer(groupName); 57 | producer.setNamesrvAddr(MQ_NAMESRVADDR); 58 | producer.start(); 59 | String body = "Hello, 老王"; 60 | Message message = new Message(topicName, tagName, body.getBytes()); 61 | producer.send(message); 62 | producer.shutdown(); 63 | } 64 | 65 | /** 66 | * @Description 消费者 67 | * @Author wanglei 68 | * @Param [groupName 分组名, topicName 主题名, tagName 标签名] 69 | **/ 70 | public static void consumer(String groupName, String topicName, String tagName) throws MQClientException { 71 | DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName); 72 | consumer.setNamesrvAddr(MQ_NAMESRVADDR); 73 | consumer.subscribe(topicName, tagName); 74 | consumer.registerMessageListener(new MessageListenerConcurrently() { 75 | @Override 76 | public ConsumeConcurrentlyStatus consumeMessage( 77 | List msgs, ConsumeConcurrentlyContext context) { 78 | for (MessageExt msg : msgs) { 79 | System.out.println(new String(msg.getBody())); 80 | } 81 | return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; 82 | } 83 | }); 84 | consumer.start(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /interview-code/src/main/java/com/interview/other/SynchronizedTest.java: -------------------------------------------------------------------------------- 1 | package com.interview.other; 2 | 3 | public class SynchronizedTest { 4 | public static void main(String[] args) { 5 | synchronized (SynchronizedTest.class) { 6 | System.out.println("Java"); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /mybatislearning-xml/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.6.RELEASE 9 | 10 | 11 | com.interview 12 | mybatislearning-xml 13 | 0.0.1-SNAPSHOT 14 | mybatislearning 15 | Demo project for Spring Boot + MyBatis 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | org.mybatis.spring.boot 28 | mybatis-spring-boot-starter 29 | 2.1.0 30 | 31 | 32 | mysql 33 | mysql-connector-java 34 | 8.0.16 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-maven-plugin 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/main/java/com/interview/mybatislearning/MyBatisLearningApplication.java: -------------------------------------------------------------------------------- 1 | package com.interview.mybatislearning; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @MapperScan("com.interview.mybatislearning.mapper") 9 | public class MyBatisLearningApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(MyBatisLearningApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/main/java/com/interview/mybatislearning/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.interview.mybatislearning.mapper; 2 | 3 | 4 | import com.interview.mybatislearning.model.UserEntity; 5 | 6 | import java.util.List; 7 | 8 | public interface UserMapper { 9 | List getAll(); 10 | 11 | UserEntity getOne(Long id); 12 | 13 | void insert(UserEntity user); 14 | 15 | void update(UserEntity user); 16 | 17 | void delete(Long id); 18 | } 19 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/main/java/com/interview/mybatislearning/model/UserEntity.java: -------------------------------------------------------------------------------- 1 | package com.interview.mybatislearning.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class UserEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -5980266333958177104L; 8 | private Integer id; 9 | private String userName; 10 | private String passWord; 11 | private String nickName; 12 | 13 | public UserEntity(String userName, String passWord, String nickName) { 14 | this.userName = userName; 15 | this.passWord = passWord; 16 | this.nickName = nickName; 17 | } 18 | 19 | public Integer getId() { 20 | return id; 21 | } 22 | 23 | public void setId(Integer id) { 24 | this.id = id; 25 | } 26 | 27 | public String getUserName() { 28 | return userName; 29 | } 30 | 31 | public void setUserName(String userName) { 32 | this.userName = userName; 33 | } 34 | 35 | public String getPassWord() { 36 | return passWord; 37 | } 38 | 39 | public void setPassWord(String passWord) { 40 | this.passWord = passWord; 41 | } 42 | 43 | public String getNickName() { 44 | return nickName; 45 | } 46 | 47 | public void setNickName(String nickName) { 48 | this.nickName = nickName; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | debug: true 2 | spring: 3 | datasource: 4 | url: jdbc:mysql://localhost:3306/learndb?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true 5 | username: root 6 | password: root 7 | driver-class-name: com.mysql.cj.jdbc.Driver 8 | mybatis: 9 | config-location: classpath:mybatis/mybatis-config.xml 10 | mapper-locations: classpath:mybatis/mapper/*.xml 11 | type-aliases-package: com.interview.mybatislearning.model 12 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/main/resources/mybatis/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | id, username, password, nick_name 13 | 14 | 15 | 16 | 17 | and userName = #{userName} 18 | 19 | 20 | 21 | 26 | 27 | 33 | 34 | 35 | INSERT INTO 36 | t_user 37 | (username,password,nick_name) 38 | VALUES 39 | (#{userName}, #{passWord}, #{nickName}) 40 | 41 | 42 | 43 | UPDATE 44 | t_user 45 | SET 46 | username = #{userName}, 47 | password = #{passWord}, 48 | nick_name = #{nickName} 49 | WHERE 50 | id = #{id} 51 | 52 | 53 | 54 | DELETE FROM 55 | t_user 56 | WHERE 57 | id =#{id} 58 | 59 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/main/resources/mybatis/mybatis-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /mybatislearning-xml/src/test/java/com/interview/mybatislearning/MybatislearningApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.interview.mybatislearning; 2 | 3 | import com.interview.mybatislearning.mapper.UserMapper; 4 | import com.interview.mybatislearning.model.UserEntity; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | 11 | import javax.annotation.Resource; 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class MybatislearningApplicationTests { 16 | 17 | @Resource 18 | private UserMapper userMapper; 19 | 20 | @Test 21 | public void testInsert() { 22 | userMapper.insert(new UserEntity("laowang", "123456", "老王")); 23 | Assert.assertEquals(1, userMapper.getAll().size()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /mybatislearning/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.7.RELEASE 9 | 10 | 11 | com.interview 12 | mybatislearning 13 | 0.0.1-SNAPSHOT 14 | mybatislearning 15 | Demo project for Spring Boot + MyBatis 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | org.mybatis.spring.boot 28 | mybatis-spring-boot-starter 29 | 2.1.0 30 | 31 | 32 | 33 | mysql 34 | mysql-connector-java 35 | 8.0.16 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-maven-plugin 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /mybatislearning/src/main/java/com/interview/MybatisApplication.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @MapperScan("com.interview.mapper") 9 | public class MybatisApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(MybatisApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /mybatislearning/src/main/java/com/interview/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.interview.mapper; 2 | 3 | import com.interview.model.UserEntity; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | public interface UserMapper { 9 | @Select("select * from t_user") 10 | @Results({ 11 | @Result(property = "nickName", column = "nick_name") 12 | }) 13 | List getAll(); 14 | 15 | @Select("select * from t_user where id = #{id}") 16 | @Results({ 17 | @Result(property = "nickName", column = "nick_name") 18 | }) 19 | UserEntity getOne(Long id); 20 | 21 | @Insert("insert into t_user(username,password,nick_name) values(#{userName}, #{passWord}, #{nickName})") 22 | void insert(UserEntity user); 23 | 24 | @Update("update t_user set username=#{userName},nick_name=#{nickName} where id =#{id}") 25 | void update(UserEntity user); 26 | 27 | @Update({""}) 35 | void updateUserEntity(UserEntity user); 36 | 37 | @Delete("delete from t_user where id =#{id}") 38 | void delete(Long id); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /mybatislearning/src/main/java/com/interview/model/UserEntity.java: -------------------------------------------------------------------------------- 1 | package com.interview.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class UserEntity implements Serializable { 6 | 7 | private static final long serialVersionUID = -5980266333958177104L; 8 | private Integer id; 9 | private String userName; 10 | private String passWord; 11 | private String nickName; 12 | 13 | public UserEntity(String userName, String passWord, String nickName) { 14 | this.userName = userName; 15 | this.passWord = passWord; 16 | this.nickName = nickName; 17 | } 18 | 19 | public Integer getId() { 20 | return id; 21 | } 22 | 23 | public void setId(Integer id) { 24 | this.id = id; 25 | } 26 | 27 | public String getUserName() { 28 | return userName; 29 | } 30 | 31 | public void setUserName(String userName) { 32 | this.userName = userName; 33 | } 34 | 35 | public String getPassWord() { 36 | return passWord; 37 | } 38 | 39 | public void setPassWord(String passWord) { 40 | this.passWord = passWord; 41 | } 42 | 43 | public String getNickName() { 44 | return nickName; 45 | } 46 | 47 | public void setNickName(String nickName) { 48 | this.nickName = nickName; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /mybatislearning/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | debug: true 2 | spring: 3 | datasource: 4 | url: jdbc:mysql://localhost:3306/learndb?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true 5 | username: root 6 | password: root 7 | driver-class-name: com.mysql.cj.jdbc.Driver 8 | mybatis: 9 | type-aliases-package: com.interview.model -------------------------------------------------------------------------------- /mybatislearning/src/test/java/com/interview/MybatisApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.interview; 2 | 3 | import com.interview.mapper.UserMapper; 4 | import com.interview.model.UserEntity; 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest 15 | public class MybatisApplicationTests { 16 | 17 | @Autowired 18 | private UserMapper userMapper; 19 | 20 | @Test 21 | public void testInsert() { 22 | userMapper.insert(new UserEntity("laowang", "123456", "老王")); 23 | Assert.assertEquals(1, userMapper.getAll().size()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /springbootlearning/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.1.6.RELEASE 9 | 10 | 11 | com.interview.java 12 | springbootlearning 13 | 0.0.1-SNAPSHOT 14 | springbootlearning 15 | Demo project for Spring Boot 16 | war 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-test 30 | test 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-maven-plugin 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /springbootlearning/src/main/java/com/interview/java/springbootlearning/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.interview.java.springbootlearning; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | public class HelloController { 9 | 10 | @Value("${app.name}") 11 | private String appName; 12 | 13 | @RequestMapping("/index") 14 | public String index(String hiName) { 15 | return "Hello, " + hiName + " |@" + appName; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /springbootlearning/src/main/java/com/interview/java/springbootlearning/SpringbootlearningApplication.java: -------------------------------------------------------------------------------- 1 | package com.interview.java.springbootlearning; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootlearningApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootlearningApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /springbootlearning/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8086 2 | app.name2=\u4E2D\u6587 3 | 4 | 5 | -------------------------------------------------------------------------------- /springbootlearning/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8086 3 | app: 4 | name: 简体中文 -------------------------------------------------------------------------------- /springbootlearning/src/test/java/com/interview/java/springbootlearning/SpringbootlearningApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.interview.java.springbootlearning; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootlearningApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /springlearning/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | com.interview 7 | springlearning 8 | 1.0-SNAPSHOT 9 | war 10 | springlearning Maven Webapp 11 | http://www.example.com 12 | 13 | 14 | UTF-8 15 | 1.8 16 | 1.8 17 | 18 | 19 | 20 | 21 | 22 | org.springframework 23 | spring-web 24 | 5.1.8.RELEASE 25 | 26 | 27 | org.springframework 28 | spring-webmvc 29 | 5.1.8.RELEASE 30 | 31 | 32 | 33 | javax.servlet.jsp.jstl 34 | jstl-api 35 | 1.2 36 | 37 | 38 | 39 | junit 40 | junit 41 | 4.11 42 | test 43 | 44 | 45 | 46 | org.aspectj 47 | aspectjweaver 48 | 1.7.4 49 | 50 | 51 | 52 | org.hibernate.validator 53 | hibernate-validator 54 | 6.0.17.Final 55 | 56 | 57 | 58 | com.google.code.gson 59 | gson 60 | 2.8.5 61 | 62 | 63 | 64 | 65 | 66 | springlearning 67 | 68 | 69 | 70 | maven-clean-plugin 71 | 3.1.0 72 | 73 | 74 | maven-resources-plugin 75 | 3.0.2 76 | 77 | 78 | maven-compiler-plugin 79 | 3.8.0 80 | 81 | 82 | maven-surefire-plugin 83 | 2.22.1 84 | 85 | 86 | maven-war-plugin 87 | 3.2.2 88 | 89 | 90 | maven-install-plugin 91 | 2.5.2 92 | 93 | 94 | maven-deploy-plugin 95 | 2.8.2 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/aop/CarAop.java: -------------------------------------------------------------------------------- 1 | package com.learning.aop; 2 | 3 | import org.aspectj.lang.annotation.After; 4 | import org.aspectj.lang.annotation.Aspect; 5 | import org.aspectj.lang.annotation.Before; 6 | import org.springframework.stereotype.Component; 7 | 8 | 9 | @Component 10 | @Aspect 11 | public class CarAop { 12 | @Before("execution(* com.learning.aop.Person.drive())") 13 | public void before() { 14 | System.out.println("巡视车体及周围情况"); 15 | System.out.println("发动"); 16 | } 17 | 18 | @After("execution(* com.learning.aop.Person.drive())") 19 | public void after() { 20 | System.out.println("熄火"); 21 | System.out.println("锁车"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/aop/Person.java: -------------------------------------------------------------------------------- 1 | package com.learning.aop; 2 | import org.springframework.stereotype.Component; 3 | 4 | @Component("person") 5 | public class Person { 6 | public void drive() { 7 | System.out.println("开车"); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/aop/PersonTest.java: -------------------------------------------------------------------------------- 1 | package com.learning.aop; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | 6 | /** 7 | * 测试类 8 | **/ 9 | public class PersonTest { 10 | public static void main(String[] args) { 11 | ApplicationContext context = 12 | new ClassPathXmlApplicationContext("spring-mvc.xml"); 13 | Person landlord = context.getBean("person", Person.class); 14 | landlord.drive(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/config/MyConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.learning.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | @Configuration 9 | public class MyConfiguration { 10 | @Bean 11 | public WebMvcConfigurer corsConfigurer() { 12 | return new WebMvcConfigurer() { 13 | @Override 14 | public void addCorsMappings(CorsRegistry registry) { 15 | // 设置允许跨域的请求规则 16 | registry.addMapping("/api/**"); 17 | } 18 | }; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/controller/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.learning.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.servlet.ModelAndView; 6 | 7 | @Controller 8 | public class HomeController { 9 | 10 | /** 11 | * index 方法 12 | **/ 13 | @RequestMapping("/") 14 | public ModelAndView index() { 15 | System.out.println("do index()"); 16 | ModelAndView modelAndView = new ModelAndView("index", 17 | "message", "用户信息"); 18 | return modelAndView; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/controller/PersonController.java: -------------------------------------------------------------------------------- 1 | package com.learning.controller; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.learning.pojo.PersonDTO; 5 | import org.springframework.validation.BindingResult; 6 | import org.springframework.validation.ObjectError; 7 | import org.springframework.validation.annotation.Validated; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.util.List; 12 | 13 | 14 | @RestController 15 | @RequestMapping("/api") 16 | public class PersonController { 17 | /** 18 | * 自动类型转换 19 | **/ 20 | @RequestMapping(value = "/add", produces = "text/plain;charset=utf-8") 21 | public String add(PersonDTO person) { 22 | System.out.println("do add()"); 23 | return person.getName() + ":" + person.getAge(); 24 | } 25 | 26 | /** 27 | * 需要 import com.google.gson.Gson(JSON 操作) 28 | **/ 29 | @RequestMapping(value = "/check", produces = "text/plain;charset=utf-8") 30 | public String check(@Validated PersonDTO person, BindingResult bindResult) { 31 | JsonObject result = new JsonObject(); 32 | StringBuilder errmsg = new StringBuilder(); 33 | if (bindResult.hasErrors()) { 34 | List errors = bindResult.getAllErrors(); 35 | for (ObjectError error : errors) { 36 | errmsg.append(error.getDefaultMessage()+"|"); 37 | } 38 | result.addProperty("status", -1); 39 | } else { 40 | result.addProperty("status", 1); 41 | } 42 | result.addProperty("errmsg", errmsg.toString()); 43 | return result.toString(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/core/MyInteceptor.java: -------------------------------------------------------------------------------- 1 | package com.learning.core; 2 | 3 | import org.springframework.web.servlet.HandlerInterceptor; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | // 自定义拦截器 10 | public class MyInteceptor implements HandlerInterceptor { 11 | // 在业务处理器处理请求之前被调用 12 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 13 | Object handler) throws Exception { 14 | System.out.println("preHandle"); 15 | return true; 16 | } 17 | 18 | // 在业务处理器处理请求完成之后,生成视图之前执行 19 | public void postHandle(HttpServletRequest request, HttpServletResponse response, 20 | Object handler, ModelAndView modelAndView) throws Exception { 21 | System.out.println("postHandle"); 22 | } 23 | 24 | // 在 DispatcherServlet 完全处理完请求之后被调用 25 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 26 | Object handler, Exception ex) throws Exception { 27 | System.out.println("afterCompletion"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /springlearning/src/main/java/com/learning/pojo/PersonDTO.java: -------------------------------------------------------------------------------- 1 | package com.learning.pojo; 2 | 3 | import javax.validation.constraints.Min; 4 | import javax.validation.constraints.NotNull; 5 | 6 | public class PersonDTO { 7 | 8 | @NotNull(message = "姓名不能为空") 9 | private String name; 10 | 11 | @Min(value = 18,message = "年龄不能低于18岁") 12 | private int age; 13 | 14 | public String getName() { 15 | return name; 16 | } 17 | 18 | public void setName(String name) { 19 | this.name = name; 20 | } 21 | 22 | public int getAge() { 23 | return age; 24 | } 25 | 26 | public void setAge(int age) { 27 | this.age = age; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /springlearning/src/main/resource/spring-mvc.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /springlearning/src/main/webapp/WEB-INF/views/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | 3 | 4 |

${message}

5 |
6 | 名称:
7 | 年龄:
8 | 9 |
10 | 11 | 12 | -------------------------------------------------------------------------------- /springlearning/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | springservlet 9 | org.springframework.web.servlet.DispatcherServlet 10 | 11 | contextConfigLocation 12 | classpath:spring-mvc.xml 13 | 14 | 1 15 | 16 | 17 | springservlet 18 | / 19 | 20 | 21 | 22 | encodingFilter 23 | org.springframework.web.filter.CharacterEncodingFilter 24 | 25 | encoding 26 | UTF-8 27 | 28 | 29 | 30 | encodingFilter 31 | /* 32 | 33 | --------------------------------------------------------------------------------