Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >输了!广州某小厂一面,也凉了

输了!广州某小厂一面,也凉了

作者头像
小林coding
发布于 2024-05-28 04:29:09
发布于 2024-05-28 04:29:09
24901
代码可运行
举报
文章被收录于专栏:小林coding小林coding
运行总次数:1
代码可运行

图解学习网站:https://xiaolincoding.com

大家好,我是小林。

之前「后端面经」系列已经分享过北京、深圳、上海等地方的小厂面经,有同学想看看广州的。

那么今天来分享一个广州小厂的Java后端面经,面试问了 40 分钟,除了拷打项目的问题,还问了一些技术面试题。

不算难,可惜同学一些问题没有回答好,最后还是挂了,其实面试官人很好,整个交流也比较舒服,是自己太菜了。

考察的范围:Java 基础、Java 集合、Java 并发、Spring、Linux 这些知识点。无算法,MySQLRedis 、网络、系统也都没有问。

面试八股

Arraylist和LinkedList区别

  • 底层数据结构:ArrayList使用数组作为底层数据结构,而LinkedList使用双向链表作为底层数据结构
  • 随机访问性能:ArrayList支持通过索引直接访问元素,因为底层数组的连续存储特性,所以时间复杂度为O(1)。而LinkedList需要从头或尾部开始遍历链表,时间复杂度为O(n)。
  • 插入和删除操作:ArrayList在尾部插入和删除元素的时间复杂度为O(1),因为它只需要调整数组的长度即可。但在中间或头部插入和删除元素时,需要将后续元素进行移动,时间复杂度为O(n)。而LinkedList在任意位置插入和删除元素的时间复杂度为O(1),因为只需要调整节点的指针即可。
  • 内存占用:ArrayList在每个元素中都存储了实际的数据,而LinkedList在每个节点中存储了数据和前后节点的指针。因此,相同数量的元素情况下,LinkedList通常比ArrayList占用更多的内存空间。

ArrayList的扩容机制说一下

ArrayList在添加元素时,如果当前元素个数已经达到了内部数组的容量上限,就会触发扩容操作。ArrayList的扩容操作主要包括以下几个步骤:

  • 计算新的容量:一般情况下,新的容量会扩大为原容量的1.5倍(在JDK 10之后,扩容策略做了调整),然后检查是否超过了最大容量限制。
  • 创建新的数组:根据计算得到的新容量,创建一个新的更大的数组。
  • 将元素复制:将原来数组中的元素逐个复制到新数组中。
  • 更新引用:将ArrayList内部指向原数组的引用指向新数组。
  • 完成扩容:扩容完成后,可以继续添加新元素。

ArrayList的扩容操作涉及到数组的复制和内存的重新分配,所以在频繁添加大量元素时,扩容操作可能会影响性能。为了减少扩容带来的性能损耗,可以在初始化ArrayList时预分配足够大的容量,避免频繁触发扩容操作。

之所以扩容是 1.5 倍,是因为 1.5 可以充分利用移位操作,减少浮点数或者运算时间和运算次数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 新容量计算
int newCapacity = oldCapacity + (oldCapacity >> 1);

线程安全的 List, CopyonWriteArraylist是如何实现线程安全的

CopyOnWriteArrayList底层也是通过一个数组保存数据,使用volatile关键字修饰数组,保证当前线程对数组对象重新赋值后,其他线程可以及时感知到。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private transient volatile Object[] array;

在写入操作时,加了一把互斥锁ReentrantLock以保证线程安全。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public boolean add(E e) {
    //获取锁
    final ReentrantLock lock = this.lock;
    //加锁
    lock.lock();
    try {
        //获取到当前List集合保存数据的数组
        Object[] elements = getArray();
        //获取该数组的长度(这是一个伏笔,同时len也是新数组的最后一个元素的索引值)
        int len = elements.length;
        //将当前数组拷贝一份的同时,让其长度加1
        Object[] newElements = Arrays.copyOf(elements, len + 1);
        //将加入的元素放在新数组最后一位,len不是旧数组长度吗,为什么现在用它当成新数组的最后一个元素的下标?建议自行画图推演,就很容易理解。
        newElements[len] = e;
        //替换引用,将数组的引用指向给新数组的地址
        setArray(newElements);
        return true;
    } finally {
        //释放锁
        lock.unlock();
    }
}

看到源码可以知道写入新元素时,首先会先将原来的数组拷贝一份并且让原来数组的长度+1后就得到了一个新数组,新数组里的元素和旧数组的元素一样并且长度比旧数组多一个长度,然后将新加入的元素放置都在新数组最后一个位置后,用新数组的地址替换掉老数组的地址就能得到最新的数据了。

在我们执行替换地址操作之前,读取的是老数组的数据,数据是有效数据;执行替换地址操作之后,读取的是新数组的数据,同样也是有效数据,而且使用该方式能比读写都加锁要更加的效率。

现在我们来看读操作,读是没有加锁的,所以读是一直都能读

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public E get(int index) {
    return get(getArray(), index);
}

Stream流的并行API是什么?

是 ParallelStream。

并行流(ParallelStream)就是将源数据分为多个子流对象进行多线程操作,然后将处理的结果再汇总为一个流对象,底层是使用通用的 fork/join 池来实现,即将一个任务拆分成多个“小任务”并行计算,再把多个“小任务”的结果合并成总的计算结果

Stream串行流与并行流的主要区别:

对CPU密集型的任务来说,并行流使用ForkJoinPool线程池,为每个CPU分配一个任务,这是非常有效率的,但是如果任务不是CPU密集的,而是I/O密集的,并且任务数相对线程数比较大,那么直接用ParallelStream并不是很好的选择。

底层使用线程池的核心线程数

ParallelStream 底层使用了 ForkJoinPool 线程池。

ForkJoinPool 与 ThreadPoolExecutor 是完全不同的实现机制。ForkJoinPool 有四个参数可以设置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public ForkJoinPool(int parallelism,
                        ForkJoinWorkerThreadFactory factory,
                        UncaughtExceptionHandler handler,
                        boolean asyncMode) {
        this(checkParallelism(parallelism),
             checkFactory(factory),
             handler,
             asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
             "ForkJoinPool-" + nextPoolId() + "-worker-");
        checkPermission();
    }

但其实关键参数也只有一个线程数 parallelism(并行度,默认为CPU数,最小为1),其它参数影响不大。ForkJoinPool 机制特殊,每个线程都有自己独立的队列,并且没有核心线程和最大线程的概念。ForkJoinPool 线程数的设置很简单,分 cpu 密集型任务和 io 密集型任务两种情况考虑。对于 cpu 密集型任务,建议都用静态的 commonPool(线程数为 CPU 核心数 - 1,JDK 已经设置好了)原因是,如果 new 出多各 ForkJoinPool:

  • 浪费内存:ForkJoinPool 内存占用与线程数成正比,而且还挺大,可以计算,一个队列一个 ForkJoinTask 数组,数组初始容量就有 2^13,存储的是 ForkJoinTask 引用,一个对象引用占用 4 字节,那么一个队列占用 2^13 * 4 + 8 Byte 约等于 32 KB,如果设置了 16 线程,那么会有 32 个队列(大于等于线程数的最小 2 的 n 次幂乘 2),也就是 1M,多一个 16 线程的 ForkJoinPool 仅队列自身,一个任务都没有就多占用 1M 内存,再加上拆分出一堆子任务占用内存更多;
  • 影响性能:多占用内存,不仅没有性能提升,反而可能有性能损耗,cpu 密集型任务线程数最多也就 cpu 核心数,再多除了增加线程上下文切换次数没什么意义。

对于 io 密集型任务,线程数设置逻辑与 ThreadPoolExecutor 类似,队列容量无限大不可设置,在此基础上寻找合适的线程数即可。

CPU密集型和IO密集型 N+ 1 2N 具体是如何计算的?

N代表的是 CPU核数

  • CPU密集型:corePoolSize = CPU核数 + 1
  • IO密集型:corePoolSize = CPU核数 * 2

在《Java并发编程实践》中,是这样来计算线程池的线程数目的:

这种计算方式,我们需要知道上面定义的几个数值,才能计算出来线程池需要设置的线程数。其中,CPU数量是确定的,CPU使用率是目标值也是确定的,W/C也是可以通过基准程序测试得出的。

对于计算密集型应用,假定等待时间趋近于0,是的CPU利用率达到100%,那么线程数就是CPU核心数,那这个+1意义何在呢?《Java并发编程实践》这么说:

计算密集型的线程恰好在某时因为发生一个页错误或者因其他原因而暂停,刚好有一个“额外”的线程,可以确保在这种情况下CPU周期不会中断工作。

所以 N+1 是一个经验值。

那么对于对于IO密集型应用,假定所有的操作时间几乎都是IO操作耗时,那么W/C的值就为1,那么对应的线程数确实为2N。

说一下你对 spring的IOC 的理解

IOC:Inversion Of Control,即控制反转,是一种设计思想。在传统的 Java SE 程序设计中,我们直接在对象内部通过 new 的方式来创建对象,是程序主动创建依赖对象;

而在Spring程序设计中,IOC 是有专门的容器去控制对象。

所谓控制就是对象的创建、初始化、销毁。

  • 创建对象:原来是 new 一个,现在是由 Spring 容器创建。
  • 初始化对象:原来是对象自己通过构造器或者 setter 方法给依赖的对象赋值,现在是由 Spring 容器自动注入。
  • 销毁对象:原来是直接给对象赋值 null 或做一些销毁操作,现在是 Spring 容器管理生命周期负责销毁对象。

总结:IOC 解决了繁琐的对象生命周期的操作,解耦了我们的代码。所谓反转:其实是反转的控制权,前面提到是由 Spring 来控制对象的生命周期,那么对象的控制就完全脱离了我们的控制,控制权交给了 Spring 。这个反转是指:我们由对象的控制者变成了 IOC 的被动控制者。

spring 三级缓存是什么?

三级缓存主要是为了解决单例模式下的循环依赖的问题。

循环依赖指的是两个类中的属性相互依赖对方:例如 A 类中有 B 属性,B 类中有 A属性,从而形成了一个依赖闭环,如下图。

循环依赖问题在Spring中主要有三种情况:

  • 第一种:通过构造方法进行依赖注入时产生的循环依赖问题。
  • 第二种:通过setter方法进行依赖注入且是在多例(原型)模式下产生的循环依赖问题。
  • 第三种:通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题。

只有【第三种方式】的循环依赖问题被 Spring 解决了,其他两种方式在遇到循环依赖问题时,Spring都会产生异常。

Spring 解决单例模式下的setter循环依赖问题的主要方式是通过三级缓存解决循环依赖。三级缓存指的是 Spring 在创建 Bean 的过程中,通过三级缓存(缓存的底层都是Map)来缓存正在创建的 Bean,以及已经创建完成的 Bean 实例。具体步骤如下:

  • 实例化 Bean:Spring 在实例化 Bean 时,会先创建一个空的 Bean 对象,并将其放入一级缓存中。
  • 属性赋值:Spring 开始对 Bean 进行属性赋值,如果发现循环依赖,会将当前 Bean 对象提前暴露给后续需要依赖的 Bean(通过提前暴露的方式解决循环依赖)。
  • 初始化 Bean:完成属性赋值后,Spring 将 Bean 进行初始化,并将其放入二级缓存中。
  • 注入依赖:Spring 继续对 Bean 进行依赖注入,如果发现循环依赖,会从二级缓存中获取已经完成初始化的 Bean 实例。

通过三级缓存的机制,Spring 能够在处理循环依赖时,确保及时暴露正在创建的 Bean 对象,并能够正确地注入已经初始化的 Bean 实例,从而解决循环依赖问题,保证应用程序的正常运行。

三级缓存都是CurrentHashMap吗?

不是,只有一级用了ConcurrentHashMap,二级和三级用的是HashMap。

Spring利用三级Bean缓存的方式解决Bean循环依赖的问题,三级缓存也就是DefaultSingletonBeanRegistry中的三个Map:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/** Cache of singleton objects: bean name to bean instance. 一级缓存*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
 
/** Cache of early singleton objects: bean name to bean instance. 二级缓存*/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
 
/** Cache of singleton factories: bean name to ObjectFactory. 三级缓存*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  • singletonObjects:一级缓存,存放完整的Bean;
  • earlySingletonObjects:二级缓存,存放早期Bean,即还没有设置属性的Bean;
  • singletonFactories:三级缓存,存放ObjectFactory对象,即Bean的生产工厂。

但是在 spring 2.7.10新版本开始,earlySingletonObjects(二级缓存)改成使用 ConcurrentHashMap。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/** Cache of singleton objects: bean name to bean instance. 一级缓存 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of early singleton objects: bean name to bean instance. 二级缓存 */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

/** Cache of singleton factories: bean name to ObjectFactory. 三级缓存 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

Linux的常用命令了解过哪些?

  • 文件相关(mv mkdir cd ls)
  • 进程相关( ps top netstate )
  • 权限相关(chmod chown useradd groupadd)
  • 网络相关(netstat ip addr)
  • 测试相关(测试网络连通性:ping 测试端口连通性:telnet)

查找日志中某个字符的长度?

要在 Linux 中查找日志文件中某个字符的长度,你可以使用一些工具和命令来实现。其中,grep 是一个强大的命令行工具,可以用于在文件中查找匹配指定模式的行。你也可以结合一些其他命令来完成这个任务,如 awk 或者 sed。以下是一个示例命令,用于查找日志文件中某个字符的长度:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
grep "search_string" log_file | awk '{ print length }'

在这个命令中:

  1. grep "search_string" log_file 会找到日志文件中包含 "search_string" 的所有行。
  2. awk '{ print length }' 会输出每一行的长度,即搜索到的 "search_string" 的长度。

如果你想查找日志文件中单个字符的长度,你可以直接使用 grep 命令配合 wc 命令来实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
grep "c" log_file | wc -m

这个命令会计算搜索到的字符 "c" 在日志文件中出现的次数。

深拷贝和浅拷贝区别是什么?

image.png

  • 浅拷贝是指只复制对象本身和其内部的值类型字段,但不会复制对象内部的引用类型字段。换句话说,浅拷贝只是创建一个新的对象,然后将原对象的字段值复制到新对象中,但如果原对象内部有引用类型的字段,只是将引用复制到新对象中,两个对象指向的是同一个引用对象。
  • 深拷贝是指在复制对象的同时,将对象内部的所有引用类型字段的内容也复制一份,而不是共享引用。换句话说,深拷贝会递归复制对象内部所有引用类型的字段,生成一个全新的对象以及其内部的所有对象。

实现深拷贝的三种方法是什么?

在 Java 中,实现对象深拷贝的方法有以下几种主要方式:

实现 Cloneable 接口并重写 clone() 方法

这种方法要求对象及其所有引用类型字段都实现 Cloneable 接口,并且重写 clone() 方法。在 clone() 方法中,通过递归克隆引用类型字段来实现深拷贝。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyClass implements Cloneable {
    private String field1;
    private NestedClass nestedObject;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        MyClass cloned = (MyClass) super.clone();
        cloned.nestedObject = (NestedClass) nestedObject.clone(); // 深拷贝内部的引用对象
        return cloned;
    }
}

class NestedClass implements Cloneable {
    private int nestedField;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

使用序列化和反序列化

通过将对象序列化为字节流,再从字节流反序列化为对象来实现深拷贝。要求对象及其所有引用类型字段都实现 Serializable 接口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.io.*;

class MyClass implements Serializable {
    private String field1;
    private NestedClass nestedObject;
    
    public MyClass deepCopy() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            oos.flush();
            oos.close();
            
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (MyClass) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }
}

class NestedClass implements Serializable {
    private int nestedField;
}

手动递归复制

针对特定对象结构,手动递归复制对象及其引用类型字段。适用于对象结构复杂度不高的情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class MyClass {
    private String field1;
    private NestedClass nestedObject;

    public MyClass deepCopy() {
        MyClass copy = new MyClass();
        copy.setField1(this.field1);
        copy.setNestedObject(this.nestedObject.deepCopy());
        return copy;
    }
}

class NestedClass {
    private int nestedField;

    public NestedClass deepCopy() {
        NestedClass copy = new NestedClass();
        copy.setNestedField(this.nestedField);
        return copy;
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小林coding 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
rbpf虚拟机-即时编译器(JIT)
本文记录的是基于 x86-64 架构的 eBPF(Extended Berkeley Packet Filter)即时编译器(JIT)。
盹猫
2025/07/22
700
一文读懂eBPF|即时编译(JIT)实现原理
在《eBPF实现原理》一文中,我们介绍了 eBPF 的实现原理,这篇文章我们主要介绍 eBPF 运行加速器 JIT(Just In Time)的实现原理。
用户7686797
2022/05/17
3.5K0
一文读懂eBPF|即时编译(JIT)实现原理
PyTorch 源码解读之即时编译篇
来源丨https://zhuanlan.zhihu.com/p/361101354
BBuf
2021/07/01
1.3K0
PyTorch 源码解读之即时编译篇
PyTorch 2.0 之 Dynamo: 窥探加速背后的真相
PyTorch 2.0 算是正式官宣了,预计在明年 3 月和大家见面。官方的 blog 宣发了非常多的内容,但是阅读下来不难发现,几乎所有的性能提升、体验优化都源自于 PyTorch 新设计的即时编译工具:Dynamo。
OpenMMLab 官方账号
2022/12/30
2.8K0
PyTorch 2.0 之 Dynamo: 窥探加速背后的真相
Rc-lang开发周记4 函数其一
这里我一开始没想好怎么做的,所以会做的很诡异,最大的原因是静态类型语言和动态类型语言是不同的。由于我只对动态语言有一些了解,这里暂时只提动态语言的一些点
AkemiHomura
2023/04/07
3170
太强了!鹅厂程序员“自研”脚本语言 eben
计算机科学家 David Wheeler 有一句名言,“All problems in computer science can be solved by another level of indirection, except for the problem of too many layers of indirection.”。大意是指,计算机科学中所有问题都可以通过多一个间接层来解决,除了间接层太多这个问题本身。
腾讯云开发者
2023/10/19
1.3K0
太强了!鹅厂程序员“自研”脚本语言 eben
TorchScript 系列解读 (二):Torch jit tracer 实现解析
小伙伴们好呀,TorchScript 解读系列教程更新啦~在上篇文章中,我们带领大家初步了解了 TorchScript。
OpenMMLab 官方账号
2022/04/09
1.8K0
TorchScript 系列解读 (二):Torch jit tracer 实现解析
堆、栈、方法区到底是什么?一文带你搞懂 JVM 运行时数据区内存模型!
在 JVM 的世界中,运行时数据区域是整个虚拟机的基础,它决定了程序的内存管理、线程的执行流以及垃圾回收的核心逻辑。
码哥字节
2024/11/26
8060
堆、栈、方法区到底是什么?一文带你搞懂 JVM 运行时数据区内存模型!
idapython使用笔记
You have chosen to enable IDAPython 2. The IDAPython 3 plugins have been renamed to idapython.3.disabled and idapython64.3.disabled in the plugins subdirectory. If you want to switch to IDAPython 3, proceed as follows:
用户1879329
2023/02/27
1.5K0
idapython使用笔记
eBPF原理介绍与编程实践
注:本文包括了ebpf的原理介绍、流程分析、相关资料链接、工具编写实战等,可以选择感兴趣的部分直接阅读;鉴于作者语文水平有限,很多地方描述可能不清楚,有错误或疑问欢迎指出交流
johnazhang
2022/07/18
2.8K1
用 go 实现 lua 虚拟机
下面依次介绍上面的一些步骤,本文旨在一篇文章写清楚大概流程,具体的细节将会忽略,实际的实现也会尽可能的简化,本文主要参考 自己动手实现 lua,和 gopher-lua
王磊-字节跳动
2020/12/27
2.2K0
Rc-lang开发周记2 VM相关
本周主要先对tac的函数进行了简单的测试,以确保能够正确运行我的vm demo,修正了function的一些问题,之后就是处理对vm指令的生成,处理了一下符号相关的信息,还做了一点函数的相关的以及生成C++的解析代码(都没做完,还是下周吧
AkemiHomura
2023/04/07
5260
用沐神的方法阅读PyTorch FX论文
【GiantPandaCV导语】torch.fx对于PyTorch来说确实是一个比较好的工作,因为它消除了一些动态图和静态图的Gap。比如在图改写方面,torch.fx让PyTorch想做一些其它静态图框架的算子融合优化非常容易。并且torch.fx让后训练量化和感知训练量化以及AMP等的实现难度大大降低,这得益于我们可以直接在Python层操作这个IR,所以我认为这是一个不错的工作。尤其是对使用PyTorch开发的算法工程师来说,现在可以基于这个特性大开脑洞了。我之前围绕FX也做了一个QAT的工作,感兴趣可以阅读:基于OneFlow实现量化感知训练。torch.fx的卖点就是,它使用纯Python语言实现了一个可以捕获PyTorch程序的计算图并转化为一个IR的库,并且非常方便的在这个IR上做Pass,同时提供将变换后的IR Codegen合法的Python代码功能。我觉得算是达到了在Eager下写Pass就像做链表插入删除题目一样顺滑。
BBuf
2021/12/27
9150
用沐神的方法阅读PyTorch FX论文
【精通 JVM 原理】浅析 JavaAgent & Instrumentation 机制
1、JVM的字节码指令,方法调用机制 2、Java类加载器 3、JavaAgent 4、Java Instrumentation
一个会写诗的程序员
2021/04/04
1.5K0
【AI系统】AI编译器前瞻
本文首先会基于 The Deep Learning Compiler: A Comprehensive Survey 中的调研做一个热门 AI 编译器的横向对比,并简要介绍几个当前常用的 AI 编译器。随后会分析当前 AI 编译器面临的诸多挑战,并展望 AI 编译器的未来。
用户11307734
2024/11/28
4750
一文带你学明白java虚拟机:C1编译器,HIR代码优化
为了减少编译时间,C1在抽象解释生成HIR期间,每生成一条SSA指令,都会调用append_with_bci努力尝试若干局部优化。除此之外,HIR构造完成之后,C1还会执行若干轻量级全局优化。本节将详细描述这些优化的执行过程。这些优化都位于build_hir()。
愿天堂没有BUG
2022/10/28
9870
一文带你学明白java虚拟机:C1编译器,HIR代码优化
《Python 源码剖析》一些理解以及勘误笔记(1)
以下是本人阅读此书时理解的一些笔记,包含一些影响文义的笔误修正,当然不一定正确,贴出来一起讨论。 注:此书剖析的源码是2.5版本,在python.org 可以找到源码。纸质书阅读,pdf 贴图。 文章
s1mba
2017/12/26
1.1K0
《Python 源码剖析》一些理解以及勘误笔记(1)
浅谈机器学习模型推理性能优化
在机器学习领域,清晰明了的数据预处理和表现优异的模型往往是数据科学家关注的重点,而实际生产中如何让模型落地、工程化也同样值得关注,工程化机器学习模型避不开的一个难点就是模型的推理(Inference / Serving)性能优化。
ThoughtWorks
2021/01/08
1.3K0
Android虚拟机的JIT编译器
最近参加了华为方舟的Workshop,从编译到Runtime都有了一些体会,并且对于虚拟机的运行也有了一些了解。
None_Ling
2019/06/14
1.6K0
Android虚拟机的JIT编译器
一文教你搞懂 Go 中栈操作
多任务操作系统中的每个进程都在自己的内存沙盒中运行。在32位模式下,它总是4GB内存地址空间,内存分配是分配虚拟内存给进程,当进程真正访问某一虚拟内存地址时,操作系统通过触发缺页中断,在物理内存上分配一段相应的空间再与之建立映射关系,这样进程访问的虚拟内存地址,会被自动转换变成有效物理内存地址,便可以进行数据的存储与访问了。
luozhiyun
2021/04/05
1.1K0
推荐阅读
相关推荐
rbpf虚拟机-即时编译器(JIT)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验