四面阿里Java开发岗,国内一线互联网公司面试题汇总

前言

我想对所有程序员说:除了看视频、做项目来提高自身的技术之外,还有一种提升自己的专业技能就是:多!看!书!(本文内提到的书单笔者整理出了一份电子档作为分享,文末有免费获取方式)

网络框架、中间件、容器、并发编程、虚拟机等最近几年在互联网行业是越来越火热,Netty、Docker、并发编程、虚拟机也是程序员不得不掌握的技术点,掌握熟练这些技术点,必能让你在“互联网寒冬”的这场大战中立于不败之地!今天我们就来了解当下最流行的那些新兴技术。

一、什么是ZooKeeper

ZooKeeper是一个分布式服务协调框架,提供了分布式数据一致性的解决方案,基于ZooKeeper的数据结构,Watcher,选举机制等特点,可以实现数据的发布/订阅,软负载均衡,命名服务,统一配置管理,分布式锁,集群管理等等。

二、为什么使用ZooKeeper

ZooKeeper能保证:

  • 更新请求顺序进行。来自同一个client的更新请求按其发送顺序依次执行
  • 数据更新原子性。一次数据更新要么成功,要么失败
  • 全局唯一数据视图。client无论连接到哪个server,数据视图都是一致的
  • 实时性。在一定时间范围内,client读到的数据是最新的

三、数据结构

ZooKeeper的数据结构和Unix文件系统很类似,总体上可以看做是一棵树,每一个节点称之为一个ZNode,每一个ZNode默认能存储1M的数据。每一个ZNode可通过唯一的路径标识。如下图所示:

创建ZNode时,可以指定以下四种类型,包括:

  • PERSISTENT,持久性ZNode。创建后,即使客户端与服务端断开连接也不会删除,只有客户端主动删除才会消失。
  • PERSISTENT_SEQUENTIAL,持久性顺序编号ZNode。和持久性节点一样不会因为断开连接后而删除,并且ZNode的编号会自动增加。
  • EPHEMERAL,临时性ZNode。客户端与服务端断开连接,该ZNode会被删除。
  • EPEMERAL_SEQUENTIAL,临时性顺序编号ZNode。和临时性节点一样,断开连接会被删除,并且ZNode的编号会自动增加。

四、监听通知机制

Watcher是基于观察者模式实现的一种机制。如果我们需要实现当某个ZNode节点发生变化时收到通知,就可以使用Watcher监听器。

客户端通过设置监视点(watcher)向 ZooKeeper 注册需要接收通知的 znode,在 znode 发生变化时 ZooKeeper 就会向客户端发送消息

这种通知机制是一次性的。一旦watcher被触发,ZooKeeper就会从相应的存储中删除。如果需要不断监听ZNode的变化,可以在收到通知后再设置新的watcher注册到ZooKeeper。

监视点的类型有很多,如监控ZNode数据变化、监控ZNode子节点变化、监控ZNode 创建或删除

五、选举机制

ZooKeeper是一个高可用的应用框架,因为ZooKeeper是支持集群的。ZooKeeper在集群状态下,配置文件是不会指定Master和Slave,而是在ZooKeeper服务器初始化时就在内部进行选举,产生一台做为Leader,多台做为Follower,并且遵守半数可用原则。

由于遵守半数可用原则,所以5台服务器和6台服务器,实际上最大允许宕机数量都是3台,所以为了节约成本,集群的服务器数量一般设置为奇数

如果在运行时,如果长时间无法和Leader保持连接的话,则会再次进行选举,产生新的Leader,以保证服务的可用

六、初の体验

首先在官网下载ZooKeeper,我这里用的是3.3.6版本。

然后解压,复制一下/conf目录下的zoo_sample.cfg文件,重命名为zoo.cfg。

修改zoo.cfg中dataDir的值,并创建对应的目录:

最后到/bin目录下启动,我用的是window系统,所以启动zkServer.cmd,双击即可:

启动成功的话就可以看到这个对话框:

可视化界面的话,我推荐使用ZooInspector,操作比较简便

最后,附一张自己面试前准备的脑图:

image

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

image

  • Spring全家桶(实战系列)

image.png

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

image

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

资料领取方式:Java全套学习手册

是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

资料领取方式:Java全套学习手册

以上学习资料均免费分享,最后祝愿各位身体健康,顺利拿到心仪的offer!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现正四面体的透视投影动态隐线算法,需要以下步骤: 1. 定义正四面体的顶点坐标和连接关系。 2. 根据相机位置和视角计算出每个顶点在屏幕上的坐标。 3. 对于每个面,判断其是否朝向相机,如果是则不需要绘制,否则需要进行透视投影。 4. 对于每个面,判断其是否需要显示边界,如果需要则进行动态隐线算法。 下面是一个简单的 Java 代码实现: ```java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; public class Tetrahedron extends JPanel implements ActionListener { private static final int WIDTH = 800; private static final int HEIGHT = 600; private static final int SIZE = 100; private static final int[] X = {0, 0, SIZE/2, -SIZE/2}; private static final int[] Y = {0, SIZE, -SIZE/2, -SIZE/2}; private static final int[][] Z = {{0, SIZE/2, SIZE/2, SIZE/2}, {0, 0, SIZE/2, -SIZE/2}, {0, 0, -SIZE/2, SIZE/2}, {0, -SIZE, 0, 0}}; private static final int[][] CONNECT = {{0, 2}, {0, 3}, {0, 1}, {1, 2}, {1, 3}, {2, 3}}; private double angle = 0; private Timer timer = new Timer(30, this); public Tetrahedron() { setPreferredSize(new Dimension(WIDTH, HEIGHT)); timer.start(); } @Override public void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D)g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.clearRect(0, 0, WIDTH, HEIGHT); // calculate vertex coordinates double sin = Math.sin(angle); double cos = Math.cos(angle); int[][] coords = new int[4][2]; for (int i = 0; i < 4; i++) { int x = X[i]; int y = (int)(Y[i]*cos - Z[i][0]*sin); int z = (int)(Y[i]*sin + Z[i][0]*cos); coords[i][0] = x; coords[i][1] = (int)(y*cos - z*sin); } // draw edges g2d.setColor(Color.BLACK); for (int[] conn : CONNECT) { int x1 = coords[conn[0]][0] + WIDTH/2; int y1 = coords[conn[0]][1] + HEIGHT/2; int x2 = coords[conn[1]][0] + WIDTH/2; int y2 = coords[conn[1]][1] + HEIGHT/2; if (isVisible(x1, y1, x2, y2)) { g2d.drawLine(x1, y1, x2, y2); } } angle += 0.05; } private boolean isVisible(int x1, int y1, int x2, int y2) { boolean visible = true; for (int[] conn : CONNECT) { int x3 = X[conn[0]]; int y3 = Y[conn[0]]; int z3 = Z[conn[0]][0]; int x4 = X[conn[1]]; int y4 = Y[conn[1]]; int z4 = Z[conn[1]][0]; if (isIntersecting(x1, y1, x2, y2, x3, y3, z3, x4, y4, z4)) { visible = false; break; } } return visible; } private boolean isIntersecting(int x1, int y1, int x2, int y2, int x3, int y3, int z3, int x4, int y4, int z4) { double t = ((x3-x1)*(y4-y3) - (y3-y1)*(x4-x3))/((x2-x1)*(y4-y3) - (y2-y1)*(x4-x3)); double s = ((x2-x1)*(y3-y1) - (y2-y1)*(x3-x1))/((x2-x1)*(y4-y3) - (y2-y1)*(x4-x3)); if (t >= 0 && t <= 1 && s >= 0 && s <= 1) { int z1 = (int)((1-t)*z3 + t*z4); int z2 = (int)((1-s)*z3 + s*z4); if (z1 < z2) { return true; } } return false; } public static void main(String[] args) { JFrame frame = new JFrame("Tetrahedron"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new Tetrahedron()); frame.pack(); frame.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { repaint(); } } ``` 在这个代码中,我们首先定义了正四面体的顶点坐标和连接关系,然后在 `paintComponent` 方法中计算出每个顶点在屏幕上的坐标。接着,我们绘制正四面体的边界,对于每条边,我们判断其是否需要进行透视投影和动态隐线算法。最后,在 `actionPerformed` 方法中更新角度并重绘图形。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值