记录阿里的一次电话面!

前几天做了个阿里的笔试,但谁能想到好难啊,就两道算法题,一道也没做出来…原本想着肯定也凉凉了, 知道自己欠缺的太多了,努力努力吧(ps.找实习)

就在昨日心漫漫,意外收到了一通电话,很是惊奇和兴奋,哈哈哈让后就开始了
首先是自我介绍(略,说的可能也不太好,没有准备模板就随意说的)

然后是一个链表的题目(如果想删除一个结点该怎么做)

下面是我的解题思路:
一:(找出要删除结点的前一个节点)

  1. 首先应该想到的是要删除哪一个结点(是正数第k个还是倒数第k个,还是给你的结点)都要自己问一下
  2. 知道具体题意,要求再下手,首先想到的就是遍历,找到要删除的结点,将 删除结点的前一个next指针指向,删除结点的next指针指向的结点,完成删除

二: (不用知道前面的结点是什么就可以)

  1. 直接找到要删除的那个节点,然后将后面节点的值赋给要删除的那个节点,再讲要删除的结点的next指针指向要删除的结点的next.next.

然后是一个socket的问题(大概是问怎么通信的吧)

Java Socket 编程,分为Socket 和ServerSocket两个类,其中Client 通过构造Socket 实例,向Server 端的ServerSocket发起请求。 ServerSocket 在接受到来自Client 的请求后,构建一个Socket,并将响应内容通过这个Socket实例返回。

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket=null;
        Socket socket =null;
        InputStream is =null;
        ByteArrayOutputStream baos =null;
        try {
            //要有一个地址
            serverSocket =new ServerSocket(9090);
            //等待客户端连接
            socket = serverSocket.accept();
            //读取客户端的消息
            is = socket.getInputStream();

            //管道流
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len =is.read(buffer))!=-1){
                baos.write(buffer,0,len);
            }
            System.out.println(baos.toString());
            
;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
        baos.close();
        is.close();
        socket.close();
        serverSocket.close();
        }
    }
}
public class TCPClient {
    public static void main(String[] args) throws IOException {
        OutputStream os =null;
        Socket socket =null;

        try {
            //要有一个端口和 ip地址
            InetAddress serverIp = InetAddress.getByName("127.0.0.1");
            int port =9090;
            //创立socket连接
            socket =new Socket(serverIp,port);
            //发消息 IO流
            os = socket.getOutputStream();
            os.write("你好啊我的socket程序".getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            os.close();
            socket.close();
        }

    }
}

在这里插入图片描述

然后紧接着就是OSI模型(问的tcp/ip是在那一层)

TCP/IP对OSI的网络模型层进行了划分如下:
在这里插入图片描述
TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中
  应用层:TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 等等
  传输层:TCP,UDP
  网络层:IP,ICMP,OSPF,EIGRP,IGMP
  数据链路层:SLIP,CSLIP,PPP,MTU
  每一抽象层建立在低一层提供的服务上,并且为高一层提供服务,看起来大概是这样子的
  在这里插入图片描述

然后问的是synchronized和lock锁的区别

(就想着玩赛车的例子,好比手动挡和自动挡)当然大神都是用的手动
1、Synchronized 内置的Java关键字, Lock 是一个Java类
2、Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3、Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
4、Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下
去;
5、Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可自己设置);
6、Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!

提到了效率问题,那么一定synchronized就比lock锁效率低?

Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码

  1. 单线程: 可见Lock的运行时间比synchronized略大。可以推测java编译器为synchronized做了特别优化。
  2. 多线程: 由代码可以看出在多线程环境并存在大量竞争的情况下,synchronized的用时迅速上升,而lock却依然保存不变或增加很少。

ps. 这里就不放代码了

Lock是用CAS(compare and swap)来实现的
JDK 1.6以上synchronized也改用CAS来实现了,所以两者性能差不多
Lock提供的功能丰富点,synchronized的使用简单点

提到了重入锁,那么什么是可重入锁??

可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁.
巴拉巴拉一堆(好比,人进入一个房间,有很多的们,可以获取里面门的锁)

结语:

  1. 我认为问的还是比较简单的吧,可能因为我是非科班的…
  2. 问的过程确实是全程紧张的,效率也是很高的,通过回复问答,查漏补缺,提高自己对知识盲区的学习,果然算法还是非常的重要!
  3. 确实发现自己还有很长的路要走,不以物喜不以己悲,平常心,这只是起点!
  4. 对自己的一句话 加油!

猜你喜欢

转载自blog.csdn.net/weixin_45399846/article/details/105383239