Java面试编程手撕相关题目

这篇具有很好参考价值的文章主要介绍了Java面试编程手撕相关题目。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言
面试官通过Java相关的手撕题目能够很好的看出面试者是否真的具备工程思维,如果有项目,那么这一块一定要掌握好,否则项目的可信度会大打折扣。这类题目可以粗略分为两类,与线程相关的考察的是并发相关编程能力,设计模式以及消息队列相关,就更加考验面向对象的思维。其实知识点不多,重点是要滤清有些什么类,各自实现什么功能,如何配合。

这里基本就是所有需要掌握的了,应该不会少,掌握这些大厂应该都没问题,也不会多,我在面试的过程中全部遇到过。(部分没整理完,这两天会继续整理)

面试手撕除了这种题,当然还有力扣算法题,我也做了整理,也在陆续更新,还没有写完。

1. 实现三个线程交替打印1-120

这个问题考察的是线程之间的通信,线程之间通信的手段可以通过系统提供的线程间通信方法配合锁、信号量等方法实现,方法很多,会两到三个即可。
方法一:synchronized关键字+wait()+notifyAll()

public class PrintNumber{
    private int num;
    private static final Object lock = new Object();
    public void print(int order){
        while(true){
            synchronized(lock){
                if(num >= 10){break;}
                while(num % 3 == order){
                    try{
                        System.out.println(Thread.currentThread().getName()+num);
                        num++;
                        lock.notifyAll();
                        lock.wait();
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static void main(String[]args){
        PrintNumber test = new PrintNumber();
        Thread t0 = new Thread(()->{test.print(0);},"A");
        Thread t1 = new Thread(()->{test.print(1);},"B");
        Thread t2 = new Thread(()->{test.print(2);},"C");

        t0.start();
        t1.start();
        t2.start();

    }
}

方法二:RentrantLock

import java.util.concurrent.locks.ReentrantLock;

public class Main{
        private static int num;
        private ReentrantLock lock = new ReentrantLock();

        public void print(int order){
            while (true){
                lock.lock();
                if(num >= 40){
                    break;
                }
                if(num % 3 == order){
                    System.out.println(Thread.currentThread().getName()+num);
                    num++;
                }
                lock.unlock();
            }
        }
        public static void main(String[]args){
                Main test = new Main();

                Thread t0 = new Thread(()->{test.print(0);},"A");
                Thread t1 = new Thread(()->{test.print(1);},"B");
                Thread t2 = new Thread(()->{test.print(2);},"C");

                t0.start();
                t1.start();
                t2.start();
        }
}

方法三:Semaphore信号量

2. 实现一个线程池

定义 Runnable 线程

import java.util.Date;

/**
 * 这是一个简单的Runnable类,需要大约5秒钟来执行其任务。
 * @author shuang.kou
 */
public class MyRunnable implements Runnable {

    private String command;

    public MyRunnable(String s) {
        this.command = s;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " Start. Time = " + new Date());
        processCommand();
        System.out.println(Thread.currentThread().getName() + " End. Time = " + new Date());
    }

    private void processCommand() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return this.command;
    }
}


定义线程池

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorDemo {

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAX_POOL_SIZE = 10;
    private static final int QUEUE_CAPACITY = 100;
    private static final Long KEEP_ALIVE_TIME = 1L;
    public static void main(String[] args) {

        //使用阿里巴巴推荐的创建线程池的方式
        //通过ThreadPoolExecutor构造函数自定义参数创建
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(QUEUE_CAPACITY),
                new ThreadPoolExecutor.CallerRunsPolicy());

        for (int i = 0; i < 10; i++) {
            //创建WorkerThread对象(WorkerThread类实现了Runnable 接口)
            Runnable worker = new MyRunnable("" + i);
            //执行Runnable
            executor.execute(worker);
        }
        //终止线程池
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");
    }
}


3. 设计模式相关

1) 实现单例模式

首先要明白什么是单例模式,简单来说假如有类 A, 当我们 new 一个 A 的对象的时候,如果是单例模式,先判断是否已经有这个对象了,如果有就返回,没有再创建。这相当于将一个对象和一个类绑定了,该怎么做呢?我们知道,在Java中,如果将一个属性或方法声明为 static 的,那么这个属性或方法就是属于这个类的了,与类绑定了。那办法就呼之欲出了,我们在类中声明一个自身的对象,声明为static的,同时不允许做出修改,加上final关键字。

除此之外,单例模式有两种实现方式,即 饿汉模式 与 懒汉模式。饿汉模式是在类加载的时候直接创建对象,懒汉模式就是当第一次 new 类 A 的对象的时候,才去创建唯一实例。

从以上的描述不难看出,如果是饿汉模式,我们直接将属性初始化即可,如果是懒汉模式,就需要在构造函数中检查是否已经存在相应的对象了,因为要保证单例,当已经存在的时候就不能够再创建了。除此之外,无论是单例还是多例,都需要为外界提供一个 getInstance 函数来获得对象。

饿汉模式

public class Singleton{
	private static final Singleton instance = new Singleton();
	private Singleton(){}
	public static Singleton getInstance(){
		return instance;
	}
}

懒汉模式(方式一)

public class Singleton{
	private static final Singleton instance;
	private Singleton(){}
	public static synchronized Singleton getInstance(){
		if(instance == null){
			this.instance = new Singleton();
		}
		return instance;
	}
}

懒汉模式(方式二:双重校验)文章来源地址https://www.toymoban.com/news/detail-732843.html

public class Singleton{
	private static final Singleton instance;
	private Singleton(){}
	public static Singleton getInstance(){
		if(instance == null){
			synchronized (Singleton.class){
				if(instance == null){
					this.instance = new Singleton();
				}
			}
		}
		return instance;
	}
}
  • 为什么懒汉模式要加锁?
    因为多线程可能会多次创建,因为要保证单例,所以必须加锁。
  • 为什么要用双重校验?
    因为第一种方式直接在方法上加锁,过于笨重,当创建了实例之后,后面的每一次访问,其实不用创建,但是还是要被加锁,用第二种的对代码块加锁,更加的灵活,更加的符合场景。
  • 为什么双重校验方法里,synchronized 关键字的代码块中还要检验一次?
    同样是为了避免多线程多次创建,如果创建之前不检查,可能别的线程也创建了。
  • 双重校验有什么好处?
    获取对象无需加锁,更加符合场景;创建过程线程安全。

2)实现适配器模式

3)实现代理模式

4) 实现策略模式

5) 实现生产者-消费者模式

4. 实现消息队列

到了这里,关于Java面试编程手撕相关题目的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

    🍎 个人博客: 个人主页 🏆 个人专栏: JAVA ⛳️   功不唐捐,玉汝于成 目录 前言 正文 懒汉式(Lazy Initialization): 双重检查锁定(Double-Checked Locking): 结语 我的其他博客 在软件设计中,单例设计模式是一种重要的设计思想,它确保了一个类只有一个实例,并提供了一

    2024年01月15日
    浏览(51)
  • 【JAVA开发面试】如何处理并发访问如何进行代码的单元测试Java多线程编程消息中间件设计模式技术难题是如何解决的

    【 点我-这里送书 】 本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题 中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明

    2024年02月03日
    浏览(48)
  • Java并发面试算法题目

    思路:用lock锁。定义一个类成员变量 max_value,min_value代表资源的最大,最小数量。 2个线程交替打印1-10 问题解决方法比较多。

    2024年02月22日
    浏览(44)
  • Java设计模式【单例模式】

    单例模式(Singleton Pattern)是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供对该实例的唯一访问点。 优点 : 提供了对唯一实例的受控访问。 由于在系统内存中只存在一个对象,因此可以节约系统资源。 缺点 : 单例类的扩展有很大的困难。 单例类的

    2024年02月04日
    浏览(59)
  • JAVA设计模式——单例模式

    单例模式是应用最广的设计模式之一,也是程序员最熟悉的一个设计模式,使用单例模式的类必须保证只能有创建一个对象。 今天主要是回顾一下单例模式,主要是想搞懂以下几个问题 为什么要使用单例? 如何实现一个单例? 单例存在哪些问题? 单例对象的作用域的范围

    2024年02月16日
    浏览(41)
  • 【java】设计模式——单例模式

    单例模式要点 : 一个类只需要一个实例化对象; 必须自行创建实例; 必须自行向整个系统提供这个实例 实现 : 只提供 私有 构造方法; 有一个该类的 静态 私有对象; 提供一个静态 公有 方法用于创建、获取静态私有对象; 分析: 私有构造方法-不能随意创建实例; 静态

    2024年02月13日
    浏览(43)
  • Java设计模式-单例模式

    单例模式是一种设计模式,它确保一个类只能创建一个实例,并提供一种全局访问这个实例的方式。在Java中,单例模式可以通过多种方式来实现,其中最常见的是使用私有构造函数和静态方法实现 在Java中,实现单例模式的方式有多种,其中最常见的实现方式包括以下几种:

    2024年02月01日
    浏览(42)
  • Java 设计模式——单例模式

    (1)单例模式 (Singleton Pattern) 是 Java 中最简单的设计模式之一。它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的

    2024年02月13日
    浏览(58)
  • Java单例模式详解--七种单例模式实现+单例安全+实际应用场景

    保证了一个类只有一个实例,并且提供了一个全局访问点。单例模式的主要作用是节省公共资源,方便控制,避免多个实例造成的问题。 实现单例模式的三点: 私有构造函数 私有静态变量维护对象实例 公有静态方法提供获取实例对象 七种单例模式实现 1.静态类:第一次运

    2024年02月04日
    浏览(59)
  • Java设计模式---单例 工厂 代理模式

    单例模式是设计模式中的一种,属于创建型模式。在软件工程中,单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于那些需要频繁实例化然后引用,且创建新实例的开销较大的类,例如数据库连接池、缓存管理等。 意图 :保证一个类仅有一个实例

    2024年01月24日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包