Java的基础知识

Java的基础知识

目录

== 和 equals() 的区别

hashCode() 有什么用?

重写equals为什么要重写hashcode?

为什么用BigDecimal不用float/double计算出现什么问题?

自动装箱与拆箱

深拷贝和浅拷贝区别?什么是引用拷贝

面向对象的三大特征

面向对象和面向过程的区别

String的不可变性

String s1 = new String("abc");创建了几个对象?

String和StringBuffer和StringBuilder区别

字符串拼接用“+” 还是 StringBuilder?

字符串常量池的作用了解吗?


== 和 equals() 的区别

== 对于基本类型和引用类型的作用效果是不同的:

对于基本数据类型来说,== 比较的是值

对于引用数据类型来说,== 比较的是对象的内存地址

equals() 方法存在两种使用情况:

类没有重写 equals() 方法 :通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是 Object 类equals()方法。

类重写了 equals() 方法 :一般我们都重写 equals()方法来比 较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。

String 中的 equals 方法是被重写过的,因为 Object 的 equals方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。

hashCode() 有什么用?

hashCode() 的作用是获取哈希值。这个哈希值的作用是确定该对象在哈希表中的索引位置 (可以快速找到所需要的对象)

Java用hashcode()和equals()判断是否为同一个对象

如果两个对象的hashCode 值相等,那这两个对象不一定相等(哈希碰撞)。

如果两个对象的hashCode 值相等并且equals()方法也返回 true,我们才认为这两个对象相等

如果两个对象的hashCode 值不相等,我们就可以直接认为这两个对象不相等。

重写equals为什么要重写hashcode?

因为java判断两个对象是否是相等的, 需要先比较hashcode是否一致, 如果hashcode不一致那么就认为不相等.

如果没有重写hashcode, 那么两个相等的对象由于hashcode不相等, 就会被认为是不相等的. 但是按照重写的equals规则, 他们应该是相等的.

在集合中, 如set集合去重中就会出现, 两个相等的对象放到set中都可以存在的怪象.

为什么用BigDecimal不用float/double计算出现什么问题?

double会出现精度丢失的问题

计算机无法精确地表示小数, 所以做浮点数计算时会出现精度丢失问题.

BigDecimal底层是用字符串存储数字, 运算也是用字符串做加减乘除计算的, 所以它能做到精确计算. 所以一般牵扯到金钱等精确计算,都使用Decimal。

自动装箱与拆箱

装箱:将基本类型用它们对应的引用类型包装起来;调用了包装类的valueOf()方法

拆箱:将包装类型转换为基本数据类型;调用了 xxxValue()方法

// 手动装箱和拆箱 Integer i1 = Integer.valueOf(100); // 手动装箱 int n1 = i1.intValue(); // 手动拆箱 // 自动装箱和拆箱 Integer i2 = 100; // 自动装箱:编译器自动改为 Integer.valueOf(100) int n2 = i2; // 自动拆箱:编译器自动改为 i2.intValue()

深拷贝和浅拷贝区别?什么是引用拷贝

浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。

深拷贝 :深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。

引用拷贝: 引用拷贝就是两个不同的引用指向同一个对象。

面向对象的三大特征

封装

为了提高代码的安全性,隐藏对象的内部细节,封装将对象的内部状态(字段、属性)隐藏起来,并通过定义公共的方法(接口)来操作对象

外部代码只需要知道如何使⽤这些⽅法而无需了解内部实现

继承

允许一个类(子类)继承另⼀个类(父类)的属性和⽅法的机制

子类可以重用父类的代码,并且可以通过添加新的方法或修改(重写)已有的方法来扩展或改进功能

提高了代码的可重用性和可扩展性

多态

就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。

理解多态的三个条件

public class duotai { public static class Animal { String name; int age; public Animal(String name, int age){ this.name = name; this.age = age; } public void eat(){ System.out.println(name + "吃饭"); } } public static class Cat extends Animal{ public Cat(String name, int age){ super(name, age); } @Override public void eat(){ System.out.println(name+"吃鱼~~~"); } } public static class Dog extends Animal { public Dog(String name, int age){ super(name, age); } @Override public void eat(){ System.out.println(name+"吃骨头~~~"); } } public static void main(String[] args) { // Animal animal=new Animal("花花",4); Animal cat = new Cat("元宝",2); Animal dog = new Dog("小七", 1); cat.eat(); dog.eat(); // animal.eat(); } }

面向对象和面向过程的区别

面向过程: 直接将解决问题的步骤分析出来,然后用函数把步骤一步一步实现,然后再依次调用就可以了. 面向过程思想偏向于我们做一件事的流程,首先做什么,其次做什么,最后做什么。

面向对象: 将构成问题的事物,分解成若干个对象, 需要完成什么事情, 直接让某个对象来干即可,不关注是怎么完成的.

类和对象

类: 像是一个抽象的设计图/模板. 类往往保存一类事物的共性(属性), 共有行为.

对象: 是通过这个设计图/模板创造出来具体实例. 实例往往是共性个性化的表现.

String的不可变性

  • String类被final修饰,表明该类不能被继承,可防止子类添加修改方法
  • value数组被final修饰,表明value自身的值不能改变,即不能引用其他字符数组。

错误说法:因为value数组,被final修饰了,因此不可变

final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。

String s1 = new String("abc");创建了几个对象?

这取决于字符串常量池中是否已存在'abc'这个字符串对象。

情况1:如果常量池中没有'abc',会创建2个对象

  1. 字符串'abc'对应的String对象(加载到常量池)
  2. new关键字创建的String对象(在堆中)

情况2:如果常量池中已有'abc'(比如之前代码用过),只创建1个对象

  1. new关键字创建的String对象

这是因为Java在加载类时,会把字符串放入常量池。执行new String("abc")时,'abc'这个字符串会触发常量池的加载检查。"

String和StringBuffer和StringBuilder区别

String:字符串变量,private final修饰,不可变

StringBuffer:字符串变量(线程安全,可变) 没有使用 final和 private 关键字修饰

StringBuilder:字符串变量(线程不安全,可变) 没有使用final 和 private 关键字修饰

StringBuilder是StringBuffer的简易版,更快

每次对 String 类型进行改变的时候,都会生成一个新的 String对象,然后将指针指向新的 String 对象。StringBuffer 或 StringBuilder 每次都会对 StringBuffer 或 StringBuilder对象本身进行操作,而不是生成新的对象并改变对象引用。

对于三者使用的总结:

  • 操作少量的数据: 适用 String
  • 单线程做大量字符串拼接操作: 适用 StringBuilder
  • 多线程做大量字符串拼接操作: 适用 StringBuffer

字符串拼接用“+” 还是 StringBuilder?

少量、单行拼接:用+,因为编译器会自动优化为StringBuilder,代码更简洁。

循环内或大量拼接:必须用StringBuilder,并且要在循环外创建

字符串常量池的作用了解吗?

字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串 (String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建

开发中使用的字符串很可能有大量的重复, 字符串常量池就可以将重复的字符串只保存一份, 极大地节省了内存.

Read more

【DataX篇】DataX的两种部署方式以及DataX-Web可视化管理平台的搭建

【DataX篇】DataX的两种部署方式以及DataX-Web可视化管理平台的搭建

💫《博主主页》: 🔎 ZEEKLOG主页:奈斯DB 🔎 IF Club社区主页:奈斯、 🔎 微信公众号:奈斯DB 🔥《擅长领域》: 🗃️ 数据库:阿里云AnalyticDB(云原生分布式数据仓库)、Oracle、MySQL、SQLserver、NoSQL(Redis) 🛠️ 运维平台与工具:Prometheus监控、DataX离线异构同步工具 💖如果觉得文章对你有所帮助,欢迎点赞收藏加关注💖     这篇文章将系统的分享 DataX 的安装部署实践,详细拆解DataX的两种核心部署方式——二进制部署与源码编译部署,并深入探讨动态参数配置、并发度优化等关键调优技巧。🎯     在此基础上,也将进一步介绍如何集成 DataX-Web可视化管控平台 ,以构建一个具备 统一调度、实时监控与高效管理 能力的企业级数据同步运维体系。🚀     DataX二进制、源码安装部署的 Github 地址: https://github.com/alibaba/DataX/blob/master/userGuid.md     DataX-Web二进制、

By Ne0inhk
前端岗面试30万字原题含答案

前端岗面试30万字原题含答案

我们正处在前端发展的一个微妙节点。 曾几何时,几句 HTML、CSS 加个 jQuery 特效就能轻松拿 Offer;后来,掌握 Vue 或 React 便能成为市场宠儿。但现在,当你翻开这本“前端岗面试30万字原题含答案”时,我们所面对的前端世界,已经悄然变成了一场 “冰与火之歌”。 大环境的“冰”:在存量博弈中寻找缺口 当下的技术招聘市场,用一个字形容就是 “卷”。互联网行业从野蛮生长步入精耕细作,HC(招聘名额)紧缩,而涌入的求职者却依旧庞大。大厂不再仅仅为了业务扩张而招人,更看重候选人的不可替代性。 你不仅要与同级的毕业生竞争,还要与众多因公司业务调整而释放出来的、经验丰富的中高级开发者同台竞技。这就导致了一个现象:面试难度呈指数级上升。以前“背八股”就能通关,现在面试官更擅长从一个简单的知识点出发,逐步深挖到你知识体系的盲区。 面试的“火”:从“会用”到“

By Ne0inhk
踩坑与成长:WordPress、MyBatis-Plus 及前端依赖问题解决记录

踩坑与成长:WordPress、MyBatis-Plus 及前端依赖问题解决记录

目录 * WordPress中要点,域和托管 * 域名 * 托管 * 添加新页面 * 添加新文章 * 安装方式 * 1. 接口清单(API Design) * 2. Controller 层实现 * 3. Service 层实现 * 4. Mapper 层(MyBatis-Plus) * (1) 好友关系实体 * (2) Mapper接口 * 5. 统一返回结构 * 6. 接口测试示例 * **(1) 添加好友** * **(2) 查询好友列表** * **关键设计说明** * **扩展建议** * 为什么需要为数据库的 email 字段建立索引 * 1. 提高查询性能 * 2. 保证数据唯一性(当需要时) * 3. 支持高级查询特性 * 注意事项 * 实际应用示例 * 关于前端使用openapi报错原因 * 解决方案

By Ne0inhk
【前端】Vue 组件开发中的枚举值验证:从一个Type属性错误说起

【前端】Vue 组件开发中的枚举值验证:从一个Type属性错误说起

🌹欢迎来到《小5讲堂》🌹 🌹这是《小程序》系列文章,每篇文章将以博主理解的角度展开讲解。🌹 🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!🌹 👨💻 作者简介 🏆 荣誉头衔:2024博客之星Top14 | ZEEKLOG博客专家 | 阿里云专家博主 🎤 经历:曾多次进行线下演讲,亦是 ZEEKLOG内容合伙人 以及 新星优秀导师 💡 信念:“帮助别人,成长自己!” 🚀 技术领域:深耕全栈,精通 .NET Core (C#)、Python、Java,熟悉主流数据库 🤝 欢迎交流:无论是基础概念还是进阶实战,都欢迎与我探讨! 目录 * 前言 * 解决过程 * 一、错误场景还原 * 1.1 错误发生的位置 * 1.2 常见的触发场景 * 二、深入理解 Vue

By Ne0inhk