总结

难度:⭐⭐⭐⭐⭐ 学到的知识:⭐⭐⭐⭐☆

算法

题目描述

String转Long,需要考虑各种异常情况。
设计测试用例。

一些要点

Java中,int占4个字节,long占8个字节。以long为例,其取值范围为$$-2^{63}到2^{63}-1$$,不要轻易对下界取反,因为会溢出。 Java中提供了Long.MAX_VAlUE和Long.MIN_VALUE来获取long的上下界。 其他类型,byte(非bit)占1字节,short占2字节,float 4字节,double 8字节,char 2字节。 对象占几个字节?

Class MaNong { 
    int count;
    boolean flag;
    Object obj; 
}

对象头(8字节/16字节)+ int(4字节)+ boolean(1字节)+ 空引用(4字节/8字节)= 17字节。 Java对象内存分配时以8的整数分配(对齐填充,以提高访问速度),故会分配24字节。 其中空引用类型,32位jvm是4字节,64位jvm是8字节,如果启动了压缩oops(限制堆大小,最大让其寻址32G内存),仍可能是4字节。 包装类占几个字节? 和对象一样,对象头 + 基本数据类型 + 对齐填充。

代码

public class BilibiliExamThree {

    public static void main(String[] args) {
        try {
            System.out.println(StringToLong("1234"));
            System.out.println(StringToLong("-12233"));
            System.out.println(StringToLong("9223372036854775807"));
            System.out.println(StringToLong("9223372036854775809")); //溢出
            System.out.println(StringToLong("+"));
            System.out.println(StringToLong("122c2234a"));
            System.out.println(StringToLong("abc"));
            System.out.println(StringToLong(""));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static long StringToLong(String string) throws Exception {
        if (string == null || string.trim().isEmpty()) {
            throw new NumberFormatException("输入的字符串为空,或仅包含空白字符");
        }
        string = string.trim();
        long res = 0;
        boolean isNegative = false;
        int start = 0;
        if (string.charAt(0) == '-' || string.charAt(0) == '+') {
            start = 1;
            if (string.charAt(0) == '-') isNegative = true;
        }

        if (start == 1 && string.length() == 1) {
            throw new Exception("输入的字符串仅包含正负号。");
        }

        // MIN_VALUE的绝对值大于MAX_VALUE,不能对MIN_VALUE取反,否则会溢出
        long limit = isNegative ? Long.MIN_VALUE : -Long.MAX_VALUE;
        long multmin = limit / 10;

        for (int i = start; i < string.length(); i++) {
            char ch = string.charAt(i);

            //判断是否是否合法
            if (ch < '0' || ch > '9') {
                throw new NumberFormatException("输入的字符串不合法");
            }

            // 判断是否超过long类型的界限
            if (res < multmin) {
                throw new NumberFormatException("超过long类型的界限。");
            }
            res *= 10;

            // 判断是否超过long类型的界限
            int nextDigit = ch - '0';
            if (res < limit + nextDigit) {
                throw new NumberFormatException("超过long类型的界限。");
            }
            res -= nextDigit;

        }

        if (!isNegative) res = -res;
        return res;

    }
}

数据库

1. 写一段会让数据库死锁的代码?

在互相持有对方需要的资源,且资源独占时会死锁。

-- 会话1
start transaction;
update tableA set id = 2 where id = 1;

--会话2
start transaction;
update tableB set id = 2 where id = 1;
update tableA set id = 3 where id = 2; -- 这里会等待,因为会话1已经将这行锁定

--回到会话1
update tableB set id = 3 where id = 2; --这里会产生死锁,因为会话2已经将这行锁定
-- 
innodb有一个死锁检测机制,他在检测到死锁时,会中断其中一个事务,从而解决死锁。上述两个事务中,其中一个会收到死锁的错误消息。

操作系统

1. 什么是哲学家就餐问题?如何解决?--mark,看视频学习下

并发和死锁问题。 解决方式:

  1. 仲裁串行化:任何时候只有一个哲学家在尝试拿叉子
  2. 限制同时尝试的哲学家数量:每次最多4位哲学家就餐(总共5个),这样至少有一个哲学家会成功。
  3. 随机等待:如果不能拿到全部的叉子,则随机等待一段时间再尝试
  4. 资源分级

数据结构

1. 如何设计一个哈希表?

  1. 选择哈希函数
  • 好的哈希函数是关键,将输入均匀地映射到哈希表的索引。
  • 快速计算,保持哈希表操作的高效性
  1. 数组或桶来存储数据
  2. 处理哈希冲突
  • 链地址法
  • 开放寻址法(顺序,跳跃,双重哈希)
  1. 动态调整大小
  • 在加载因子超过一定的阈值,需要进行扩容。
  1. 删除操作
  • 如果在开放定址法中,会标记已删除,如果直接删除,会中断其他键的探测序列。
  1. 其他:
  • 设计合理的加载因子阈值
  • 安全性:使用加密哈希函数或其他安全措施来避免恶意攻击(例如故意制造哈希冲突)

2. 如何解决哈希冲突?

  • 开放寻址
  • 链地址法

网络

1. 服务器发送rst的情况?

rst(reset)包是一种特殊的包,用于快速、无条件的终止连接,而无需tcp正常的终止序列(fin握手),在以下情况中使用。

  1. 异常关闭:当一个端点检测到连接中的错误或异常,可能会发送一个rst包来立即终止连接。
  2. 非预期的数据:如果一个端点接收到它不期望的数据(比如,认为连接已经关闭,但突然收到了数据,半开问题),他会回应一个rst包。

2. tcp如何只允许单方面发送消息?

通过tcp的半关闭或半开来实现,允许一个方向上的数据传输被关闭,另一个方向的数据传输保持打开。

  1. 半关闭 - tcp的正常特性 四次挥手中,客户端发送了fin报文,但是接收端仍有数据要发送,不发送fin报文,来保持办关闭状态。
  2. 半开 - 异常状态 由网络问题或其他中断导致。 半开状态中,一方认为连接仍然是打开并尝试发送数据,而另一方认为连接已经关闭。 这种状态是由FIN或RST包在网络中丢失导致的。 半开连接会导致资源泄露或其他问题,因为其中一方会为它认为仍然打开的链接保持资源。 半开状态下,若客户端已经断开,服务器不知道连接关闭,服务器尝试向客户端发送数据时,客户端会响应一个RST包。 解决:许多服务器有超时机制,如果一段时间内没有从连接中接收到任何数据,会自动关闭连接。

python

1. python多线程有什么问题?

python的实现中,使用了GIL互斥锁,来防止多个线程同时执行python字节码,也就说在任何给定的时间点,只有一个线程可以在解释器中执行。 由于gil的存在,多线程在cpu密集型任务上不会提供的预期的性能提升,因为线程不能并行的在多个cpu核心上运行。

python为什么要引入GIL呢?

  • 取消复杂的锁机制,并提升了单线程程序的性能。
  • cpython的内存管理使用的是引用计数,对引用计数的增减需要同步,GIL可以确保在任何时候只有一个线程能够修改引用计数。
  • 历史原因:GIL最初被引入时,多核cpu并不那么普及。(GIL在90年代引入,盛业多核cpu在2001发布。)
  • 早期的c扩展和库并不是线程安全,GIL提供一种方式来确保这些库在多线程环境中安全使用,而无需大量修改。

如何解决了GIL存在的问题?

  1. 使用其他Python实现,jpython,ironpython
  2. 使用多进程
  3. 子解释器,创建多个解释器,每个解释器有自己的GIL

django

1. django的设计思路是什么?

dango的设计思路是提供一个全面、集成的框架,让开发者可以快速、快速地开发出健壮、安全、可维护的web应用。 几个关键点:

  1. MTV架构
    • Model:数据结构,数据库操作
    • Template:在web页面中显示数据,定义了静态部分和动态部分的呈现方式
    • View: 如何处理用户的输入并返回适当的响应。
  2. DRY:鼓励代码重用
  3. 约定由于配置:允许开发者快速开始而无需进行大量配置。
  4. 简化开发任务:内置轻量级web服务器、自动化的数据库迁移工具,管理界面生成器,这些都可以简化开发任务
  5. 可扩展性: 使用模块化的设计,开发者可以轻松地添加自己的应用程序或使用第三方应用。

松散耦合的体现

  1. 视图和模板逻辑分开,视图负责处理业务逻辑和决定哪些数据需要显示,而模板负责如何显示这些数据,因为视图和模板逻辑分开,可以独立修改和测试。
  2. 鼓励开发者构造可重用的应用程序,例如可以为用户身份验证创建一个应用程序,可以在多个Django项目中重用,而不需要做大量的更改。

MTV与MVC的不同? 主要讲一下MVC的各部分。 Model:一致,都是数据存储、检索和业务逻辑 View:如何将数据展示给用户,很多都是模板+数据 Controller:负责接收用户的请求,调用模型进程数据操作,然后选择使用哪个视图来显示结果给用户。

都是为了责任分离,django更强调模板,他只用于定义如何显示内容,而不涉及决定哪些内容要显示。

其他

1. 最近在看的一本书?讲下印象最深刻的地方?

《代码整洁之道》 "最好额注释是不需要注释的代码" "代码并不补偿糟糕的代码" "当代码无法明确地传达某个意图或背后的原因时,注释是有用的,例如解释某个复杂算法的原理或者为什么采取非常规的做法。" "避免误导性的代码,保证代码和注释一致,错误过时的注释比没有注释还操作" "不要在注释中重复代码,比如对代码做字面翻译" "函数和变量的良好命名可以减少对注释的需求。"