【Java 强化,最全面试考点与面试技巧

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: 【Java 强化,最全面试考点与面试技巧


  • sayHello
  • saveEmployee

变量名:名词,首字母小写,驼峰表示法。

  • username
  • password
  • bornDate

常量名:全大写字母,单词之间使用下划线隔开。

  • MAX_VALUE
  • NOT_FOUND

主板加载通信组件案例(知识点回顾)

====================================================================================

面向接口编程 + 集合 + 匿名内部类


声明一个 IUSB 接口作为规范:

// USB规范
public interface IUSB {
  void swapData();
} 

创建一个实现该规范的类 Mouse

public class Mouse implements IUSB {
  public void swapData() {
    System.out.println("鼠标在移动");
  }
} 

创建主板类 MotherBoard

import java.util.HashMap;
import java.util.Map;
public class MotherBoard {
  // 存储安装的USB设备对象
  private Map<String, IUSB> plugins = new HashMap<>();
  // 将配件插在主板上
  public void install(String name, IUSB usb) {
    plugins.put(name, usb);
  }
  // 从主板上卸载指定的配件
  public void uninstall(String name) {
    plugins.remove(name);
  }
  // 主板通信, 让每个配件都工作
  public void doWork() {
    for (IUSB usb : plugins.values()) {
      usb.swapData();
    }
  }
} 

用来启动项目的类 App

public class App {
  public static void main(String[] args) {
    // 主板对象
    MotherBoard board = new MotherBoard();
    // 鼠标对象
    Mouse mouse = new Mouse();
    // 安装配件
    board.install("mouse", mouse);
    // 使用匿名内部类, 安装打印接对象
    board.install("print", new IUSB() {
      @Override
      public void swapData() {
        System.out.println("打印......");
      }
    });
    // 调用主板的通信
    board.doWork();
    System.out.println("-----------------------");
  }
} 

鼠标在移动

打印…


[](https://gitee.com/vip204888/java-p7)加载资源文件 + 反射
------------------------------------------------------------------------------
上面的一系列操作是很常规的**面向接口编程**,接下来重点来了!!!如果我们要添加一个键盘类 `Keyboard`要怎么做,新建一个 `Keyboard` 类,然后在 `App.java` 中 `new` 了,再进行操作吗?这样还是有点麻烦了,可以利用 **加载资源文件 + 反射** 真正实现解放双手。。
首先创建一个 **资源文件夹**(必须是 resource folder,它会在编译时将里面的文件放到项目的 path 路径),在里面引用 `properties` 文件:

key = value

mouse = com.yusael._01_review.Mouse

此时目录是这样的:  
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200428225132675.png)  
来到 `MotherBoard`,**使用静态代码块加载资源文件**,并**通过反射创建对象**:

import java.io.InputStream;

import java.util.HashMap;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Properties;

import java.util.Set;

public class MotherBoard {

// 存储安装的USB设备对象
private static Map<String, IUSB> plugins = new HashMap<>();
//-----------------------静态代码快加载资源文件-------------------------
static {
  Properties p = new Properties();
  // 从classpath的根路径去加载plugins.properties文件
  try (InputStream is = Thread.currentThread()
    .getContextClassLoader()
    .getResourceAsStream("plugins.properties"))
  {             
    p.load(is);
    // 读取properties文件, 创建USB组件对象
    Set<Entry<Object, Object>> entrys = p.entrySet();
    for (Entry<Object, Object> entry : entrys) {
      // 资源文件中读取到的类名
      String className = entry.getValue().toString(); 
      // 通过反射利用类名创建对象
      IUSB usbObject = (IUSB)Class.forName(className).newInstance();
      plugins.put(entry.getKey().toString(), usbObject);
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
}
//-------------------------------------------------------------------
// 将配件插在主板上
public void install(String name, IUSB usb) {
  plugins.put(name, usb);
}
// 从主板上卸载指定的配件
public void uninstall(String name) {
  plugins.remove(name);
}
// 主板通信, 让每个配件都工作
public void doWork() {
  for (IUSB usb : plugins.values()) {
    usb.swapData();
  }
}

}

此时 `APP` 中的代码将变得十分简洁,我们无需再手动创建配件对象再调用主板的 `install`,我们只需要维护好配置文件 `plugins.properties` 中的内容即可。
比如,我们写一个键盘类 `Keyboard`:

public class Keyboard implements IUSB{

@Override
public void swapData() {
  System.out.println("键盘在跳舞");
}

}

我们只需要将它添加到配置文件中即可。

key=value

mouse = com.yusael._01_review.Mouse

keyboard = com.yusael._01_review.Keyboard

`APP` 中的代码是不需要动的。

public class App {

public static void main(String[] args) {
  // 主板对象,
  MotherBoard board = new MotherBoard();
  // 调用主板的通信
  board.doWork();
  System.out.println("-----------------------");
}

}

键盘在跳舞
鼠标在移动
----------------------- 
```
[](https://gitee.com/vip204888/java-p7)JavaBean 规范
==============================================================================
**JavaBean** 是一种JAVA语言写成的**可重用组件**(类),必须遵循一定的规范:
1.  类必须使用 `public` 修饰
2.  必须保证有公共无参数构造器
3.  包含了属性的操作手段(`getter`,`setter`)
分类:
*   复杂:UI,比如 `Button`、`Panel`、`Window` 类
*   简单:`domain`、`dao`、`service`组件、封装数据、操作数据库、逻辑运算等
成员:
*   方法:`Method`
*   事件:`event`
*   属性:`property`
属性:
1.  `attribute`:表示状态,Java中没有该概念,很多人把 字段(Field) 称之为 **属性**(attribute)
2.  `property`:表示状态,但是不是字段,是字段的操作方法(`getter`/`setter`)决定的
框架中使用的大多是是属性。
设置字段值:`writeMethod: setter` 方法:
```
public void setXxx(数据类型 变量){
    赋值操作;
} 
```
若:`setName` ----> 属性:`name`  
若:`setUserName` ----> 属性:`userName`  
若:`setISBN` ----> 属性:`ISBN`
获取字段值:`readMethod: getter`方法:
```
public 数据类型 getXxx(){
  return 结果值;
} 
```
若:`getName` ----> 属性:`name`  
若:`getUserName`\----> 属性:`userName`  
若:`getISBN` ----> 属性:`ISBN`  
若:数据类型是 `boolean`,则不叫 get 方法,而是is方法,如:`isEmpty`
标准的属性:一般提供字段,Eclipse 生成 `getter/setter`,**字段和属性同名**
是否需要同时提供 `getter/setter`:
```
public  class User{
  private String firstName;  // 名
  private String lastName; // 性别
  //在数据库只需要存储全名
  public void setFullName(String fullName){}
} 
```
面试题:说说 JavaBean 和 EJB 的区别。
[](https://gitee.com/vip204888/java-p7)Lombok 工具(减少代码量)
===================================================================================
**一、Lombok 是什么**  
Lombok 是一款小巧的代码生成工具。官方网址:[http://projectlombok.org/](https://gitee.com/vip204888/java-p7)
Lombok 主要特性有:自动生成默认的 `getter/setter` 方法、自动化的资源管理(通过`@Cleanup`注解)及注解驱动的异常处理等。目前在国外广泛应用。
Lombok 它和 jquery 一样,**目标是让程序员写更少的代码**,以及改进一些原始语法中不尽人意的地方。Lombok 能做到这一点。既不是用 annotations process,也不是用反射。而是直接黑到了编译过程中。所以**对运行效率没有任何影响**,我们可以通过反编译 class 文件进行验证。
**二、为何项目中要引入 Lombok**
1.  提高开发效率
2.  使代码直观、简洁、明了、减少了大量冗余代码(一般可以节省60%-70%以上的代码)
3.  极大减少了后期维护成本
4.  修改变量名不需要再手动修改 `getter/setter`
**三、使用 Lombok**
1.  给 Eclipse 安装插件,识别语法
2.  在项目中引入 lombok 包
3.  使用其中的注解(标签)
注意:**构造器 和 `toSring` 也可以使用 lombok**,但是建议写出来,看的更明显。
```
import lombok.Getter;
import lombok.Setter;
@Getter@Setter
public class Person {
  private Long id;
  private String name;
  private Integer age;
  public Person(Long id, String name, Integer age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
  @Override
  public String toString() {
    return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
  } 
} 
```
Ctrl \+ O 可以看到当前类的**字段**和**方法**:`getter/setter` 已经存在。  
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200429125233811.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
[](https://gitee.com/vip204888/java-p7)内省机制(Introspector)(重要)
=========================================================================================
内省机制作用:**查看和操作 JavaBean 中的属性**
*   获取 JavaBean 中的每一个属性名/属性类型
*   通过 getter 方法获取属性值;通过 setter 方法给属性设置值
首先创建一个类 `User`:
```
public class User {
  private String name;
  private int age;
  private boolean man;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  public boolean isMan() {
    return man;
  }
  public void setMan(boolean man) {
    this.man = man;
  }
} 
```
下面是一个关于内省机制的例子:
```
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
// 内省机制: 操作User类值的属性
public class IntrospectorDemo {
  public static void main(String[] args) throws Exception {
    // 1:获取JavaBean的描述对象
    BeanInfo beanInfo = Introspector.getBeanInfo(User.class, Object.class);
    User u = User.class.newInstance();
    // 2:获取JavaBean中的属性的描述器
    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
    System.out.println(u); // 证明是同一个对象
    for (PropertyDescriptor pd : pds) {
      // 获取当前属性的名称
      System.out.println("属性名 = " + pd.getName());
      // 获取当前属性的getter方法
      System.out.println("getter : " + pd.getReadMethod());
      // 获取当前属性的setter方法
      System.out.println("setter : " + pd.getWriteMethod());
      System.out.println("--------------------------------");
      if ("name".equals(pd.getName())) {
        Method setter = pd.getWriteMethod(); // 获取方法
        setter.invoke(u, "Jack"); // 调用方法
      }
    }
    System.out.println(u);
  }
} 
```
[](https://gitee.com/vip204888/java-p7)apache的 commons 项目(了解)
=========================================================================================
这部分内容了解一下就可以,知道 apache 有很多强大的项目,commons 是其中之一。  
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200429130937630.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
[](https://gitee.com/vip204888/java-p7)JavaBean 和 Map 相互转换(自行实现)
--------------------------------------------------------------------------------------------
*   JavaBean 拥有**多组属性名和属性值**,每一个属性名称对应一个属性值,属性名称不同。
*   Map 拥有**多组 key-value**,每一个 key 对应一个 value,key 不同。
如果把 JavaBean 中的属性名称看做是 Map 中的 key,二者就是等价的。  
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200429130546705.png)  
把 JavaBean 转换为 Map 对象:
*   `public static Map<String,Object> bean2map(Object bean){}`
把Map对象转换为JavaBean:
*   `public static Object map2bean(Map<String,Object> beanMap,Class beanType){}`
```
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.HashMap;
import java.util.Map;
import com.yusael._02_javabean.Person;
// JavaBean的工具类
public class BeanUtil {
  public static void main(String[] args) throws Exception {
    Person p = new Person();
    p.setId(123L);
    p.setName("Jack");
    p.setAge(18);
    // JavaBean -> Map
    Map<String, Object> map = bean2map(p);
    System.out.println(map);
    // Map -> JavaBean
    Person obj = map2bean(map, Person.class);
    System.out.println(obj);
  }
  // 把JavaBean对象转换为Map
  public static Map<String, Object> bean2map(Object bean) throws Exception {
    Map<String, Object> map = new HashMap<>();
    BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(), Object.class);
    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
    for (PropertyDescriptor pd : pds) {
      String name = pd.getName(); // 属性名称
      Object value = pd.getReadMethod().invoke(bean); // 调用getter方法, 获取属性值
      map.put(name, value);
    }
    return map;
  }
  // 把Map转换为JavaBean
  public static <T> T map2bean(Map<String, Object> map, Class<T> beanType) throws Exception {
    // 创建JavaBean对象
    Object obj = beanType.newInstance();
    BeanInfo beanInfo = Introspector.getBeanInfo(beanType, Object.class);
    PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
    for (PropertyDescriptor pd : pds) {
      // 从Map中获取和属性同名的key的值
      Object value = map.get(pd.getName());
      // 调用setter方法, 设置属性值
      pd.getWriteMethod().invoke(obj, value);
    }
    return (T)obj;
  }
} 
```
[](https://gitee.com/vip204888/java-p7)commons-beanutils(了解、体验一下使用即可)
-------------------------------------------------------------------------------------------------
这部分了解一下即可,大概体验一下这些工具类的作用。。。
需要 jar 包:`commons-beanutils-1.9.4.jar`、`commons-logging-1.2.jar`;  
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200429132609380.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
```
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import com.yusael._02_javabean.Person;
public class BeanUtilsDemo {
  public static void main(String[] args) throws Exception {
    Person p = new Person();
    Map<String, Object> map = new HashMap<>();
    map.put("id", "17210224");
### 最后
提供一下免费的Java架构学习资料给大家,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。
**[需要的朋友可以戳这里免费领取](https://gitee.com/vip204888/java-p7)**
还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
-------------------------------------------------------------
这部分了解一下即可,大概体验一下这些工具类的作用。。。
需要 jar 包:`commons-beanutils-1.9.4.jar`、`commons-logging-1.2.jar`;  
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/20200429132609380.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNDA5NQ==,size_16,color_FFFFFF,t_70)
```
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import com.yusael._02_javabean.Person;
public class BeanUtilsDemo {
  public static void main(String[] args) throws Exception {
    Person p = new Person();
    Map<String, Object> map = new HashMap<>();
    map.put("id", "17210224");
### 最后
提供一下免费的Java架构学习资料给大家,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。
**[需要的朋友可以戳这里免费领取](https://gitee.com/vip204888/java-p7)**
还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/img_convert/8d024dc392da50ff1307e6ef5633b183.png)



相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
相关文章
|
9天前
|
安全 架构师 Java
Java大厂面试高频:Collection 和 Collections 到底咋回答?
Java中的`Collection`和`Collections`是两个容易混淆的概念。`Collection`是集合框架的根接口,定义了集合的基本操作方法,如添加、删除等;而`Collections`是一个工具类,提供了操作集合的静态方法,如排序、查找、同步化等。简单来说,`Collection`关注数据结构,`Collections`则提供功能增强。通过小王的面试经历,我们可以更好地理解这两者的区别及其在实际开发中的应用。希望这篇文章能帮助你掌握这个经典面试题。
26 4
|
9天前
|
监控 Dubbo Java
Java Dubbo 面试题
Java Dubbo相关基础面试题
|
9天前
|
SQL Java 数据库连接
Java MyBatis 面试题
Java MyBatis相关基础面试题
|
9天前
|
存储 监控 算法
Java JVM 面试题
Java JVM(虚拟机)相关基础面试题
|
9天前
|
SQL 监控 druid
Java Druid 面试题
Java Druid 连接池相关基础面试题
|
9天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题
|
29天前
|
Java
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
今日分享的主题是如何区分&和&&的区别,提高自身面试的能力。主要分为以下四部分。 1、自我面试经历 2、&amp和&amp&amp的不同之处 3、&对&&的不同用回答逻辑解释 4、彩蛋
|
5月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
2月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?