21年-自研-笔试题

news2024/10/5 21:14:41

目录

  • 背景
  • 题目
    • 1、Object的常用方法
    • 2、 == 和 equals 的区别是什么?
      • ==
      • equals
    • 3、以下代码的运行结果
    • 4、以下代码的运行结果
    • 5、String, StringBuilder,StringBuffer
    • 6、ArrayList和LinkedList
    • 7、一些常用的线程安全的集合类
    • 8、以下代码的运行结果
    • 9、完成下面的代码
    • 10、写一个线程安全的单例模式
    • 11、哪些方法保障线程安全
      • 使用synchronized关键字
        • 同步代码块
        • 同步方法
      • 使用lock
    • 12、算法,任选一个
    • 13、数据库编程
      • 统计每个班级(class_id)的人数
      • 查询所有18岁以上学生的信息。如果有课程成绩,查询出最高分的课程成绩
      • 查询每门课程最高分的学生信息
    • 14、介绍下几种join
    • 15、基本类型和包装类型的区别

背景

21年4月,应聘杭州滨江某自研公司,以下是该公司的笔试题
题目的答案,是根据我的理解写的。可能有不对的地方,欢迎大家指正。
这一场的面试题忘了,当时没记录

题目

1、Object的常用方法

●1.getClass()

public final native Class<?> getClass()

获取对象运行时的class对象,通常和反射机制搭配使用。
class对象就是描述对象所属类的对象
●2.hashCode

public native int hashCode()

获取对象的散列值。Object中该方法默认返回的是对象的堆内存地址。
●3.equals

public boolean equals(Object object){
    return (this == obj);
}

比较2个对象,如果2个对象引用的是同一个对象,那么返回true。
一般equals和==是不一样的,但在Object中是一样的。子类一般重写equals方法。
●4.clone

protected native Object clone() throws CloneNotSupportedException;

该方法是保护方法,实现对象的浅拷贝,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportException。
默认的clone是浅拷贝。浅拷贝,指的是对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存。
深拷贝就是会连引用的对象也重新创建。
●5.toString

public String toString(){
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

返回一个String对象,一般子类都有覆盖。
默认返回格式:对象的class名称 + @ + hashCode的十六进制字符串。
●6.notify

 public final native void notify()

final方法,主要唤醒在该对象上等待的某个线程
●7.notifyAll

 public final native void notifyAll()

final方法,唤醒在该对象上等待的所有线程
●8.wait(long timeout)

 public final native void wait(long timeout) throws InterruptedException

timeout是毫秒值
使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。
这里设置一个超时间隔,如果在规定时间没有获得到锁就返回。
无参的wait() 方法会一直等待,直到获得锁或者被中断。
●9.wait(long timeout, int nanos)

 public final void wait(long timeout, int nanos) throws InterruptedException{
    if (timeout < 0) {
    throw new IllegalArgumentException("timeout value is negative");
  }
 
  if (nanos < 0 || nanos > 999999) {
    throw new IllegalArgumentException(
              "nanosecond timeout value out of range");
  }
 
  if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
    timeout++;
  }
 
  wait(timeout);

}

timeout:最大等待时间,毫秒
nanos:附加时间在毫秒范围(0-999999),纳秒/毫微秒,十亿分之一秒
该方法导致当前线程等待,直到其他线程调用此对象的 notify() 方法或notifyAll()方法,或在指定已经过去的时间。此方法类似于 wait 方法的一个参数,但它允许更好地控制的时间等待一个通知放弃之前的量。实时量,以毫微秒计算,计算公式如下:1000000 * timeout + nanos
在所有其他方面,这种方法与 wait(long timeout) 做同样的事情。特别是 wait(0, 0) 表示和 wait(0) 相同。
●10.wait()

 public final void wait() throws InterruptedException{
    wait(0);
}

实际调用的是wait(long timeout)方法,只不过timeout是0。
●11.finalize

 protected void finalize() throws Throwable{}

是保护方法,用于在GC的时候再次被调用。如果实现了这个方法,对象可能在这个方法中再次复活,避免被GC回收。

2、 == 和 equals 的区别是什么?

==

对于基本类型和引用类型 == 的作用效果是不同的,如下所示:
基本类型:比较的是值是否相同;
引用类型:比较的是引用是否相同;
代码示例:

String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y); // true
System.out.println(x==z); // false
System.out.println(x.equals(y)); // true
System.out.println(x.equals(z)); // true

代码解读:
因为 x 和 y 指向的是同一个引用,所以 == 也是 true。
而 new String()方法则重写开辟了内存空间,所以 == 结果为 false,
而 equals 比较的一直是值,所以结果都为 true。

equals

equals 本质上就是 ==,只不过 String 和 Integer 等重写了 equals 方法,把它变成了值比较。看下面的代码就明白了。
首先来看默认情况下 equals 比较一个有相同值的对象,代码如下:

String s1 = new String("老王");
String s2 = new String("老王");
System.out.println(s1.equals(s2)); // true

进入 String 的 equals 方法,找到了答案,代码如下:

public boolean equals(Object anObject) {    
     if (this == anObject) {        
          return true;   
     }    
     if (anObject instanceof String) {        
          String anotherString = (String)anObject;        
          int n = value.length;        
          if (n == anotherString.value.length) {            
               char v1[] = value;           
               char v2[] = anotherString.value;            
               int i = 0;            
               while (n-- != 0) {                
                   if (v1[i] != v2[i])                    
                       return false;                
                   i++;            
               }            
               return true;        
            }    
      }    
      return false;
}

可以看出, String 重写了 Object 的 equals 方法,把引用比较改成了值比较。
总结 :
== 对于基本类型来说是值比较,对于引用类型来说是比较的是引用;
equals 默认情况下是引用比较,只是很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,
所以一般情况下 equals 比较的是值是否相等。

3、以下代码的运行结果

public class Stu {

	private String name;
	private int age;

	public Stu(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
 
   public static void main(String[] args) {
		Stu s1 = new Stu("张三", 18);
		Stu s2 = new Stu("张三", 18);
		System.out.println(s1 == s2);// false
		System.out.println(s1.equals(s2));// false
	}
}

4、以下代码的运行结果

String s0 = null;
String s1 = "Tomcat";
String s2 = "Tom" + "cat";
String s3 = new String("Tomcat");
System.out.println(s1==s2);//true
System.out.println(s1.equals(s2));//true
System.out.println(s1==s3);//false
System.out.println(s1.equals(s3));//true
//intern():返回常量池中这个对象的引用
System.out.println(s1==s3.intern());//true
System.out.println(s0==s1);//false
System.out.println(s0.equals(s1));//空指针异常!
//null去equals某个值,就会报错。如果非null去equals任意值,就不会错,如下所示
System.out.println(s1.equals(s0));//false

5、String, StringBuilder,StringBuffer

String:定义的不可变字符串。在操作少量数据时使用。
StringBuilder:定义的可变字符串。线程不安全。性能比StringBuffer快。推荐单线程下使用。
StringBuffer:定义可变字符串。线程安全,因为它的所有公开方法都用synchronized修饰。推荐多线程下用。
整体性能上:StringBuilder > StringBuffer > String
为什么是这样的性能排序?
String每执行一次+(重载运算符),就要创建一个新的对象
StringBuffer比StringBuilder相比,少了同步锁。
为什么不可变?
String底层代码中,整个类被final修饰,该类不能被继承;其中的value[]属性被final修饰,引用不能被修改。
为什么StringBuffer线程安全?
StringBuffer通过synchronized关键字修饰,保证资源不会被抢,从而确保了线程安全。

6、ArrayList和LinkedList

①ArrayList底层是数组,(动态数组),LinkedList底层是双向链表。
②随机访问get和set,ArrayList要优于LinkedList。
③对于新增和删除,add/remove,LinkedList更快,因为ArrayList要移动数据。

7、一些常用的线程安全的集合类

①Vector:(实现了List接口),比ArrayList多了同步化机制
②Stack:栈,继承于Vector。先进后出。
③HashTable:比HashMap多了线程安全。(实现了Map接口)
④ConcurrentHashMap:高效且线程安全的集合。(继承AbstractMap,实现了ConcurrentMap接口)

8、以下代码的运行结果

static class VO implements Cloneable {
	List<Object> datas = new ArrayList<>();

	@Override
	public VO clone() throws CloneNotSupportedException {
        return (VO) super.clone();
	}
}

@Test	
public void cloneT() throws CloneNotSupportedException {
    VO vo = new VO();
    vo.datas.add("1");
    VO vo2 = vo.clone();
    vo2.datas.add("2");
    
    System.out.println(vo.datas.size());// 2
    System.out.println(vo2.datas.size());// 2
}

9、完成下面的代码

public class VO {

	private Integer id;

	public VO(Integer id) {
       super();
       this.id = id;
	}
	//...get、set、toString方法
}

List<VO> volist = mockDatas();

要求:请对集合voList,根据id进行分组
分析:就是有个集合,集合内装的是某种对象(泛型),对象有个ID字段。
根据ID进行分组,同个ID的对象放在一起。
实现代码如下

public static void main(String[] args) {
    // 根据题意,准备的测试用的voList
	VO v1 = new VO(18);
	VO v2 = new VO(18);
	VO v3 = new VO(18);
	VO v4 = new VO(18);
	List<VO> voList = new ArrayList<>();
	voList.add(v1);
	voList.add(v2);
	voList.add(v3);
	voList.add(v4);
 
   //解法1
	// 0.新建map,存放分组后的vo集合数据
	Map<Integer, List<VO>> map = new HashMap<Integer, List<VO>>();
	// 1.遍历list
	for (VO vo: voList) {
		// 2.获取每个元素的id,判断map中的key有没有这个id
		if (map.containsKey(vo.getId())) {
			// 有,就把这个元素放到这个key下的value里
			map.get(vo.getId()).add(vo);
		} else {
			// map的key里没有这个id,
                   // ==>那就以此新建key,再把对应的vo集合放进value
			List<VO> newVOList = new ArrayList<VO>();
			newVOList.add(vo);
			map.put(vo.getId(), newVOList);
		}
	}
	// 现在,已经得到了按id分组的map。
	// 下一步,根据map,新建list,把分好组的数据放进去
	List<List<VO>> resultList = new ArrayList<List<VO>>(map.values());
	// 展示结果
	for (List<VO> list : resultList) {
		for (VO vo : list) {
			System.out.println("User---" + vo.toString());
		}
	}
	/*
    * HashMap.values(): 获取value集合
	 * 把Map转换成List<List<User>>,为什么会变成List<List<User>>?
	 * 原因在于
	 * map是以多个userId为键值,存储多个List<User>,map.values转换成list就会变成
	 * List<List<User>>
	 */
    
    // 解法2——使用Stream流
    Map<Integer, List<VO>> finalMap = voList.stream().collect(Collectors.groupingBy(VO::getId));
}

10、写一个线程安全的单例模式

单例模式,一种设计模式,一个类只能创建一个对象。
单例模式,可以有饿汉式 和 懒汉式。其中饿汉式,是线程安全的。
懒汉式
(1)为节省内存,创建对象的步骤放到getInstance()中
(2)为保证单例,创建对象时加判断。若未创建,就创建;若已创建,就返回之前创建的
(3)为线程安全,方法上加锁,用synchronized上锁

//处理后的懒汉式(线程安全), 缺点效率低,
public static Singleton{
    private static Singleton singleton;
    private Singleton(){
        
    }
    public static synchronized Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}
//没有用synchronized 的懒汉式, 线程不安全
public static Singleton{
    private static Singleton singleton;
    private Singleton(){
        
    }
    public static Singleton getInstance(){
        if(singleton == null){
            singleton = new Singleton();
        }
        return singleton;
    }
}

饿汉式
(1)私有化构造器
(2)内部创建一个实例
(3)定义一个方法将实例返回。
这个方法的修饰符必须是public static,返回对象也static修饰。
(4)返回对象用private修饰,防止外界随意调用。

//饿汉式
public class Singleton{
    private static Singleton singleton = new Singleton();
    private Singleton(){    
    }
    
    public static Singleton getInstance(){
        return singleton;
    }
}

11、哪些方法保障线程安全

使用synchronized关键字

同步代码块

synchronized 锁对象{
多条操作共享数据的语句
}
锁对象:任意对象,多个线程必须使用同一把锁
这种方法的好处:多线程下提高安全性
坏处:运行速率变低

同步方法

●同步非静态方法:
格式:将synchronized写在方法上。
锁对象:当前类对象this
●同步静态方法:
锁对象:当前的类对象,类名.class

使用lock

lock():加锁 unlock():解锁
一般使用ReturnLock,是lock的实现类。
即,Lock lock = new ReturnLock
释放锁必须在finally中执行,因为锁必须释放

12、算法,任选一个

(1)合并2个有序数组,写出代码实现
(2)从一个有序数组中找一个缺少的元素。数组中至少有一个缺失元素。如数组[1,2,4,5,6,7,],缺少数字3

13、数据库编程

学生表stu(id,name,age,class_id)
学生的成绩表score(id,stu_id,kemu,chengji)

统计每个班级(class_id)的人数

select class_id as '班级', count(id) as '人数'
from stu
group by class_id

在这里插入图片描述

查询所有18岁以上学生的信息。如果有课程成绩,查询出最高分的课程成绩

select stu.*, score.kemu, score.chengji
from stu stu
left join score
on stu.id = score.stu_id
where stu.age > 18

在这里插入图片描述

查询每门课程最高分的学生信息

 select b.kemu,b.chengji, c.age, c.name 
 from (
     select kemu, max(chengji) maxc 
     from score group by kemu) a,score b, stu c 
 where 
    a.kemu = b.kemu and 
    a.maxc = b.chengji and
    b.stu_id = c.id

结果如下

14、介绍下几种join

15、基本类型和包装类型的区别

(1)包装类型可以为null,基本类型不可以
使得包装类型可以应用于POJO中,而基本类型不行。
(2)包装类型可用于泛型,基本类型不可以
(3)基本类型比包装类型更高效
基本类型在栈中存储具体的数值。包装类型存储的是堆中的引用.
(4)自动装箱和自动拆箱
基本类型 -> 包装类型,自动装箱
包装类型 -> 基本类型,自动拆箱

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/47368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java环境准备——JDK下载和安装、IDEA下载和安装

一、JDK下载及安装 1、必要性&#xff1a;JDK是整个Java开发的核心。 2、下载网址&#xff1a;Java Downloads | Oracle 3、选择下载JDK17的原因&#xff1a;JDK17 是Java的长期支持版本。 4、下载到本地后&#xff0c;双击进行安装&#xff0c;然后点击下一步&#xff0c;安…

AI物品分类识别管理系统uniapp源码带文档教程

技术架构 技术框架&#xff1a;SpringBoot2 Mysql5.7 Mybatis-Plus uniapp Swagger2 RuoYi-fast swagger-bootstrap-ui 运行环境&#xff1a;jdk8 IntelliJ IDEA maven 宝塔面板 百度智能云平台服务 本地api接口端搭建教程 后端需要准备相关的IDE和JDK8开发环境 , 前…

GIT技巧

目录 基础命令 commit 、branch merge rebase 高级特性 自由修改提交树 cherry-pick rebase 远程仓库命令 基础命令 commit 、branch Git Commit Git 仓库中的提交记录保存的是你的目录下所有文件的快照&#xff0c;就像是把整个目录复制&#xff0c;然后再粘贴一样…

Linux内核中ideapad-laptop.c文件全解析6

接前一篇文章《Linux内核中ideapad-laptop.c文件全解析5》&#xff0c;地址为&#xff1a; Linux内核中ideapad-laptop.c文件全解析5_蓝天居士的博客-CSDN博客 上一篇详细分析了ideapad_debugfs_init&#xff0c;本篇详细分析ideapad_input_init。 ideapad_input_init ideap…

Word控件Spire.Doc 【图像形状】教程(7): 如何使用 C# 在 Word 中替换图像

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

b站黑马JavaScript的Ajax案例代码——聊天机器人案例

目录 目标效果&#xff1a; 更换的新接口&#xff1a; 1.机器人智能回复接口&#xff1a;http://www.liulongbin.top:3006/api/robot 2.机器人语音接口&#xff1a;http://www.liulongbin.top:3006/api/synthesize 重点原理&#xff1a; 1.jQuery中trim方法 2.jquery中a…

Hive数据查询语言-DQL-含示例演练(Select查询数据、Join查询)

文章目录1. Select查询数据1.1 基础语法1.1.1 select_ecpr1.1.2 ALL、DISTINCT1.1.3 WHERE1.1.4 分区查询、分区裁剪1.1.5 GROUP BY1.1.6 HAVING1.1.7 LIMIT1.1.8 执行顺序1.2 高阶语法1.2.1 ORDER BY1.2.2 CLUSTER BY1.2.4 Union联合查询1.2.5 from子查询&#xff08;Subqueri…

Allegro自动沿着目标任意形状走线操作指导

Allegro自动沿着目标任意形状走线操作指导 Allegro有个非常好用的功能,支持自动沿着目标任意形状走线,对于异形板框走线尤其方便,以下图为例,需要沿着这个外形走一段线 具体操作如下 点击add connect命令 点击空白处 鼠标右击选择contour命令 出现一个对话框,当前是…

03【Spring AOP、CGBLIB代理】

文章目录03【Spring AOP、CGBLIB代理】一、AOP前奏1.1 案例1.1.1 需求设计1.1.2 需求修改1.1.3 需求增加1.1.4 分析存在的问题1.2 动态代理1.2.1 定义接口&#xff1a;1.2.2 日志代理类1.2.3 缓存代理类&#xff1a;1.2.4 测试类二、AOP2.1 AOP 概述2.1.1 纵向编程2.1.2 纵横配…

【Java进阶篇】第六章 IO流

文章目录一、IO流的概述1、流2、流的分类3、Java IO流的四大块4、流的两大特性5、java.io包下的16个常用流二、文件专属流1、java.io.FileInputStream2、java.io.FileOutputStream3、java.io.FileReader4、java.io.FileWriter三、缓冲流与转换流1、java.io.BufferedReader2、ja…

【面试题】深度解析Java多线程中的 run() 与 start() 有什么区别?

【面试题】深度解析Java多线程中的 run() 与 start() 有什么区别&#xff1f; 大多数人的回答 start() run() 深入底层源码的解析 run() 与 start() 为什么我们不能直接调用 run() 方法&#xff1f; 如何证明 start() 会调用 run() 方法&#xff1f; JVM -> OS执行全…

Nodejs -- 数据库基本概念的介绍及在Express中操作数据库

文章目录1. 数据库的基本概念1.1 什么是数据库1.2 常见的数据库及分类1.3 传统型数据库的数据组织结构1.3.1 Excel的数据组织结构1.3.2 传统型数据库的数据组织结构1.3.3 实际开发中库、表、行、字段的关系2. 在Express中操作MySQL2.1 在项目中操作数据库的步骤2.2 安装与配置m…

Java编程案例:买飞机票

编程案例&#xff1a; 一、目的 复习前半段课程学习的Java编程知识&#xff0c;能够使用所学的知识解决问题&#xff0c;提升同学们的编程能力。 二、涉及到的知识点 变量、数组。运算符&#xff1a;基本运算符、关系运算符、逻辑运算符…程序流程控制&#xff1a;if、switc…

np.meshgrid()函数

文章目录(1)自己理解(2)官方解释(3)参数:3.1 x1, x2,…, xn:array_like3.2 sparse:bool, optional 默认false3.3 copy:bool, optional(1)自己理解 np.meshgrid(a, b,indexing "xy") 函数会返回 b.shape() 行 &#xff0c;a.shape() 列的二维数组。 因此 i, j 都是 …

【序列召回推荐】(task6)多兴趣召回Comirec-SA

note Comirec-SA基于attention的多兴趣建模&#xff0c;论文中先通过attention提取单一兴趣&#xff0c;再推广到多兴趣建模。另外使用贪心算法优化带有准确度多样性的目标函数。DR把MIND的attention换成argmax&#xff08;还有初始化方式不同、序列胶囊到兴趣胶囊用可学习权重…

2.线性代数基础

1.矩阵 2. 特殊矩阵 正交矩阵 AATE&#xff08;E为单位矩阵&#xff0c;AT表示“矩阵A的转置矩阵”。&#xff09;或ATAE&#xff0c;则n阶实矩阵A称为正交矩阵 正交矩阵有如下性质&#xff1a; A是正交矩阵&#xff0c;AT也是正交矩阵A的各行是单位向量且两两正交&#xff0…

html实现ezuikit.js萤石云直播监控,ezuikit.js实时监控实现,萤石云实时监控简单实现

效果图 实现 下面的播放url获取&#xff1a;登录萤石云->控制台->我的资源->设备列表->列表中&#xff1a;查看通道->监控地址 appKey和appSecret获取&#xff1a;登录萤石云->控制台->我的账号->应用信息->右侧&#xff1a;应用密钥 下载ezuikit…

(服务器客户端)网络通信是怎么实现的?7000字爆肝----原来java网络编程技术功不可没(多线程,URL,InetAddressm,TCP,UDP)集结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏 java ⭐java网络编程技术⭐ 文章目录⭐java网络编程技术⭐&#x1f468;‍&#x1f4bb;一&#xff0c;URL类…

[附源码]Python计算机毕业设计Django的4s店车辆管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

虎牙、斗鱼同道同命:共同御寒

配图来自Canva可画 回顾游戏直播行业过去十年&#xff0c;先是直播行业野蛮发展玩家快速跑马圈地&#xff0c;而后历经千播大战形成斗鱼、虎牙分天下的市场格局&#xff0c;现在头部平台进入精细化、多元化运作阶段&#xff0c;市场竞争愈加激烈。 也就是说&#xff0c;游戏直…