金歌 发表于 2024-5-31 17:49:25

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

https://img2024.cnblogs.com/blog/1912367/202405/1912367-20240531174702126-1190706269.png
  行情动荡不安,看着同组曾经一块并肩战斗过的开发同事们一连被迫离职,我最近几个月也多少的思维活跃了些,有些惴惴不安,不知何时会轮到自己。想着即使暂时轮不到自己,也要有着被裁后能立马找到下家工作的能力,一直坐以待毙终究沦为案板上的羔羊。
  据说华为社招技术岗基本都是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年了,我是一个求稳定的人,若不是公司各种资金吃紧,大面积的裁人,换调项目组导致晋升渺茫,停止调薪,我是万不会萌发出去看看的想法,但是人总归给自己个退路么,等有一天裁员这把大刀真的架在了我的脖子上,又当如何?
https://img2024.cnblogs.com/blog/1912367/202405/1912367-20240531175011420-394331605.png
 
  废话说了那么多,开始回归主题了,我复盘了下在技术面时答得不是很好的几个问题,也担当大家的批评与指正:
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)工作流程


[*]事件发布:事件源通过ApplicationEventPublisher的publishEvent方法发布事件。
[*]事件监听:事件监听器通过实现ApplicationListener接口并注册到ApplicationContext中,从而能够监听到感爱好的事件。
[*]事件处置惩罚:当事件发布后,ApplicationContext会找到所有订阅了该事件的监听器,并调用它们的onApplicationEvent方法进行处置惩罚。
(4)使用方式


[*]定义自定义事件:通过继承ApplicationEvent类来定义自定义事件,可以添加与事件相关的数据和方法。
[*]创建事件监听器:创建一个实现了ApplicationListener接口的类,并指定需要监听的事件范例。在onApplicationEvent方法中编写事件处置惩罚逻辑。
[*]发布事件:在需要发布事件的地方,通过ApplicationEventPublisher的publishEvent方法发布自定义事件。
(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不清晰了。

[*]final

[*]final 是一个修饰符,它可以用来修饰类、方法和变量。
[*]当 final 修饰一个类时,这个类不能被继承。
[*]当 final 修饰一个方法时,这个方法不能被重写(在子类中)。
[*]当 final 修饰一个变量时,这个变量的值不能被改变(常量)。对于基本范例,值不可变;对于引用范例,引用本身不可变,但引用的对象内部状态可以改变。

[*]finally

[*]finally 是一个异常处置惩罚块的关键字,用于定义在所有情况下都必须执行的代码,无论是否抛出或捕获到异常。
[*]通常,finally 块与 try 和 catch 块一起使用,以确保资源(如文件句柄、网络连接等)在异常发生时也能被正确开释。
[*]无论 try 块中的代码是否成功执行,或者 catch 块是否捕获到异常,finally 块中的代码都会被执行。

[*]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 方法来唤醒。但是面试官还追问我有没有其他的区别,可见我回答的并不全面,厥后也整理了一版,分享给大家:

[*]所属类和方法签名:

[*]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))。

[*]锁机制:

[*]sleep 方法不会开释当前线程持有的任何锁。线程在调用 sleep 后会进入 TIMED_WAITING 状态,但会继续持有锁,直到就寝时间结束。
[*]wait 方法会开释当前线程持有的对象锁(即调用 wait 方法的对象上的锁)。线程在调用 wait 后会进入 WAITING 或 TIMED_WAITING 状态,而且不会持有锁,直到其他线程在同一对象上调用 notify 或 notifyAll 方法。

[*]唤醒机制:

[*]sleep 方法在指定的时间后自动唤醒,或者如果线程被中断,也会提前唤醒。
[*]wait 方法只能被其他线程在同一对象上调用 notify 或 notifyAll 方法来唤醒。如果线程在等待时被中断,它也会提前唤醒,并抛出 InterruptedException。

[*]用途:

[*]sleep 通常用于暂停线程的执行一段时间,或者用于实现简单的轮询或延迟。
[*]wait 通常用于多线程之间的通信和同步,特殊是在实现生产者-消耗者模式或其他需要线程间协作的场景时。

[*]异常处置惩罚:使用注意事项:

[*]如果线程在调用 sleep 时被中断,它会清除中断状态(即将中断状态重置为 false)并抛出 InterruptedException。
[*]如果线程在调用 wait 时被中断,它也会抛出 InterruptedException,但不会清除中断状态。这意味着调用线程可以立即检查中断状态,并决定是继续等待还是处置惩罚中断。

[*]


[*]

[*]sleep 可以在任何情况下调用,但 wait 必须在同步代码块或同步方法中调用,由于它依赖于对象锁。
[*]在调用 wait 或 notify 之前,最好总是先检查对象的锁状态,以避免潜伏的并发问题。
[*]wait 和 notify 应该与 synchronized 关键字一起使用,以确保线程安全。

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 盘点下华为大佬的技术拷问下我没招架住的一些问题