当前位置: 首页 > news >正文

邪修实战系列(1)


1、第一阶段邪修实战总览(9.1-9.30)

把第一阶段(基础夯实期)的学习计划拆解成极具操作性的每日行动方案。这个计划充分利用我“在职学习”的特殊优势,强调“用输出倒逼输入”,确保每一分钟的学习都直接服务于面试和实战。

  • 核心目标:构建起Java后端开发的知识树主干,并能通过一个小型项目串联起所有知识点。
  • 核心策略:每天3小时雷打不动的高效学习(工作日可分散,周末集中攻坚)。

2、周目标(9.1-9.14)

Java核心+Sprig Boot破冰,能独立使用Spring搭建Web后端并提供RESTful接口。


3、分日目标与邪修技巧

3.1、Day 9.1-9.2: Java基础(变量、循环、条件分支、字符串操作)

  • 行动:安装JDK、IDE(IntelliJ IDEA),配置好环境。在菜鸟教程中学Java的变量、循环、条件分支、字符串操作这几个板块的内容,并用IDEA写一个简单的控制台程序,我这里做了一个类似的程序叫"Data_Board",这是一个用Java编写的广告数据展示程序,采用面向对象设计思想重构,能够从Excel文件读取广告数据,展示广告花费、线索数量等关键指标,并提供多日期数据对比分析功能。程序支持数据自动计算(单个线索成本、私信转化成本)和趋势分析,具备良好的可扩展性和维护性。
  • 邪修技巧:可以用TREA写项目的README,定时更新一下,这样后期我们面试之前可以仔细看看自己项目的编写流程。
  • 学习分享:这一阶段的下载安装就先不跟大家分享了,没有那么多时间写哈哈哈,如果大家有疑问想了解可以私聊我哈~这几天的程序我会综合在day5-day6中分享出来。

3.2、Day 9.3-9.4: Java面向对象(类、对象、继承、多态、接口)

  • 行动:在菜鸟教程中学Java的类、对象、继承、多态、接口这几个板块的内容,将前两天的"Data_Board"改造成面向对象风格。定义AdCampaign类,包含名称、花费、收入等属性,并封装计算方法。
  • 邪修技巧:思考为公司写的那个程序,如果用OOP思想重构,该怎么设计?把这个思考过程写在代码注释里,面试时可以聊。

3.3、Day 9.5-9.6: Java集合框架(List, Map, Set)和IO操作

  • 行动:在菜鸟教程中学Java的List、Map、Set和IO操作这几个板块的内容,编写程序从Excel文件(模拟数据源)读取广告数据,存入ArrayList或HashMap,并进行统计计算。
  • 邪修技巧:这是面试重点。每学一个集合类,就去查一下它的底层实现(比如HashMap是数组+链表/红黑树),记下一两句源码分析,面试时抛出来是巨大加分项。

3.3.1、学习分享

  • 根据前几天所学,制作了一个采用面向对象设计思想重构,能够从Excel文件读取广告数据,展示广告花费、线索数量等关键指标,并提供多日期数据对比分析功能。程序支持数据自动计算(单个线索成本、私信转化成本)和趋势分析,具备良好的可扩展性和维护性。我把具体的代码和README文档放到了github里,点击链接进入Data_Board-README文档可以查看、下载并学习。
  • 由于本人也是第一次正式使用Github来管理自己的代码,以前总是自己存储,所以现在也是仔细学了一下。给大家推荐几个博客,大家如果想仔细学一下Github的话可以借鉴一下:
    • Github入门教程,适合新手学习(非常详细),这个博客的内容比较全面,有对GitHub和Git的介绍以及使用教程,唯一缺点是比较长,适合静下心来仔细查看。
    • 【2025版】最新GitHub新手用法详解(适合新手入门)零基础入门到精通,收藏这篇就够了_github使用详解,相较于上一篇博客,针对于Github和Git的讲解少一点,但是基础使用都是有的,赶进度可以试试。
    • 如何解决:ssh: connect to host github.com port 22: Connection refused,这篇文档解决了本地机器尝试通过 SSH 协议连接 GitHub 的 22 端口时,连接被拒绝了的问题,如果你看不懂这个问题,你就切记当你碰到ssh: connect to host github.com port 22: Connection refused时,来找这个博客就行啦,别整什么防火墙、服务器之类的,就是个简单的端口问题,跟着这个博客一步步解决即可。

3.3.2、集合类分析思考

ArrayList:
  • 底层实现:基于动态数组(transient Object[] elementData),默认初始容量10,支持自动扩容。
  • 扩容机制:当添加元素导致不足时,通过grow()方法扩容,新容量为oldCapacity + (oldCapacity >>1)(即1.5倍),使用Array.copyof()复制数组元素。
    • oldCapacity + (oldCapacity >>1)是ArrayList扩容时计算“新容量”的核心公式,作用是把当前容量扩大到原来的1.5倍。
    • >> 是 Java 里的 “右移运算符”,简单说就是 把一个数在二进制里往右挪几位,效果相当于 “除以 2 的 n 次方”(n 是右移的位数)。这里用的是 oldCapacity >> 1(右移 1 位),效果就等于 oldCapacity ÷ 2(只取整数部分)。
  • 关键代码:
// 添加元素时的扩容判断
ensureCapacityInternal(size + 1);  // 确保容量足够:检查一下,现在的够不够再放 1 个新元素
elementData[size++] = e;  // 直接在数组末尾赋值:添加新元素,并记录现在的大小
// 代码分析:
// 先确认有地方放新元素(不够就扩容),然后把元素放到最后一个空位置,再更新已有的元素数量。
// ensureCapacityInternal(...):这是个 “检查容量” 的工具方法,它会做两件事:1、看看当前elementData的长度(也就是 “总抽屉数”)够不够装size + 1个元素。2、如果够(比如总抽屉数 10,要放第 10 个),就啥也不做,直接下一步;如果不够(比如总抽屉数 10,要放第 11 个),就触发 “扩容”(把抽屉数变成 15),然后再下一步。
// elementData[size] = e:往 “元素数组” 的第size个位置放新元素。因为size是 “当前已有的数量”,所以第size个位置正好是 “下一个空位置”。比如现在有 3 个元素(size=3),空位置就在索引 3 的位置,直接把新元素放进去。size++:放完之后,“已有的数量” 要加 1(比如原来 3 个,现在变成 4 个)。
LinkedList:
  • 底层实现:基于双向链表,每个节点(Node)包含prev(前驱)、next(后继)指针和实际元素item。
  • 源码关键分析:插入 / 删除效率高(无需移动元素),查询需遍历。
// 节点结构定义
private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}
}
// 添加到尾部:直接修改尾节点的next指针
void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null) first = newNode;else l.next = newNode;size++;
}
HashMap
  • 底层实现:基于数组 + 链表 + 红黑树,数组(Node<K,V>[] table)是主体,链表用于解决哈希冲突,当链表长度 > 8 且数组容量≥64 时转为红黑树。
    • 数组+链表+红黑树的底层核心结构可以想象成一个带编号的多层货架:
    • 第一层:数组(哈希表,Node<K,V>[] table)。这是最基础的“大格子”,每个格子有唯一编号(索引),默认初始容量是16(必须是2的幂次,比如16、32、64…)。每个格子里可以放“链条”或“小数”。
    • 第二层:链表(解决哈希冲突)。当多个“商品”(key-value)计算后落到同一个“大格子”里时,会像串珠子一样练成链表(每个节点Node有next指针,指向后一个节点)。
    • 第三层:红黑树(优化长链表查询)。当一个格子里的链表太长(默认超过8个节点),且整个货架的大格子数量>=64时,链表会自动转成红黑树(一种平衡二叉树)。树的查询效率比长链表高很多(从O(n)降到O(logn))。
  • 哈希计算:通过(key.hashCode() ^ (key.hashCode() >>> 16))扰动哈希值,再用(n-1) & hash计算数组索引(n 为数组容量)。
  • 哈希冲突:也叫哈希碰撞,是哈希表(如 HashMap)在存储数据时必然可能遇到的问题。根本原因是哈希函数的 “输出范围”(数组索引的数量)是有限的,但 “输入范围”(可能的 key 数量)是无限的。比如数组长度只有 16(索引 0~15),但可能的 key 可以是 “苹果”“橙子”“西瓜”…… 无数个,有限的索引必然会被无限的 key “重复占用”,冲突无法完全避免,只能尽量减少。
  • 扩容机制:容量为 2 的幂次,扩容时通过resize()方法将元素重新哈希分配,红黑树可能拆分为链表。
  • 关键代码:
// 计算哈希值(减少碰撞)
static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// 树化判断(JDK 1.8新增)
if (binCount >= TREEIFY_THRESHOLD - 1) // TREEIFY_THRESHOLD = 8treeifyBin(tab, hash);
HashSet
  • 底层实现:基于HashMap,元素存储在HashMap的key中,value固定为一个静态常量(PRESENT = new object()).
  • 特点:无序、不可重复,依赖HashMap的key去重(通过hashCode()和equals()判断)。
    • 无序:元素的存储顺序不固定,因为HashMap的key是无序的;
    • 去重:依赖HashMap的key不重复(靠hashCode()和equals()判断);
    • 线程不安全:和HashMap一样,多线程操作可能出问题;
    • 查询/增删效率高:平均时间复杂度是O(1),因为HashMap的核心操作效率高。
  • HashSet里,不同元素可能算出相同哈希值(比如“苹果”和“橙子”哈希值都是123),这是必须要再用equals()确认“到底是不是真的相同”,避免把“不同元素误判为重复”。必须同时满足两个条件:
    • a.hashCode() == b.hashCode():两个元素的哈希值相等(哈希值是元素的“数字身份证”,由hashCode()方法计算);
    • a.equals(b) == true:两个元素通过equals()方法比较,结果为“相等”。
  • 关键代码:
// 添加元素实际调用HashMap的put()
public boolean add(E e) {return map.put(e, PRESENT) == null;  // 若key不存在则添加,返回true
}
// HashMap 的 put 方法有个规则:如果 key 不存在,就新增 key-value,返回 null;如果 key 已存在,就覆盖 value,返回 “旧的 value”;
//所以 HashSet 的 add 方法:如果返回 true,说明 “元素是新的,添加成功”;如果返回 false,说明 “元素已存在,添加失败”—— 这就实现了 “去重”。

总结

  • ArrayList 添加元素时,会先通过 ensureCapacityInternal 检查容量够不够,不够就扩容;够的话直接把元素放到数组的末尾(elementData [size] 的位置),然后把元素数量 size 加 1。
  • LinkedList 底层是双向链表,每个节点存前后指针和元素。增删快(改指针即可,不用挪元素),查询慢(得从头 / 尾遍历)。适合频繁增删、少查询的场景,和 ArrayList(数组,查快增删慢)互补。
  • HashMap 靠 “数组 + 链表 + 红黑树” 的结构,结合哈希计算和动态扩容,实现了高效的键值对存储。核心特点是:查询、增删效率高(平均 O (1)),key 不重复(依赖hashCode()和equals()),线程不安全,适合频繁查询和修改的场景。
  • HashSet底层基于 HashMap 实现,把要存的元素作为 HashMap 的 key,用一个固定对象当 value,借 HashMap 的 key 去重特性实现自己的功能,特点是无序、不重复、效率高。


文章转载自:

http://qMawZ2Rd.xzrbd.cn
http://gvtqwUkM.xzrbd.cn
http://Li4z2P7g.xzrbd.cn
http://6DkE6KnV.xzrbd.cn
http://gq8XmJ7R.xzrbd.cn
http://PqWw5aNA.xzrbd.cn
http://L7u0Hxbw.xzrbd.cn
http://i6ubl0uG.xzrbd.cn
http://zxvshzvb.xzrbd.cn
http://33GeN6zU.xzrbd.cn
http://cb3H46vs.xzrbd.cn
http://1NLCMWl2.xzrbd.cn
http://t2Ksk7U6.xzrbd.cn
http://sYSIMxlG.xzrbd.cn
http://LWRR6NX3.xzrbd.cn
http://QZKES8o6.xzrbd.cn
http://JtuWg2Je.xzrbd.cn
http://1AMBsKRM.xzrbd.cn
http://spoS5xnX.xzrbd.cn
http://Atsxodg8.xzrbd.cn
http://SPPMIvND.xzrbd.cn
http://Rg2kFRVO.xzrbd.cn
http://f1ldb0UO.xzrbd.cn
http://Dl2VYkHB.xzrbd.cn
http://UxgQwAkb.xzrbd.cn
http://zuTikJk5.xzrbd.cn
http://vhf38kTD.xzrbd.cn
http://dZmLgVTK.xzrbd.cn
http://VYpSBnqP.xzrbd.cn
http://ZL8XQGJa.xzrbd.cn
http://www.dtcms.com/a/369557.html

相关文章:

  • 今日行情明日机会——20250905
  • MCP(Model Context Protocol)与大模型一起运用
  • 【Lin通信】AUTOSAR架构下TC3xx芯片Lin报文收发详解
  • SDRAM详细分析—06 存储单元架构和放大器
  • stm32——NVIC,EXIT
  • Leetcode每日一练--20
  • 关机之前未正确关闭代理,导致DNS出现问题无法上网的解决方法(windows和linux)
  • Linux查看设备树信息
  • *MOS 半导体功率器件简介 | 结构 / 制程 / 简史
  • @Autowired注解(二)
  • Linux基础指令(入门必备2.0)
  • 打工人日报#20250905
  • 【Leetcode】高频SQL基础题--610.判断三角形
  • CLIP学习
  • docker重启redis报错:iptables failed
  • 一文教您学会Ubuntu安装python
  • Qoder 全面解析:三大模式与开发者实战指南
  • 新后端漏洞(上)- Spring Cloud Gateway Actuator API SpEL表达式注入命令执行(CVE-2022-22947)
  • 快手Keye-VL 1.5开源128K上下文+0.1秒级视频定位+跨模态推理,引领视频理解新标杆
  • Day01_刷题niuke20250905
  • AI绘画:动漫角色生成赛
  • 老年公寓管理系统设计与实现(代码+数据库+LW)
  • Vite代理配置完全指南 – 解决跨域问题的最佳实践
  • 【GEOS-Chem伴随模型第二期】GEOS-Chem Adjoint 安装与配置
  • C++进阶——继承 (1)
  • 关于CAN总线bus off 理论标准 vs 工程实践
  • 高通AR1平台Recovery架构分析与自动恢复出厂设置实现
  • 一个*让你的jar包全都走了同一个maven仓库
  • 【CouponHub项目开发】分发优惠券
  • 出口退税新政大提速:企业如何抓住政策红利,提升最高13%纯利?