前言:
当前兄弟们对“intrinsic的优化技术”大约比较关怀,同学们都需要学习一些“intrinsic的优化技术”的相关内容。那么小编同时在网摘上网罗了一些关于“intrinsic的优化技术””的相关文章,希望同学们能喜欢,我们快快来了解一下吧!Java
1. Java线程安全?
并发编程,多个线程操作同一个对象,多个线程中的操作执行顺序是不可预测的。只有在共享数据的情况下,才会有线程安全问题;ArrayList是非线程安全的,Vector是线程安全的;HashMap是非线程安全的,HashTable是线程安全的;StringBuilder是非线程安全的,StringBuffer是线程安全的。
线程安全性:原子性,有序性,可见性
可见性:当读和写发生在不同的线程中的时候,就可能导致可见性问题
原子性:操作不可分割,不可拆分的原子过程。更新的丢失
2.Java多线程知识点
多线程能够合理的利用多核心CPU资源,实现多任务的并行处理,提高程序的吞吐量
线程:CPU执行的最小单位
进程:对计算机资源分配的最小单位
并行:当执行线程数少于CPU核的线程数,多个CPU实例执行一个处理逻辑
并发:单位时间内同时执行的线程数大于CPU核的线程数,体现系统的处理能力
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;
资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
线程是处理器调度的基本单位,但进程不是.
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
从Linux内核上讲,进程和线程的级别区别?安全退出进程的方法?
进程是资源分配的基本单位,线程是调度的基本单位。进程的个体间是完全独立的,而线程间是彼此依存的。多进程环境中,任何一个进程的终止,不会影响到其他进程。而多线程环境中,父线程终止,全部子线程被迫终止(没有了资源)。而任何一个子线程终止一般不会影响其他线程,除非子线程执行了exit()系统调用。任何一个子线程执行exit(),全部线程同时灭亡。
从系统实现角度讲,进程的实现是调用fork系统调用:
pid_t fork(void);
线程的实现是调用clone系统调用:
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */
);
3. 死锁
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。集合中的每一个进程都在等待只能由本集合中的其他进程才能引发的事件,那么该组进程是死锁的。
一般来说,要出现死锁问题需要满足以下条件:
1. 互斥条件:一个资源每次只能被一个线程使用。
2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
只要破坏死锁 4 个必要条件之一中的任何一个,死锁问题就能被解决。
现在我们介绍避免死锁的几个常见方法。
·避免一个线程同时获取多个锁。
·避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
·尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
·对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。
4. 类加载机制、jvm、GC
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制。* Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能,这里就是我们经常能见到的Class类。
5. 设计一个缓存系统LURU简单实现,数据量大导致中断怎么办?
6. spring Applicationcontext
7. 谈谈Java反射机制,动态代理是基于什么原理?
反射机制是Java语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力。通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。
动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装RPC调用、面向切面的编程(AOP)。
实现动态代理的方式很多,比如JDK自身提供的动态代理,就是主要利用了上面提到的反射机制。还有其他的实现方式,比如利用传说中更高性能的字节码操作机制,类似ASM、cglib(基于ASM)、Javassist等。
8. RPC框架
9. 线程池有多少类
10. 线程池的常用参数,核心线程数是什么时候定义的,如何达到最大上线的
11. spring beanfactory 和factorybean的区别
12. 排序算法?快速排序讲解和复杂度的求解
内部排序,至少掌握基础算法如归并排序、交换排序(冒泡、快排)、选择排序、插入排序等。
外部排序,掌握利用内存和外部存储处理超大数据集,至少要理解过程和思路。
哪些是排序是不稳定的呢(快排、堆排),或者思考稳定意味着什么;对不同数据集,各种排序的最好或最差情况;
13. spring mybatis和jpa的区别
14.java框架中不同服务是如何实现互相调用的
15.服务注册与发现的实现
16. lambda表达式
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。lambda 表达式的语法格式如下:
(parameters) -> expression 或
(parameters) ->{ statements; }
17. Spring的IOC容器初始化流程
18. 理解Java的字符串,String、StringBufer、StringBuilder有什么区别?
String是Java语言非常基础和重要的类,提供了构造和管理字符串的各种基本逻辑。它是典型的Immutable类,被声明成为fnal class,所有属性也都是fnal的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的String对象。由于字符串操作的普遍性,所以相关操作的效率往往对应用性能有明显影响。
StringBufer是为解决上面提到拼接产生太多中间对象的问题而提供的一个类,我们可以用append或者add方法,把字符串添加到已有序列的末尾或者指定位置。StringBufer本质是一个线程安全的可修改字符序列,它保证了线程安全,也随之带来了额外的性能开销,所以除非有线程安全的需要,不然还是推荐使用它的后继者,也就是StringBuilder。
StringBuilder是Java 1.5中新增的,在能力上和StringBufer没有本质区别,但是它去掉了线程安全的部分,有效减小了开销,是绝大部分情况下进行字符串拼接的首选。
19. Lindhashmap和hashmap区别,Hashmap链表如何转红黑树,阈值是多少转红黑树旋转几次平稳,红黑树和hashmap区别?
Hashtable是早期Java类库提供的一个哈希表实现,本身是同步的,不支持null键和值,由于同步导致的性能开销,所以已经很少被推荐使用。
HashMap是应用更加广泛的哈希表实现,行为上大致上与HashTable一致,主要区别在于HashMap不是同步的,支持null键和值等。通常情况下,HashMap进行put或者get操
作,可以达到常数时间的性能,所以它是绝大部分利用键值对存取场景的首选,比如,实现一个用户ID和用户信息对应的运行时存储结构。
HashMap内部的结构,它可以看作是数组(Node[] table)和链表结合组成的复合结构,数组被分为一个个桶(bucket),通过哈希值决定了键值对在这个数组的寻址;哈希值相同的键值对,则以链表形式存储,你可以参考下面的示意图。这里需要注意的是,如果链表大小超过阈值(TREEIFY_THRESHOLD, 8),图中的链表就会被改造为树形结构。
TreeMap则是基于红黑树的一种提供顺序访问的Map,和HashMap不同,它的get、put、remove之类操作都是O(log(n))的时间复杂度,具体顺序可以由指定的Comparator来决定,或者根据键的自然顺序来判断。
针对有序Map的分析内容比较有限,我再补充一些,虽然LinkedHashMap和TreeMap都可以保证某种顺序,但二者还是非常不同的。
LinkedHashMap通常提供的是遍历顺序符合插入顺序,它的实现是通过为条目(键值对)维护一个双向链表。注意,通过特定构造函数,我们可以创建反映访问顺序的实例,所谓的put、get、compute等,都算作"访问"。
对于TreeMap,它的整体顺序是由键的顺序关系决定的,通过Comparator或Comparable(自然顺序)来决定。
20. 如何保证容器是线程安全的?ConcurrentHashMap如何实现高效地线程安全?
Java提供了不同层面的线程安全支持。在传统集合框架内部,除了Hashtable等同步容器,还提供了所谓的同步包装器(Synchronized Wrapper),我们可以调用Collections工
具类提供的包装方法,来获取一个同步的包装容器(如Collections.synchronizedMap),但是它们都是利用非常粗粒度的同步方式,在高并发情况下,性能比较低下。
另外,更加普遍的选择是利用并发包提供的线程安全容器类,它提供了:
各种并发容器,比如ConcurrentHashMap、CopyOnWriteArrayList。
各种线程安全队列(Queue/Deque),如ArrayBlockingQueue、SynchronousQueue。
各种有序容器的线程安全版本等。
具体保证线程安全的方式,包括有从简单的synchronize方式,到基于更加精细化的,比如基于分离锁实现的ConcurrentHashMap等并发实现等。具体选择要看开发的场景需求,
总体来说,并发包内提供的容器通用场景,远优于早期的简单同步实现。
分离锁,也就是将内部进行分段(Segment),里面则是HashEntry的数组,和HashMap类似,哈希相同的条目也是以链表形式存放。
HashEntry内部使用volatile的value字段来保证可见性,也利用了不可变对象的机制以改进利用Unsafe提供的底层能力,比如volatile access,去直接完成部分操作,以最优化
性能,毕竟Unsafe中的很多操作都是JVM intrinsic优化过的。个早期ConcurrentHashMap内部结构的示意图,其核心是利用分段设计,在进行并发操作的时候,只需要锁定相应段,这样就有效避免了类似Hashtable整体同
步的问题,大大提高了性能。
21. 你能说说Java中Comparable和Comparator的区别吗
22. 描述Spring循环依赖注入的问题,怎么解决
23. API访问请求变慢,如何去定位这个问题?
java工程的内存设置,内存泄漏的场景,如何排查内存泄露问题
用过哪些设计模式?代理模式的理解
并发秒杀系统的实现,怎么处理秒杀系统高并发压力?
K8S,创建一个pod的过程,组件是如何交互实现的?镜像是如何再linux中工作?
K8S包括那些组件?其中service的原理,class IP的作用?
K8S的服务注册与服务发现?
3次握手和4次分手,MTU和MSS
C++智能指针
数据库
1. 数据库索引,索引的index的创建
索引是若干数据行的关键字的列表,查询数据时,通过索引中的关键字可以快速定位到要访问的记录所在的数据块,从而大大减少读取数据块的I/O次数,因此可以显著提高性能。合理的索引可以提高查询的速度,但不是索引越多越好。在执行插入语句的时候,数据库要为新插入的记录建立索引。所以过多的索引会导致插入操作变慢。原则上是只有查询用的字段才建立索引。
2. MySQL支持的事务隔离级别
读未提交,读已提交,可重复读,串行化
3. 数据库锁
K8S
1. Service是什么?使用场景
服务发现服务注册
TCP/IP
1. 3次握手的流程
2. Linux的一些常用命令,fork懂不懂
3. find3天文件全部删除Linux的文件系统 读取 读写权限Linux内核
4. C++析构函数为何用虚函数内存泄露的识别方法
4. 准备一个比较有亮点或者是你最熟悉 或者复杂度最高的项目 细节和业务逻辑 还有架构 梳理清楚
健康检查如果失效怎么办?
流量
P7是技术问题的终结者,基本开发中遇到的问题到p7这一级基本都可以被解决。
要求:
1. 基础能力:技术基础一定要好好复习,因为这是根本,是任何层级都要达到的要求。
建议看下源码。
1. 架构能力,这个也要看个人修养,架构抽象能力很重要。
分布式系统、微服务架构、落地能力和项目推进能力,抓住业务方&需求方真实的想法和化繁为简的模型抽象能力。
1. 业务:应用开发的同学不能仅限于技术,得有行业业务领域背景和学习,以及业务建模和抽象能力。
1. 思维能力:思维能力也很重要,这个会从过往项目和对新项目的理解中考察。
建议对自己做过的项目做系统、清晰的梳理、复盘;同时思考,总结是否有更好的改进方法。
1. 在面试过程中注意的问题:
回答问题思路清晰,语言简洁,切中要害,不需要重复啰嗦;可以与面试官互动。
一位同学面过蚂蚁p7的感受: 技术还是得干技术,小公司讲究能干活,各种都能搞,蚂蚁确实往深入挖技术。
标签: #intrinsic的优化技术