
1. 学习路线与目标规划第十天的自我审视坚持到第十天说实话已经淘汰了一大批人了。我身边同期开始学Java的朋友有的倒在环境配置有的倒在面向对象还有的学着学着就去打游戏了。能点开这篇内容的你至少说明还在坚持这就比很多人强了。第十天是个微妙的节点。按市面上主流的学习路线前十天基本覆盖了Java基础语法的前半程环境搭建、数据类型、运算符、流程控制、数组、方法、面向对象入门。如果你是从零开始的现在应该能写一些简单的控制台小程序了比如计算器、猜数字、学生成绩管理这类。如果这些还写不顺建议先别急着往后冲把前九天的内容复习一遍再来看今天的内容。我今天想换个思路不按教科书顺序讲新语法。第十天更应该做三件事第一把前九天学的知识串成一条线搞清楚它们之间的逻辑关系第二把环境配置和常见报错彻底踩平别让工具问题拖后腿第三用一个小项目把零散的知识点粘合起来。说白了第十天是第一个“复盘日”不是“冲进度日”。先看看网上那些热搜词Java面试题、Java数据类型、冒泡排序、环境配置、启动失败、内存溢出这些恰恰是初学者最容易被卡住的地方。我把它们拆解了一下发现可以归结为三类问题知识没串联、工具不会用、代码量不够。今天这篇就围绕这三个痛点展开每一部分都会给出我实测过的方案和踩坑记录。另外提一句学习节奏的建议每天保证两到三小时的有效学习时间比周末突击八小时强得多。编程这东西讲究手感手感是靠日积月累练出来的不是靠某一天的爆发。我见过太多人周一学到凌晨两点然后歇三天再学又是从零开始。保持节奏比追求单日时长重要十倍。1.1 前九天知识点的串联方式前九天学的散知识点其实可以这样串Java代码从编写到运行本质上是“源文件 → 字节码 → 机器执行”的过程。围绕这个过程你写的每一行代码都逃不开三个层面的问题——语法层面能不能编译通过、逻辑层面运行结果对不对、设计层面代码结构好不好。从语法层面看你学过的数据类型、运算符、流程控制、数组这些都是“砖块”。从逻辑层面看你学过的分支、循环、方法调用这些是“水泥”。从设计层面看你刚开始接触的类与对象、封装、继承这些是“图纸”。第十天的复习就是把你手里的砖块、水泥和图纸拼成一面墙。建议你做一个复习动作拿出一张白纸不翻书画出Java基础语法的思维导图从“数据类型”开始延伸出基本类型和引用类型再从引用类型延伸到数组和String再从String延伸到常用API……画不出来的地方就是你的薄弱环节重点补。1.2 面向对象编程的真正含义很多初学者学面向对象死记硬背“封装继承多态”六个字但根本不知道这东西解决什么问题。我打一个比方面向过程编程就像你开一家小饭馆从买菜、洗菜、切菜、炒菜到上菜全是你一个人干菜量一大必乱。面向对象编程就像你开一家连锁餐厅每个岗位各司其职后厨只管做菜前台只管接单采购只管进货。Java里的类就是“岗位说明书”对象就是“具体干活的员工”方法就是“工作流程”。你定义一个Student类里面有姓名、年龄属性有study方法这就相当于你给“学生”这个岗位写了份说明书。当你new出一个Student对象时就是招了一个叫张三的具体学生。张三能学习李四也能学习但他们各自的姓名年龄互不干扰。面试的时候被问到“什么是面向对象”别背课本上那句“一切皆对象”。你要能说出这样的理解面向对象的核心是把数据和对数据的操作绑定在一起通过类来抽象现实事物通过对象来具体化通过消息传递方法调用来协作完成功能。这个理解水平已经超过八成应届生了。2. 环境配置与工具链把坑填平才能跑得远环境配置是Java入门第一道坎也是劝退率最高的一关。我见过太多人在群里问“java环境变量怎么配置”“为什么java命令不识别”这些问题如果你还在问说明基础还没打牢。第十天必须把这个环节彻底搞定不然后面学框架的时候每装一个新工具就崩一次心态直接炸。先梳理一下你需要装的东西JDKJava开发工具包是必须的IDE集成开发环境推荐IntelliJ IDEA构建工具Maven属于进阶配置但强烈建议提前装数据库工具如MySQL、Navicat后面学JDBC会用到。这一套下来你的开发环境才算基本齐活。2.1 JDK多版本共存与切换方案热搜词里有“java环境变量使用多个jdk”这个问题很多人都会遇到。比如你一边学Java 8企业用的最多一边想体验Java 17的新特性两个JDK装在同一台机器上环境变量怎么配关键在于PATH和JAVA_HOME的配合。最稳妥的做法是先装两个版本的JDK比如安装到C:\Program Files\Java\jdk-8和C:\Program Files\Java\jdk-17。然后设置JAVA_HOME指向你当前需要使用的那个版本PATH里面加上%JAVA_HOME%\bin。切换的时候只需要改JAVA_HOME这一个变量值然后重新打开命令行窗口。你可以写一个简单的bat脚本放在桌面切换JDK版本时双击运行即可。脚本内容大致是setx JAVA_HOME C:\Program Files\Java\jdk-17然后用setx Path把新的%JAVA_HOME%\bin追加进去。注意setx会覆盖原有Path操作前一定要先备份原Path。我吃过这个亏曾经因为setx操作把系统Path搞坏了连cmd都打不开只能进安全模式修复血泪教训。验证是否切换成功命令行输入java -version看输出的版本号是否对应你想要的那个。如果没变八成是没重开命令行窗口Windows的环境变量缓存很坑。2.2 启动失败与内存溢出的排查思路“java启动失败怎么解决”“OutOfMemoryError”这两个问题在热搜词里出现频率很高而且初学者一遇到就慌。其实这类问题的排查思路是有固定套路的。第一步看报错信息开头的关键词。如果是Unrecognized option说明JVM参数写错了比如-XX:MaxPermSize在Java 8以后已经不支持要换成-XX:MaxMetaspaceSize。如果是Could not reserve enough space for object heap说明你给定的堆内存超过了机器可用内存——典型场景是32位系统上给JVM分配超过1.5G堆内存。如果是OutOfMemoryError: Java heap space说明堆内存真的不够用了需要加-Xmx参数。第二步确认你的机器架构和IDE位数。有些老机器装的是32位JDK而IDE是64位的那IDE启动时调用的JVM就是32位堆内存上限很小。这时候你需要把JDK升级为64位版本或者降低IDE的-Xmx配置。IDEA的配置文件在安装目录bin\idea64.exe.vmoptions里面-Xmx2048m表示最大堆内存改完后重启IDEA生效。注意修改vmoptions文件时一定要用记事本或VS Code打开不要用IDEA自带的编辑器。我曾经手滑把文件编码改成了UTF-8带BOM导致IDEA直接无法启动排查了半天才发现是编码问题。至于热搜词里的“进程堆大小调整为8000还是报错”这个很典型。堆内存调到8G还报OOM说明程序本身就有内存泄漏或超大对象引用问题不是堆不够大的事。加内存只是治标不治本真正要做的是用VisualVM或JProfiler分析堆转储文件找到是哪个对象占用了大量内存再定位到代码层面。后续我会专门写一篇OOM分析实战这里先立个Flag。2.3 IDEA编译报错的几种典型场景用IDEA写代码最常见的报错编译时报java: 程序包xxx不存在多半是Maven依赖没下载完整。解决办法是右键项目 - Maven - Reload Project让IDEA重新解析依赖。如果还不行检查本地仓库~/.m2/repository下对应的jar包是否损坏损坏了直接删掉该目录Maven会自动重新下载。另一种是编译时报Error: java: Compilation failed: internal java compiler error通常是Project SDK和Project language level不匹配。比如你装了JDK 17但Project language level还在8某些语法会编译失败。检查路径是File - Project Structure - Project把SDK正确设置为17language level也同步调整为17。小结一个经验环境问题的排查顺序永远是“先确认JDK版本 → 再确认环境变量 → 再确认IDE配置 → 最后才怀疑代码”。不要一上来就怀疑自己代码写错了环境问题在Java学习初期占比高达70%。3. 核心基础巩固数据类型、标识符与排序算法实战基础不牢地动山摇。今天既然做复盘就把几个容易卡壳的硬骨头单独拎出来啃。热搜词里的“java数据类型”“java标识符命名规则”“冒泡排序java”“sort函数用法java”我串成一块来讲。3.1 数据类型的内存模型与面试高频题Java的两大数据类型阵营——基本类型和引用类型表面上是“存值”和“存地址”的区别但面试官喜欢往深处挖。比如int和Integer的区别比较的是什么这些几乎是必考题。基本类型有八种byte、short、int、long、float、double、char、boolean。它们的核心区别在于占用内存空间不同byte占1字节short占2字节int占4字节long占8字节。float和double的区别同理4字节对8字节精度完全不同。面试中一个高频陷阱题是float a 1.0;这行代码其实是错的因为1.0默认是double类型直接赋值给float需要强转正确写法是float a 1.0f。引用类型包括类、接口、数组、枚举。它们变量本身存的是堆内存中的地址也就是引用。用比较两个引用类型变量比较的是地址是否相同用equals比较的才是内容是否相同。但有个细节String类重写了equals方法所以abc.equals(abc)返回true而Integer缓存了-128到127的值这个范围内的Integer a 100; Integer b 100;用比较返回true超过范围就返回false。这些细节不亲手敲一遍面试被问住再正常不过。3.2 标识符命名规则与规范标识符这块内容看似简单但很多人考试和面试都会在这里翻车。规则层面有四条铁律不能以数字开头不能是Java关键字严格区分大小写不能包含空格。123abc是非法的class是非法的int也是非法的它是关键字。规范层面则完全是另一码事。类名用大驼峰比如StudentManager方法名和变量名用小驼峰比如studentName、getStudentById常量全大写加下划线比如MAX_SIZE。这些规范不是Java语法强制要求的但如果不遵守团队协作时代码就是一锅粥。我在公司review过新人的代码变量名从a到z用了二十几个看完只想让他重新写一版。还有个容易被忽略的点$符号和中文都可以作为标识符。$在特殊场景如内部类、动态代理生成的类名有用途日常不建议用。中文可以做变量名Java语法允许但代码可读性极差强烈不建议。3.3 冒泡排序与sort函数的正确姿势排序是算法基础中的基础也是面试手撕代码环节的常客。这里必须分清两个场景面试考的是你手写算法思路工作中用的是现成工具方法。冒泡排序的核心思想是相邻元素两两比较大的往后冒。但很多人写出来的版本效率很差问题出在内层循环的范围。标准写法是这样的public static void bubbleSort(int[] arr) { int n arr.length; for (int i 0; i n - 1; i) { boolean swapped false; for (int j 0; j n - 1 - i; j) { if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; swapped true; } } if (!swapped) { break; } } }这里有个优化点j n - 1 - i每一轮冒泡后最大的数已经沉到末尾所以内层循环范围可以逐渐缩小。swapped标志位用于判断某一轮是否发生过交换如果一整轮都没有交换说明数组已经有序直接跳出循环这是最基础的优化。工作中别自己写排序直接用Arrays工具类。Arrays.sort(int[])底层用的是Dual-Pivot Quicksort对于引用类型用的是TimSort性能远比自己写的冒泡好得多。Arrays.sort(arr, 2, 5)可以对数组的指定区间排序。如果要对对象排序需要对象实现Comparable接口或者传入ComparatorListStudent students new ArrayList(); students.sort(Comparator.comparing(Student::getScore).reversed());一行搞定按成绩降序排序比手写排序逻辑省太多事。搜索引擎里有“sort函数用法java”说明很多人不清楚这一点。其实JDK的Arrays和Collections类里藏着大量实用方法多去看看官方文档比网上搜零散博客高效得多。对一个初学者而言手写冒泡排序主要是为了理解嵌套循环和数组操作不是为了让你工作中用。明白这一点你就不会在“要不要背排序算法”这件事上纠结了。4. 实战项目用MyBatis-Plus根据实体类生成建表SQL第十天最好的巩固方式是做一个能跑通的小项目。我从热搜词里挑一个非常实用的场景来演示——mybatisplus根据java实体类生成创建表的sql语句。这个需求在真实开发中极其常见尤其是团队里数据库表结构由后端Java工程师维护时用实体类反推建表SQL能省不少事。这不是让你现在就精通MyBatis-Plus而是告诉你一个思路ORM框架的核心价值就是让Java对象和数据库表之间建立映射关系。理解了这个思路后面学Spring Boot时会轻松很多。4.1 项目搭建与依赖配置先创建一个Maven工程在pom.xml中加入MyBatis-Plus和MySQL驱动依赖。Spring Boot项目的话引入mybatis-plus-boot-starter即可。这里给一个最小依赖示例dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency接着在application.yml中配置数据源信息。如果你本地的MySQL端口、用户名密码与我不同改成你自己的即可。这一步骤同时也是在复习JDBC的内容因为MyBatis-Plus底层就是封装了JDBC。建一个实体类User加上MyBatis-Plus的注解Data TableName(user) public class User { TableId(type IdType.AUTO) private Long id; private String username; private String email; TableField(fill FieldFill.INSERT) private LocalDateTime createTime; }这里的TableName(user)指定表名TableId指定主键TableField标注特殊字段。有了这个实体类MyBatis-Plus就能自动帮你生成对应的SQL语句。4.2 自动建表的两种实现路径第一种路路径是用MyBatis-Plus的扩展模块在配置类里定义一个MybatisPlusSqlInjector或者直接用BaseMapper提供的insert方法。第二种路径是写一个工具类利用Java反射读取实体类的字段和注解动态拼接CREATE TABLE语句。第二种路径的理解层面更值得学习因为它强迫你思考Java反射和注解的本质。核心逻辑三步走获取实体类的Class对象遍历声明字段读取注解信息把Java类型映射为MySQL类型。Java里String对应MySQL的VARCHAR(255)Integer对应INTLong对应BIGINTLocalDateTime对应DATETIME。类型映射这块有个大坑如果不指定长度VARCHAR字段在MySQL里默认是VARCHAR(255)对于用户名可能够用但如果存文章内容就完全不合适。所以更合理的做法是给实体类加一个自定义注解指定长度但很多初学者不知道MyBatis-Plus本身不提供长度注解。业界常用的方案是直接引入Flyway或Liquibase这类数据库迁移工具把建表脚本纳入版本管理。自动建表工具适合开发环境快速起项目生产环境千万别让代码自动建表风险太大。生产环境的表结构变更必须走审核流程用迁移脚本逐版本升级这个习惯要一开始就养成。我自己的体验是自动建表最舒服的场景是写Demo和学习阶段。想快速起一个功能验证环境不用手动去Navicat里敲建表语句代码一跑表就出来了整个节奏快了很多倍。4.3 从实体到SQL的完整代码示例既然提到反射动态生成SQL我手写过一个极简版本核心代码贴出来供参考public static String generateCreateTableSql(Class? clazz) { TableName tableNameAnno clazz.getAnnotation(TableName.class); String tableName tableNameAnno.value(); StringBuilder sb new StringBuilder(CREATE TABLE ) .append(tableName).append( (); Field[] fields clazz.getDeclaredFields(); for (Field field : fields) { String columnName camelToUnderscore(field.getName()); Class? type field.getType(); String columnType mapJavaTypeToMySql(type); sb.append(\n ).append(columnName).append( ) .append(columnType).append(,); } sb.deleteCharAt(sb.length() - 1); sb.append(\n) ENGINEInnoDB DEFAULT CHARSETutf8mb4;); return sb.toString(); }其中camelToUnderscore方法实现驼峰转下划线mapJavaTypeToMySql实现Java类型到MySQL类型的映射。这里用到了反射里的getDeclaredFields()获取所有字段用getAnnotation()读取注解用getType()获取字段类型。反射这块知识不是十天能学完的但你只要记住方向——反射就是Java在运行期“照镜子”看自己结构的能力后面哪天需要了再深入。这个例子把面向对象、注解、反射、字符串拼接、命名规则、类型映射全串起来了正适合第十天的复盘需求。它能做一个独立的小工具类以后写代码时随时调用。5. 常见问题排查实录这几天高频踩坑的复盘最后一部分我把这段时间在学习过程中收集到的常见问题整理成一份速查表从环境到代码再到工程实践列出问题表现、排查路径、解决方案和我的个人备注。问题典型表现排查路径解决方案java命令不可用命令行输入java报“不是内部或外部命令”检查JAVA_HOME和PATH将JDK的bin目录加入PATH重开命令行编译编码报错含有中文的文件编译后乱码或报错检查源文件编码设为UTF-8编译时加-encoding UTF-8Maven依赖下载失败依赖标红编译报包不存在检查网络与本地仓库Maven Reload Project删除损坏的仓库缓存堆内存溢出运行时报OutOfMemoryError用jstat/VisualVM观察优化代码合理设置-Xmx分析堆转储端口被占用启动时报BindException查询端口占用netstat -ano找到PID结束进程或换端口数据库中文乱码插入中文变为问号检查连接URL和表字符集URL加characterEncodingutf8建库时指定utf8mb4下面挑几个典型的细说。5.1 JAVA_HOME设了却仍然不生效这个问题搜“java环境变量使用多个jdk”的人大概率都遇到过。系统变量里明明配置了JAVA_HOMEPATH里也加了%JAVA_HOME%\bin但命令行一执行java -version还是旧版本或者直接报错。最常见的坑有两处。第一PATH里可能有其他地方也写了Java的bin路径且排在%JAVA_HOME%\bin前面系统是按顺序查找的前面的优先匹配了。第二Windows的PATH变量在“系统变量”和“用户变量”里都有用户变量的优先级高于系统变量如果你在用户变量里配了一份旧JDK路径系统变量的配置会被它覆盖。排查方法是命令行输入where javaWindows会列出所有找到的java.exe的位置和顺序一眼就能看出问题出在哪。然后逐一清理旧配置只保留一份%JAVA_HOME%\bin。5.2 MyBatis-Plus自动建表失败用MyBatis-Plus测试自动建表时最常见的报错是“Table xxx doesnt exist”或者“Unknown column”。这通常不是工具的问题而是你的实体类字段与数据表字段映射不一致。例如实体里有createTime但表里的列名是create_timeMyBatis-Plus默认开启了驼峰转下划线映射如果关掉了这个配置就会报错。另一个容易被忽略的点是配置项logic-delete-value和logic-not-delete-value当你给实体类加了TableLogic注解实现逻辑删除时如果数据库表里没有对应的delete_flag列所有查询都会报错。解决办法是先手动在表里加上该列或者把注解暂时去掉。5.3 排序结果与预期不符写排序代码时结果老是不对绝大多数情况是边界条件没处理好。比如冒泡排序外层循环多循环了一次或者内层循环的范围写成j arr.length - 1 - i但数组下标从0开始导致最后一位没参与比较。排查这类问题没有捷径只能靠两种手段一是写单元测试给定小规模输入断言输出结果二是在循环体里加打印语句观察每轮排序后数组的变化。IntelliJ IDEA的Debugger也支持条件断点可以在if (arr[j] arr[j1])处打断点逐步观察变量变化。学会用Debugger比学会任何框架都重要这个技能能帮你省下大量时间。5.4 常用库函数与工具类的使用盲区热搜词里提到“常用库函数algorithm java”这里要特别纠正一个概念C有STL algorithm库Java里没有一个叫algorithm的库。Java对应的工具类主要分布在java.util和java.lang里面。Arrays类提供了排序、二分查找、复制、填充、转List等方法Collections类专门操作Collection接口的集合。还有Objects类提供空指针检查和hashCode计算Math类提供幂运算、绝对值、随机数等。我见过不少初学者自己写循环找最大值其实Collections.max(list)一行就搞定了。JDK的官方文档是最好的工具类手册遇到需求先想想“这个功能JDK是不是已经帮我做好了”养成查文档的习惯能少写很多无用代码。6. 写在第十天的最后我的学习建议第十天是一个容易浮躁的时间点。坚持了十天你可能会觉得自己应该“会点什么了”但真让你独立写个功能又觉得无从下手。这种感觉很正常说明你正在从“听懂”向“会用”过渡这个过渡期急不来。我的建议是从今天开始换一种学习方式不再按章节顺序往后学而是给自己定一个小任务比如“做一个命令行版的学生成绩管理系统”把前面学的知识全部用上。遇到不会的知识点查资料现学现用。这种以任务驱动的方式效率远高于纯啃书本——你在完成任务过程中记住的知识比你看十遍书都牢固。之前遇到一个朋友向我请教Java自学路线我给他推荐“基础语法 → 面向对象 → 集合框架 → IO → 多线程 → 网络编程 → 数据库 → 框架”这条经典路线。但学了半个月后他反馈说太枯燥坚持不下去。后来我换了个思路让他直接做一个贪吃蛇小游戏用Java Swing做界面一边做一边补知识他反而学得飞快。所以当你感到烦躁时不用怀疑是自己不适合很可能只是学习方式不匹配。第十天的复盘到这里就差不多了。下一篇我打算聊一聊集合框架这是Java学习中承上启下的关键章节也是面试必考的重头戏。先把今天的内容消化掉哪怕只是把文中的代码自己敲一遍也算没白看。