• 模拟面试-1


    简述一下操作系统中的缺页中断

    缺页中断就是系统要访问的页不在内存中,需要操作系统将访问的页加载到内存中才能进行访问

    说一说你对volatile关键字的理解

    volatile用于保证内存的可见性,可以将其看做是轻量级的锁,它具有如下的内存语义:

    · 写内存语义:当写一个volatile变量时,JMM会把该线程本地内存中的共享变量的值刷新到主内存中。

    · 读内存语义:当读一个volatile变量时,JMM会把该线程本地内存置为无效,使其从主内存中读取共享变量。
    其中,JMM是指Java内存模型,而本地内存只是JMM的一个抽象概念,它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。在本文中,大家可以将其简单理解为缓存。
    volatile只能保证单个变量读写的原子性,而锁则可以保证对整个临界区的代码执行具有原子性。所以,在功能上锁比volatile更强大,在可伸缩性和性能上volatile更优优势。

    加分回答
    volatile的底层是采用内存屏障来实现的,就是在编译器生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。内存屏障就是一段与平台相关的代码,Java中的内存屏障代码都在Unsafe类中定义,共包含三个方法:LoadFence()、storeFence()、fullFence()。
    【延伸阅读】
    可见性是指一个线程对共享变量的修改,另外一个线程能够立刻看到。可见性问题是由CPU缓存导致的,每核CPU均有各自的缓存,这些缓存均要与内存进行同步。例如,线程A要修改内存中变量X,它需要先将变量X加载到本地缓存,修改缓存后再将缓存数据刷回内存中。在线程A修改本地缓存中变量X时,线程B可能也需要读/写内存中的变量X,为了让线程A的修改对线程B感知到,就可以在变量X前加上volatile来解决。

    在执行程序时,为了提高性能,编译器和处理器常常会对指令做重排序。重排序不会影响单线程的执行结果,但是在并发的情况下,可能会出现诡异的BUG。例如,instance = new Singleton(); 这行代码在执行时,会产生3条字节码指令,而这三条指令的顺序就可能会被编译器重排。CPU在执行指令时

    内存泄漏的问题如何解决

    内存泄漏,是指不再使用的对象仍然被引用,导致垃圾收集器无法回收它们的内存。由于不再使用的对象仍然无法清理,甚至这种情况可能会越积越多,最终导致致命的OutOfMemoryError,长生命周期的对象保持短生命周期对象的引用会导致内存泄漏。

    Redis有哪些数据类型

    它主要提供了5种数据类型:字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)。Redis还提供了Bitmap、HyperLogLog、Geo类型,但这些类型都是基于上述核心数据类型实现的。5.0版本中,Redis新增加了Streams数据类型,它是一个功能强大的、支持多播的、可持久化的消息队列。

    1. string可以存储字符串、数字和二进制数据,除了值可以是String以外,所有的键也可以是string,string最大可以存储大小为512M的数据。

    2. list保证数据线性有序且元素可重复,它支持lpush、blpush、rpop、brpop等操作,可以当作简单的消息队列使用,一个list最多可以存储2^32-1个元素。

    3. hash的值本身也是一个键值对结构,最多能存储2^32-1个元素。

    4. set是无序不可重复的,它支持多个set求交集、并集、差集,适合实现共同关注之类的需求,一个set最多可以存储2^32-1个元素。

    5. zset是有序不可重复的,它通过给每个元素设置一个分数来作为排序的依据,一个zset最多可以存储2^32-1个元素。

    算法题

    定义重复字符串是由两个相同的字符串首尾拼接而成。例如:“abcabc” 是一个长度为 6 的重复字符串,因为它由两个 “abc” 串拼接而成;“abcba” 不是重复字符串,因为它不能由两个相同的字符串拼接而成。

    给定一个字符串,请返回其最长重复子串的长度。

    若不存在任何重复字符子串,则返回 0。

    本题中子串的定义是字符串中一段连续的区间。

    数据范围:字符串长度不大于 10^3,保证字符串一定由小写字母构成。
    进阶:空间复杂度 ,时间复杂度

    思路:
    可以将两个字符串想像成两个连续的滑动窗口,并假设这个滑动窗口最大是字符串长度的一半,通过比较两个窗口的内容是否相同,不相同的时候不断从左向右平移,完了之后,还是不相同,这时候就将窗口的大小调小一点,直到找到一个相同的,这个时候窗口的长度×2就是最大字符串的大小

        public int solve (String a) {
            // write code here
            if(a.length() <= 1) {
                return 0;
            }
            char[] chars = a.toCharArray();
            // 控制窗口大小
            for(int window = a.length() / 2;window > 0;window--) {
                int last = window*2 -1;
                // 移动窗口
                int start = 0;
                while(last <= a.length()-1) {
                    last++;
                    // 遍历数据
                    boolean flag = true;
                    for(int i = start;i < start + window;i++) {
                        if(chars[i] != chars[i+window]) {
                            // 结束当前内层的for循环,进行下一次循环
                            flag = false;
                            continue;
                        }
                    }
                    start++;
                    if(flag == true) {
                        return window * 2;
                    }
                }
            }
            return 0;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    Flutter最新配置本地资源文件详解,报错看这篇文章就对了!
    2023-2028年中国六方氮化硼市场投资分析及前景预测报告
    【Redis】RedisTemplate序列化传输数据
    一、CSS文本样式[文本基础、文本样式、段落控制]
    优雅的c语言宏定义比较大小
    面试官:请说说什么是BFC?大白话讲清楚
    Mediapipe 实现3D人脸检测
    集群分布式储存
    读书笔记:《过度的医疗》
    Flink 1.11+ 版本如何生成 Watermark
  • 原文地址:https://blog.csdn.net/weixin_48412846/article/details/125881979