首页 > 基础资料 博客日记

盘点下华为大佬的技术拷问下我没招架住的一些问题

2024-05-31 19:00:03基础资料围观152

Java资料网推荐盘点下华为大佬的技术拷问下我没招架住的一些问题这篇文章给大家,欢迎收藏Java资料网享受知识的乐趣

  行情动荡不安,看着同组曾经一块并肩战斗过的开发同事们陆续被迫离职,我最近几个月也多少的思维活跃了些,有些惴惴不安,不知何时会轮到自己。想着即使暂时轮不到自己,也要有着被裁后能立马找到下家工作的能力,一直坐以待毙终究沦为案板上的羔羊。

  据说华为社招技术岗基本都是OD了,正式的很少很少,但是OD的面试流程及用人标准和正式是一样的,有不少难度,我也想试试,想试下华为大佬的技术盘问下我能抵挡几个回合,于是随机在Boss上选了一个华为OD岗投递了下。

  去年8月份,参加过一次华为算法题机考,战败收尾,毕竟我不是985/211名校,及格线要比他们高很多很多;

  今年3月份,再次参加了一次,还好,过了;

  后来又参加了华为的性格测试、提交了所有的资面材料审核,等着HR帮我推华为招聘的项目组;

  4月份工作太忙了,加上五一放假的临近不想给自己太大压力,就和HR讲把推项目组的事情安排到了节后;

  后来5月16接到了来自于华为的HR的电话,简单沟通了半小时,随后她替我约了华为的面试官时间,技术一面放在5月18号周六上午10:00,技术二面放在了5月20号周一晚上7:30,完美避开了我的上班时间。两位面试官风格迥异,第一个笑呵呵的比较随和,问技术的同时掺杂着场景题,有来有往有交流,第二个比较高冷严肃,全场拷问技术,一问一答型,回答完后不做任何评价,接着下一题。至于我回答的怎么样,其实我也没底,有些问题确实是我的技术盲区,但我会的也全答上来了,庆幸的是,两位面试官出的现场编程题我全做上来了,每轮都进行了接近一小时左右。

  5月21号,HR告诉我两轮技术面通过了,接下来就是用人主管的综面了,综面一般问题都不大,过后就发offer了,从技术面定级的情况下每个月给到 xx K,每年大概是14-16薪的样子,我粗略估算了下,综合年收入能比我现在多10W左右,妈呀,这种破行情下还能让我有这样的好机遇,华为待遇方面果然大气!   可另一个头疼的问题来了,用人部门是其他城市的,开始是想去那个城市发展的,但家里人还是不希望我走太远,我咨询了下可不可以入职后在北京的华为办公,答案是否定的,没辙,我不是一个人,我还有家人在北京上班,不再是那个初次步入社会闯荡的少年了,天南地北皆可去得,只能放弃了这份来之不易的工作,拒绝了综面。 感叹我毕业后来北京已经工作五年,第一份工作呆了2年,第二份工作呆了3年了,我是一个求稳定的人,若不是公司各种资金吃紧,大面积的裁人,换调项目组导致晋升渺茫,停止调薪,我是万不会萌发出去看看的想法,但是人总归给自己个退路么,等有一天裁员这把大刀真的架在了我的脖子上,又当如何?

 

  废话说了那么多,开始回归主题了,我复盘了下在技术面时答得不是很好的几个问题,也接受大家的批评与指正:

1.你知道Spring有哪些发布消息、监听消息的组件么?

初看这问题我以为是想问我消息中间件,我回答了Kafka消息发布监听,异步解耦的知识点,其实不然,这里面试官想考察我对Spring的事件机制了解多少,Spring事件机制名词隐约在哪听过,但工作中却从未用过,算是被难到了,后来面试官也大致给我解释了在Spring中这是个很好用的组件,使用观察者模式啥的,能够降低模块之间的耦合度,像一些发短信,发邮件的功能可以通过这种监听机制自动去处理,和业务代码隔离开,不是通过调用方法的形式。后来我也大致去网上搜了下,大致整理了一些知识点:

(1)概述

Spring的事件机制是Spring框架中的一个重要特性,它基于观察者模式实现,允许应用程序中的组件之间进行松耦合的通信。这种机制允许开发者在应用程序中定义、发布和监听事件,从而实现模块间的解耦,提高代码的可维护性和可扩展性。

(2)核心组件与概念

  • 事件(Event):表示应用程序中的某个动作或状态的发生,通常通过继承ApplicationEvent类来定义自定义事件。
  • 事件源(Event Source):负责发布事件的对象,通常使用ApplicationEventPublisher接口的实现类来发布事件。
  • 事件监听器(Event Listener):负责监听事件并执行相应操作的对象,需要实现ApplicationListener接口。 也可以在方法上添加@EventListener注解实现。
  • 事件广播器(Event Broadcaster):在Spring中,这个角色通常由ApplicationContext担任,它实现了ApplicationEventPublisher接口,负责管理事件的发布和监听。

(3)工作流程

  • 事件发布:事件源通过ApplicationEventPublisherpublishEvent方法发布事件。
  • 事件监听:事件监听器通过实现ApplicationListener接口并注册到ApplicationContext中,从而能够监听到感兴趣的事件。
  • 事件处理:当事件发布后,ApplicationContext会找到所有订阅了该事件的监听器,并调用它们的onApplicationEvent方法进行处理。

(4)使用方式

  • 定义自定义事件:通过继承ApplicationEvent类来定义自定义事件,可以添加与事件相关的数据和方法。
  • 创建事件监听器:创建一个实现了ApplicationListener接口的类,并指定需要监听的事件类型。在onApplicationEvent方法中编写事件处理逻辑。
  • 发布事件:在需要发布事件的地方,通过ApplicationEventPublisherpublishEvent方法发布自定义事件。

(5)优点

  • 解耦:通过事件机制,可以实现模块间的解耦,使代码更加清晰、易于维护。
  • 可扩展性:可以方便地添加新的事件和监听器,以满足不同的业务需求。
  • 灵活性:事件监听器可以处理多个事件,也可以只处理特定类型的事件。

(6)自己写的简单的Demo代码

// 定义一个事件类
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
@Getter
public class CustomEvent extends ApplicationEvent {

    private String phone;

    private String email;

    public CustomEvent(Object source) {
        super(source);
    }

    public CustomEvent(String phone,String email,Object source){
        super(source);
        this.email = email;
        this.phone = phone;
    }
}

// 定义一个事件发布器
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

@Component
public class CustomPublisher implements ApplicationEventPublisherAware {
    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void publish(String phone,String email) {
        CustomEvent event = new CustomEvent(phone,email,"Event Publish");
        publisher.publishEvent(event);
    }
}


import org.springframework.context.ApplicationListener;
/**
 * / 定义一个事件监听器 - 发短信
 */
public class CustomListenerOne implements ApplicationListener<CustomEvent> {
    @Override
    public void onApplicationEvent(CustomEvent customEvent) {
        System.out.println("I am ListenerOne,I need send message to phone:"+customEvent.getPhone());
    }
}


import org.springframework.context.ApplicationListener;

/**
 * 定义一个事件监听器 发邮件
 */
public class CustomListenerTwo implements ApplicationListener<CustomEvent> {
    @Override
    public void onApplicationEvent(CustomEvent customEvent) {
        System.out.println("I am ListenerTwo,I need send email to "+customEvent.getEmail());
    }
}



import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
/**
 * 注解方式实现的事件监听器
 */
@Component
public class CustomListenerThree {
    @EventListener
    public void onApplicationEvent(CustomEvent customEvent) {
        System.out.println("注解方案:I am ListenerTwo,I need send email to "+customEvent.getEmail());
    }
    @EventListener
    public void onApplicationEvent2(CustomEvent customEvent) {
        System.out.println("注解方案:I am ListenerOne,I need send message to phone:"+customEvent.getPhone());
    }
}



import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
测试启动类,注册各个组件
 */
public class MainEvent {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        // 注册事件监听器
        context.addApplicationListener(new CustomListenerOne());
        context.addApplicationListener(new CustomListenerTwo());
        // 注册发布器的bean
        context.register(CustomPublisher.class);
        context.refresh();

        // 获取发布器并发布事件
        CustomPublisher publisher = context.getBean(CustomPublisher.class);
        publisher.publish("188****865","aaa_dduuuu@1663.com");
        context.close();
    }
}

  

2.介绍下final、finally、finalize的特性与区别。

final和finally我比较熟悉,当时全都回答上来了,但是finalize我确实之前没有深入了解和使用过,直接和面试官说finalize不清楚了。

  1. final
    • final 是一个修饰符,它可以用来修饰类、方法和变量。
    • 当 final 修饰一个类时,这个类不能被继承。
    • 当 final 修饰一个方法时,这个方法不能被重写(在子类中)。
    • 当 final 修饰一个变量时,这个变量的值不能被改变(常量)。对于基本类型,值不可变;对于引用类型,引用本身不可变,但引用的对象内部状态可以改变。
  2. finally
    • finally 是一个异常处理块的关键字,用于定义在所有情况下都必须执行的代码,无论是否抛出或捕获到异常。
    • 通常,finally 块与 try 和 catch 块一起使用,以确保资源(如文件句柄、网络连接等)在异常发生时也能被正确释放。
    • 无论 try 块中的代码是否成功执行,或者 catch 块是否捕获到异常,finally 块中的代码都会被执行。
  3. finalize
    • finalize 是 Object 类的一个方法,它的设计初衷是在垃圾收集器准备释放对象占用的内存之前,被垃圾收集器调用,从而允许对象执行一些清理工作。
    • 但是,由于 finalize 方法的执行时间是不确定的,并且其执行可能会受到 JVM 实现的影响,因此在现代 Java 编程中,通常不建议依赖 finalize 方法进行资源管理或执行其他重要的清理工作。
    • 相反,应该使用 try-with-resources 语句(Java 7 引入)或显式的 close 方法(如果对象实现了 AutoCloseable 或 Closeable 接口)来管理资源。

总结:

  • final 用于声明常量、不可继承的类和不可重写的方法。
  • finally 用于定义无论是否发生异常都必须执行的代码块。
  • finalize 是 Object 类的一个方法,用于在对象被垃圾收集之前执行清理工作,但通常不建议使用它。

 

3.线程的sleep和对象的wait方法都能让线程等待,有什么区别呢?

这个问题我当时回答了一些sleep 方法在指定的时间后自动唤醒,wait 方法只能被其他线程在同一对象上调用 notify 或 notifyAll 方法来唤醒。但是面试官还追问我有没有其他的区别,可见我回答的并不全面,后来也整理了一版,分享给大家:

  1. 所属类和方法签名:
    • sleep 是 Thread 类的一个静态方法,因此可以在任何线程中调用。其方法签名是 public static void sleep(long millis) throws InterruptedException
    • wait 是 Object 类的一个方法,因此所有对象都可以调用它。其方法签名是 public final void wait() throws InterruptedException(还有其他重载版本,如 wait(long timeout) 和 wait(long timeout, int nanos))。
  2. 锁机制:
    • sleep 方法不会释放当前线程持有的任何锁。线程在调用 sleep 后会进入 TIMED_WAITING 状态,但会继续持有锁,直到睡眠时间结束。
    • wait 方法会释放当前线程持有的对象锁(即调用 wait 方法的对象上的锁)。线程在调用 wait 后会进入 WAITING 或 TIMED_WAITING 状态,并且不会持有锁,直到其他线程在同一对象上调用 notify 或 notifyAll 方法。
  3. 唤醒机制:
    • sleep 方法在指定的时间后自动唤醒,或者如果线程被中断,也会提前唤醒。
    • wait 方法只能被其他线程在同一对象上调用 notify 或 notifyAll 方法来唤醒。如果线程在等待时被中断,它也会提前唤醒,并抛出 InterruptedException
  4. 用途:
    • sleep 通常用于暂停线程的执行一段时间,或者用于实现简单的轮询或延迟。
    • wait 通常用于多线程之间的通信和同步,特别是在实现生产者-消费者模式或其他需要线程间协作的场景时。
  5. 异常处理:使用注意事项:
    • 如果线程在调用 sleep 时被中断,它会清除中断状态(即将中断状态重置为 false)并抛出 InterruptedException
    • 如果线程在调用 wait 时被中断,它也会抛出 InterruptedException,但不会清除中断状态。这意味着调用线程可以立即检查中断状态,并决定是继续等待还是处理中断。
    • sleep 可以在任何情况下调用,但 wait 必须在同步代码块或同步方法中调用,因为它依赖于对象锁。
    • 在调用 wait 或 notify 之前,最好总是先检查对象的锁状态,以避免潜在的并发问题。
    • wait 和 notify 应该与 synchronized 关键字一起使用,以确保线程安全。

 

  其余的回答的不好肯定也有,但是记不真切了,怪我没好好背八股文,像一些弱引用强引用的区别记着也没回答好,这没什么分享的价值;Spring AOP底层原理讲了一些没说很细;还有OOM的排查方案我分享了下工作中遇到时怎么排查处理的,但面试官好像想听我讲Linux命令版的排查;其余的也问了一些mysql、spring、并发编程、JVM、Kafka、SpringCould组件、缓存相关、软件设计的一些零零碎碎的知识点,感觉也都回答了七七八八吧。经过机考和两轮技术面,收获还是有的,看来我不能只关注技术的广度,也得静下心来好好看看Java语言本身的一些技术点和原理,还得注意定期复盘,否则曾经掌握过的知识点也会在时间的洪流中被冲刷干净。

 


文章来源:https://www.cnblogs.com/zaevn00001/p/18224249
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云