2.Java基础【Java面试第三季】

news2024/10/2 18:19:32

2.Java基础【Java面试第三季】

  • 前言
  • 推荐
  • 2.Java基础
  • 01_字符串常量Java内部加载-上
    • 58同城的java字符串常量池
      • 面试code
      • 讲解
        • intern()方法---源码+解释
  • 02_字符串常量Java内部加载-下
        • why
      • OpenJDK8底层源码说明
        • 递推步骤
        • 总结
      • 考查点
  • 03_闲聊力扣算法第一题
    • 字节跳动两数求和
      • 题目说明
      • 面试题
      • 解法
  • 04_TwoSum暴力解法
  • 05_TwoSum优化解法
      • 考察点
    • 字节跳动手写LRU算法
  • 最后

前言

2023-2-1 13:23:19

以下内容源自
【尚硅谷Java大厂面试题第3季,跳槽必刷题目+必扫技术盲点(周阳主讲)-哔哩哔哩】
仅供学习交流使用

推荐

Java开发常见面试题详解(LockSupport,AQS,Spring循环依赖,Redis)

2.Java基础

01_字符串常量Java内部加载-上

58同城的java字符串常量池

面试code

package javase;

public class StringPool58Demo1 {
    public static void main(String[] args) {
        String str1=new StringBuilder("58").append("tongchen").toString();
        System.out.println(str1.intern());
        System.out.println(str1 == str1.intern());

        System.out.println();

        String str2=new StringBuilder("ja").append("va").toString();
        System.out.println(str2);
        System.out.println(str2.intern());
        System.out.println(str2 == str2.intern());
    }
}

讲解

intern()方法—源码+解释

在这里插入图片描述
由于运行时常量池是方法区的一部分,所以这两个区域的溢出测试可以放到一起进行。HotSpot从JDK 7开始逐步“去永久代”的计划,并在JDK 8中完全使用元空间来代替永久代的背景故事,在此我们就以测试代码来观察一下,使用"永久代"还是“元空间"来实现方法区,对程序有什么实际的影响。

String:intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。在JDK 6或更早之前的HotSpot虚拟机中,常量池都是分配在永久代中,我们可以通过-XX:PermSize和-XX:MaxPermSize限制永久代的大小,即可间接限制其中常量池的容量。

package javase;

public class StringPool58Demo1 {
    public static void main(String[] args) {
        String str1=new StringBuilder("58").append("tongchen").toString();
        System.out.println(str1.intern());
        System.out.println(str1 == str1.intern());

        System.out.println();

        String str2=new StringBuilder("ja").append("va").toString();
        System.out.println(str2);
        System.out.println(str2.intern());
        System.out.println(str2 == str2.intern());
    }
}

输出结果:

58tongchen
58tongchen
true

java
java
false

02_字符串常量Java内部加载-下

why

  • 按照代码结果,Java字符串答案为false,必然是两个不同的java,那另外一个java字符串如何加载进来的?
  • 为什么
    • 有一个初始化的Java字符串(JDK出娘胎自带的),在加载sun.misc.Version这个类的时候进入常量池。

OpenJDK8底层源码说明

递推步骤

  • System代码解析 System -> initializeSystemClass() -> Version

System

package java.lang;

public final class System {

    /* register the natives via the static initializer.
     *
     * VM will invoke the initializeSystemClass method to complete
     * the initialization for this class separated from clinit.
     * Note that to use properties set by the VM, see the constraints
     * described in the initializeSystemClass method.
     */
    private static native void registerNatives();
    static {
        registerNatives();
    }
    
    //本地方法registerNatives()将会调用initializeSystemClass()
    private static void initializeSystemClass() {

		...
        
        sun.misc.Version.init();

		...
    }
    ...
}

Version

package sun.misc;

//反编译后的代码
public class Version {
	private static final String launcher_name = "java";
	...
}

测试Version的其他字符串

public class Version {
    private static final java.lang.String launcher_name = "java";
    private static final java.lang.String java_version = "1.8.0_60";
    private static final java.lang.String java_runtime_name = "Java(TM) SE Runtime Environment";
    private static final java.lang.String java_profile_name = "";
    private static final java.lang.String java_runtime_version = "1.8.0_60-b27";
}
  		String str3 =new StringBuilder("1.8.0_60").toString();
        String str4 =new StringBuilder("Java(TM) SE Runtime Environment").toString();
        String str5 =new StringBuilder("").toString();
        String str6 =new StringBuilder("1.8.0_60-b27").toString();

        System.out.println(str3 == str3.intern()||str4 == str4.intern()
        ||str5==str5.intern()||str6==str6.intern());//false

  • 类加载器和rt.jar----根加载器提前部署加载rt.jar
    0605

  • OpenJDK8源码

    • http://openjdk.java.net/
    • openjdk8\jdk\src\share\classes\sun\misc
      0732

总结

《深入理解java虚拟机》----第二章 Java内存区域与内存溢出异常----2.4 实战:OutOfMemoryError异常----2.4.3 方法区和运行时常量池溢出----代码清单2-8 String.intern()返回引用的测试

这段代码在JDK 6中运行,会得到两个false,而在JDK 7中运行,会得到一个true和一个false。产生差异的原因是,在JDK 6中,intern()方法会把首次遇到的字符串实例复制到永久代的字符串常量池中存储,返回的也是永久代里面这个字符串实例的引用,而由StringBuilder创建的字符串对象实例在Java堆上,所以必然不可能是同一个引用,结果将返回false。

而JDK 7(以及部分其他虚拟机,例如JRockit)的intern()方法实现就不需要再拷贝字符串的实例到永久代了,既然字符串常量池已经移到Java堆中,那只需要在常量池里记录一下首次出现的实例引用即可,因此intern()返回的引用和由StringBuilder创建的那个字符串实例就是同一个。而对str2比较返回false,这是因为“java”这个字符串在执行StringBuilder.toString()之前就已经出现过了,字符串常量池中已经有它的引用,不符合intern()方法要求“首次遇到"”的原则,“计算机软件"这个字符串则是首次出现的,因此结果返回true。
sun.misc.Version类会在JDK类库的初始化过程中被加载并初始化,而在初始化时它需要对静态常量字段根据指定的常量值(ConstantValue〉做默认初始化,此时被sun.misc.Version.launcher静态常量字段所引用的"java"字符串字面量就被intern到HotSpot VM的字符串常量池——StringTable里了。

sun.misc.Version类会在JDK类库的初始化过程中被加载并初始化,而在初始化时它需要对静态常量字段根据指定的常量值(ConstantValue〉做默认初始化,此时被sun.misc.Version.launcher静态常量字段所引用的"java"字符串字面量就被intern到HotSpot VM的字符串常量池——StringTable里了。

考查点

  • intern()方法,判断true/false?
  • 《深入理解java虚拟机》书原题是否读过经典JVM书籍

03_闲聊力扣算法第一题

字节跳动两数求和

然后考了2个算法:
1给定一个数m,求大干该数的最小2的n次幂、返同n	这个我一分钟内就完成了。
2.leetCode的第i题
给定一个整数数组nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。示例:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
快手算法:
给定一个链表,.删除相邻相同的数据项。比如2 -2-3 返回 2-3。这个算法也没运行出来,但是之前题目打的比较好,一面过了。
给定一个链表,"其中元素只有01,删除0的节点,并返回链表。≤(后来面试官说这是AQS的一部分源码……)

题目说明

https://leetcode.cn/problems/two-sum/
0334

面试题

package javase;

import java.util.HashMap;

/**
 * 给定一个整数数组nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
 * 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。示例:
 * 输入:nums = [2,7,11,15], target = 9
 * 输出:[0,1]
 * 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
 */
public class TwoSumDemo2 {
    public int[] twoSum(int[] nums, int target) {
        return null;
    }
    public static void main(String[] args) {
        int[] nums=new int[]{2,7,11,15};
        int target=9;

    }
}

解法

  • 暴力

04_TwoSum暴力解法

package javase;

import java.util.Arrays;
import java.util.HashMap;

/**
 * 给定一个整数数组nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
 * 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。示例:
 * 输入:nums = [2,7,11,15], target = 9
 * 输出:[0,1]
 * 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
 */
public class TwoSumDemo2 {

    //遍历-->暴力破解
    /**
     * 通过双重循环遍历数组中所有元素的两两组合,
     * 当出现符合的和的返回两个元素的下标
     * @param nums
     * @param target
     * @return
     */
    public static int[] twoSum1(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i+1; j <nums.length-1 ; j++) {
                if (target-nums[i]==nums[j]){
                    return new int[]{i,j};
                }
            }
        }
        return null;
    }
   
    
    public static void main(String[] args) {
        int[] nums=new int[]{2,7,11,15};
        int target=9;

        System.out.println(Arrays.toString(twoSum1(nums, target)));

    }
}

还有没有更优的解法

05_TwoSum优化解法

  • 哈希
package javase;

import java.util.Arrays;
import java.util.HashMap;

/**
 * 给定一个整数数组nums和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
 * 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。示例:
 * 输入:nums = [2,7,11,15], target = 9
 * 输出:[0,1]
 * 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
 */
public class TwoSumDemo2 {

    //遍历-->暴力破解

    /**
     * 通过双重循环遍历数组中所有元素的两两组合,
     * 当出现符合的和的返回两个元素的下标
     * @param nums
     * @param target
     * @return
     */
    public static int[] twoSum1(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i+1; j <nums.length-1 ; j++) {
                if (target-nums[i]==nums[j]){
                    return new int[]{i,j};
                }
            }
        }
        return null;
    }
    
    public static int[] twoSum2(int[] nums, int target) {
        HashMap<Integer,Integer> map=new HashMap();
        for (int i = 0; i < nums.length; i++) {
            if (map.containsKey(target-nums[i])){
                return new int[]{map.get(target-nums[i]),i};
            }
            
            map.put(nums[i],i);
            
        }

        return null;
    }

    public static void main(String[] args) {
        int[] nums=new int[]{2,7,11,15};
        int target=9;

        System.out.println(Arrays.toString(twoSum1(nums, target)));
        System.out.println(Arrays.toString(twoSum2(nums, target)));

    }
}

考察点

你都想来大厂了,算法居然从来没有刷过?呵呵机会偏爱有准备有实力的头脑,不是白说的…

字节跳动手写LRU算法

见Redis最后(请坚持到最后一章)

最后

2023-2-1 14:56:19

这篇博客能写好的原因是:站在巨人的肩膀上

这篇博客要写好的目的是:做别人的肩膀

开源:为爱发电

学习:为我而行

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

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

相关文章

rt-thread 移植调试记录

rt-thread 移植调试记录 记录rt-thread移植的过程。这里移植仅仅是利用rt-thread源码目录已经移植好的文件&#xff0c;组建自己的工程&#xff0c;不需要自己编写汇编完成底层移植。 1. 搭建基础工程 这里使用的是正点原子的潘多拉开发板&#xff0c;MCU为stm32l475。需要先…

【c++】类和对象:让你明白“面向一个对象有多重要”:构造函数,析构函数,拷贝构造函数的深入学习

文章目录 什么是面向对象&#xff1f;一&#xff1a;类是什么&#xff1f; 1.类的访问限定符 2.封装 3.类的实例化 4.this指针二&#xff1a;类的6个默认成员函数 1.构造函数 2.析构函数 3.拷贝构造函数什么是面向对象&#xff1f; c语言是面向…

window系统中安装Jupyter Notebook方法记录

1.初步感受Jupyter Notebook Jupyter Notebook 官网地址&#xff1a;Jupyter Notebook Jupyter Notebook&#xff08;此前被称为 IPython notebook&#xff09;是一个交互式笔记本&#xff0c;支持运行 40 多种编程语言。 Jupyter Notebook 的本质是一个 Web 应用程序&#xf…

Java体系最强干货分享—挑战40天准备Java面试,最快拿到offer!

如何准备java面试&#xff0c;顺利上岸大厂java岗位&#xff1f; 主攻Java的人越来越多&#xff0c;导致行业越来越卷&#xff0c;最开始敲个“hello world”都能进大厂&#xff0c;现在&#xff0c;八股、全家桶、算法等等面试题横行&#xff0c;卷到极致&#xff01;就拿今年…

聊聊什么是架构,你理解对了吗?

什么是架构?软件有架构?建筑也有架构?它们有什么相同点和不同点? 下面咱们就介绍一下,容易混淆的几个概念 一、系统与子系统 系统 泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能单独完成的工作的群体。它的意思是 “总体”、“整体”或“联盟” 子系…

Java基础常见面试题(二)

面向对象基础 面向对象和面向过程的区别 面向过程 优点&#xff1a; 性能比面向对象高&#xff0c;因为类调用时需要实例化&#xff0c;开销比较大&#xff0c;比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发&#xff0c;性能是最重要的因素。 缺点…

如何做迭代规划

敏捷开发中的迭代规划如同使用需求漏斗&#xff0c;对各方需求定期进行优先级排序并层层拆解或合并&#xff0c;最终把高优先级且细粒度的需求从漏斗进入到研发团队&#xff0c;确保研发团队做对的事&#xff08;Do Right Things&#xff09;&#xff0c;避免团队跑偏方向或进度…

Netty之EventLoopGroup详解

目录 目标 Netty版本 Netty官方API NioEventLoopGroup和DefaultEventLoop的区别 EventLoopGroup实现对内部EventLoop的轮询 EventLoop对普通任务和定时任务的实现 执行普通任务 执行定时任务 划分EventLoopGroup职责 简言 实现 指定EventLoopGroup操作ChannelHandl…

手机上怎么在线生成gif?1分钟教你手机图片合成gif

怎样通过手机实现在线制作GIF图片的操作呢&#xff1f;接下来&#xff0c;给大家分享两招gif制作&#xff08;https://www.gif.cn/&#xff09;小窍门-【GIF中文网】不需要下载任何软件&#xff0c;小白也能轻松上手。支持原画质导出&#xff0c;图片无损处理。一起来看看具体步…

前端教学视频分享(视频内容与市场时刻保持紧密相连,火热更新中。。。)

⚠️获取公众号 本次要想大家推荐一下本人的公众号&#xff0c;在微信中搜索公众号 李帅豪在对话框中输入前端视频四个字即可立即获取所有视频&#xff0c;不收费无广告&#xff01;&#xff01;&#xff01; 本公众号收集了近两年来前端最新最优秀的学习视频&#xff0c;涵盖…

大数据技术架构(组件)30——Spark:Optimize--->Submit

2.1.9、Optimize--->Submit调优工作主要从CPU、内存、网络开销和IO四方面入手2.1.9.0、Spark On Yarn2.1.9.0.1、Jar包管理及本地性调优spark.yarn.jars :将jar包放到hdfs上&#xff0c;避免每次driver启动的时候都要进行jar包的分发。yarn.nodemanager.localizer.cache.cle…

ChatGPT告诉你智能制造

ChatGPT自上线以来&#xff0c;几乎得到了外界的一致好评&#xff0c;上线两个月&#xff0c;获得1亿月活跃用户&#xff0c;成为增长最快的面向消费者的应用。 面对ChatGPT拟人一般的问答能力&#xff0c;很多人认为它代表着AlphaGo之后&#xff0c;人工智能应用的第二次浪潮…

电子技术——MOS差分输入对

电子技术——MOS差分输入对 差分输入系统因其极高的共模抑制能力&#xff0c;差分输入几乎是是构建所有通用模拟IC的基本前级输入&#xff0c;也是现代信号传输理论的基础。本节我们讲解MOS差分输入对。 MOS差分输入对 下图展示了MOS差分输入对的基本原理图&#xff1a; 一个…

数据采集协同架构,集成马扎克、西门子、海德汉、广数、凯恩帝、三菱、海德汉、兄弟、哈斯、宝元、新代、发那科、华中各类数控以及各类PLC数据采集软件

文章目录 前言一、采集协同架构是什么&#xff1f;可以做什么&#xff08;数控、PLC配置采集&#xff09;&#xff1f;二、使用步骤 1.打开软件&#xff0c;配置MQTT或者数据库&#xff08;支持sqlserver、mysql等&#xff09;存储转发消息规则2.配置数控系统所采集的参数、转…

项目(今日指数)

一 项目架构1.1 今日指数技术选型【1】前端技术【2】后端技术栈【3】整体概览3.2 核心业务介绍1】业务结构预览【2】业务功能简介1.定时任务调度服务XXL-JOB通过RestTemplate多线程动态拉去股票接口数据&#xff0c;刷入数据库&#xff1b; 2.国内指数服务 3.板块指数服务 4.涨…

使用Harbor构建docker私有仓库

一、概述1、什么是HarborHarbor 是VMware公司开源的云本地 registry 仓库&#xff0c;有可视化的Web管理界面&#xff0c;可以方便的管理和储存 Docker 镜像。Harbor 支持在多个仓库直接进行复制镜像&#xff0c;提供用户管理和访问控制和活动审计。2、Harbor的优势基于角色控制…

mysql高级(事务、存储引擎、索引、锁、sql优化、MVCC)

文章目录1.事务1.1 四大特性ACID1.2 并发事务2.存储引擎2.1 InnoDB2.2 MyISAM2.3 Memory2.4 存储引擎特点2.5 存储引擎的选择3.性能分析3.1 查看执行频次3.2 慢查询日志3.3 profile3.4 explain4.索引4.1 索引结构B-TreeBTreeHash面试题4.2 索引分类思考题4.3 语法4.4 使用规则最…

抖音电商-安全带为例分析

为什么来抖音抖音对好货的扶持力度很大好商品对抖音商城至关

Python-项目实战--飞机大战-英雄登场(7)

目标设计英雄和子弹类使用pygame.key.get_pressed()移动英雄发射子弹1.设计英雄和子弹类1.1英雄需求游戏启动后&#xff0c;英雄出现在屏幕的水平中间位置&#xff0c;距离屏幕底部120像素英雄每隔0.5秒发射一次子弹&#xff0c;每次连发三枚子弹英雄默认不会移动&#xff0c;需…

vulnhub之CLOVER: 1

1.信息收集 输入arp-scan 192.168.239.0/24进行主机存活探测&#xff0c;可以看到192.168.239.171主机存活。 对192.168.239.171主机进行端口扫描&#xff0c;可以看到20、21、22、82、110、443、5781、8080。 发现21端口可以匿名登录&#xff0c;输入&#xff1a;anonymous…