广东南北科技有限公司 - 面鸡来咯

广东南北科技有限公司小厂 - 26 届面经

岗位:Java 开发实习岗 base:广州

时间:2024/12/20

本来想等等会不会有老板面的,感觉已经凉了所以现在发吧

开始等待确实有点紧张,上了战场更紧张~ 面试官竟然是我的师兄。

来吧,不多说了面经来咯~

我也不知道他为什么上来就问这么难的 直到最后面试官说:..... ~ 后文有答案。

1、假设现在你不要用spring,你帮我写一个IOC的一个工具类。这个工具类的话需要实现两个功能。第一跟spring一样,不需要通过new把对象创建出来。第二个能够做一个 Bean 的生命周期管理,说一下你的设计思路。

重点考察:反射,泛型,类的初始化。

回答:我开始没有思路,还说了可以用注解实现,实现类似的@Autowired,@Resource。然后面试官说 JDK1.6 没有用 不可以用 spring 呢。纯 Java。然后反应过来用反射,泛型封装工具使用。然后就是手写示例代码。

相关面试鸭:https://www.mianshiya.com/question/1780933295329013762

GPT 解答:

设计一个简单的 IOC 容器工具类,主要满足以下两个功能:

  1. 无需通过 **new** 创建对象
  • 使用反射机制,通过配置或注解扫描方式加载类并创建实例。
  • 维护一个对象池(例如 Map),实现单例管理。
  1. 生命周期管理
  • 提供对象的初始化、销毁管理。
  • 生命周期管理通过接口的形式约定,例如实现 initdestroy 方法,容器在加载和销毁时自动调用。

设计思路

  1. 容器核心功能
  • 容器负责加载配置或扫描包路径下的类,利用反射机制实例化类。
  • 使用 Map<Class<?>, Object> 保存类和实例的映射,确保单例。
  1. 生命周期管理
  • 定义一个 Lifecycle 接口,包含 initdestroy 方法。
  • 容器在加载实例后调用 init,在销毁时调用 destroy
  1. 线程安全
  • 使用同步或并发集合(如 ConcurrentHashMap)确保多线程下的安全。

以下是实现代码:

java
复制代码
import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class SimpleIOCContainer { // 存放单例对象 private final Map<Class<?>, Object> beanMap = new ConcurrentHashMap<>(); // 注册对象 public <T> void registerBean(Class<T> clazz) { if (beanMap.containsKey(clazz)) { throw new IllegalArgumentException("Bean already exists: " + clazz.getName()); } try { // 创建实例 T instance = clazz.getDeclaredConstructor().newInstance(); // 如果实现了Lifecycle接口,调用init方法 if (instance instanceof Lifecycle) { ((Lifecycle) instance).init(); } // 放入bean容器 beanMap.put(clazz, instance); } catch (Exception e) { throw new RuntimeException("Failed to create bean: " + clazz.getName(), e); } } // 获取对象 public <T> T getBean(Class<T> clazz) { return clazz.cast(beanMap.get(clazz)); } // 销毁容器中的所有对象 public void destroy() { for (Object bean : beanMap.values()) { if (bean instanceof Lifecycle) { try { ((Lifecycle) bean).destroy(); } catch (Exception e) { System.err.println("Failed to destroy bean: " + bean.getClass().getName()); } } } beanMap.clear(); } // 生命周期接口 public interface Lifecycle { void init(); void destroy(); } }

设计特点

  1. 单例管理:通过 ConcurrentHashMap 确保每个类只创建一个实例。
  2. 生命周期管理:通过实现 Lifecycle 接口,支持初始化和销毁操作。
  3. 扩展性:可以通过配置文件或注解扫描动态注册类,进一步完善功能。

2、nacos 用过吧,那现在假设我要不然你自己给我手写一个 nacos 能够实现服务的一个注册发现和治理。说一下你的设计思路。

重点考察:服务注册和调用治理的流程。怎么用代码实现。

回答:这题我是真答不上来了,傻傻的说可以用别的技术 dubbo。 最后在面试官的提示下了解了 nacos 服务注册和发现的流程。

最后还是没答出来。配置,注解,http 协议发送到封装的 工具类中。保存和调用治理等~

相关面试鸭:https://www.mianshiya.com/question/1773283524460240897

GPT 解答:

服务注册

  • 注册中心提供 /register 接口,服务实例启动时发送自身信息(服务名、IP、端口等)。注册后,实例需要定期续约,避免过期。

服务发现

  • 提供 /discover 接口,客户端查询服务名获取实例列表。为提高实时性,可以使用长轮询或推送机制。

健康检查

  • 定期主动 ping 服务实例,检测服务存活状态。如果实例超时多次未响应,则标记为不可用并剔除。

高可用性

  • 注册中心支持多实例部署,数据通过 Raft 实现一致性同步。客户端使用负载均衡访问不同节点。

扩展性

  • 增加版本、权重支持,满足多版本并存和流量分配的需求。还可以扩展安全认证机制。

3、项目场景题。12 个农场,可能有个盆葡萄坏了,系统可以感知到。种植温度感知早上需 30 度,晚上 20 度。如果葡萄变紫色了代表熟了。资金充足,请作为团队帮助农场主一起完成这些需求。

回答: 一开始理解错了,回答什么服务之间发现,调用和感知。答了 Redis 的哨兵机制类似的解决思想。

结果是要回答解决实际问题的方法。在面试官的引导下。答了个温度传感器,哦对了正对面试官思想。

我:啊,难不成是要我当主力,还有硬件工程师当帮手。(反思:哦~,原来是所有资源都有了人也有,告诉硬件工程师干嘛干嘛,服务端干嘛干嘛。我主要负责服务端。)

结果还是没思路。

面试官:后端接口是不是要告诉硬件工程师要掉哪个 ip,接口是啥,要传什么数据?

我:啊,这个不是默认都要完成的事情吗? (反思:啊这么底层的吗?还要这么分析~)

面试官:现在我作为一个硬件工程师,要跟你对接,你啥都不告诉我,让我把数据发给你,我怎么发给你?发excel给你吗?

我:阿巴阿巴,封装对象,http 协议调用。发送到后端接口和网关。进行处理和分析葡萄园的颜色和温度统计

面试官:为啥都要我提示说明呢? 沟通能力要提升,钻研精神要有,不要尬聊,提高设计能力。

我:呜呜呜我还是个大三学生,这些东西真的一时答不上来,不知道还要设计,怎么设计,只会 CRUD😭。后续认真提高自己的能力。

大概没有思路了,还是没答到面试官点上,全是提示后才回答的呜呜呜,难受哇😭。上来就是上难度。

4、你有用过doctor吗?Docker有用过OK docker我要从宿主机里面考一个文件到某个容器里面去,命令怎么写?

回答: 使用docker cp命令(推荐)语法:docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH

相关面试鸭:https://www.mianshiya.com/bank/1812067352871829505/question/1811361114840145922#heading-1

5、Redis 读写为什么这么快,相比 网络 IO 多线程进行。为什么单线程就快呢?

内存,单线程,IO 多路复用。 (没有答上来跳表)但是还好上次模拟面试被@Yes 哥提问到。后续就准备了 Zset 底层跳表实现原理。

框框说出来跳表的实习原理,感谢@Yes。

相关面试鸭:https://www.mianshiya.com/question/1780933295589060609

面试官也懂,留了后路让我答。

期间有段话说到:

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
lenyan
下载 APP