将我们的程序进行静态链接,这就要求我们链接的任何库都要通过对应的静态库版本!!! 一般我们的操作系统都是动态库 并且在对.o文件打包的时候: 静态库使用ar -rc 文件名......但是对应的方法并没有在可执行程序中,所以动态库是怎样被调用的呢?又是什么时候被调用呢? 动态库也会写入到内存中,并通过页表映射到地址空间中的共享区。让调用的时候通过共享区来找到对应的方法实现。...我们之间看源代码不用加载运行,就可以想象着一步一步运行我们的程序! 我们介绍一下ELF格式的程序,二进制是有自己的固定格式的,elf可执行程序的头部储存这可执行程序的属性!...首先,库的虚拟地址储存在共享区 在磁盘中,动态库的编址是平坦模式的编址,其地址0x1234就像是距离0000...的一个偏移量 然后在共享区里,这个偏移量是没有改变的1 所以想要执行库函数,就直接到共享区通过库的起始地址...动态库是由操作系统来管理的,所以就要有对应的描述结构体!!!所以使用的时候,想要知道有没有加载,就可以通过库的名称来找到对应的描述结构体,来查看是否被加载!!!
说到进程,恐怕面试中最常见的问题就是线程和进程的关系了,那么先说一下答案:在 Linux 系统中,进程和线程几乎没有区别。...Linux 中的进程其实就是一个数据结构,顺带可以理解文件描述符、重定向、管道命令的底层工作原理,最后我们从操作系统的角度看看为什么说线程和进程基本没有区别。...为什么说 Linux 中线程和进程基本没有区别呢,因为从 Linux 内核的角度来看,并没有把线程和进程区别对待。...当然,必须要说明的是,只有 Linux 系统将线程看做共享数据的进程,不对其做特殊看待,其他的很多操作系统是对线程和进程区别对待的,线程有其特有的数据结构,我个人认为不如 Linux 的这种设计简洁,增加了系统的复杂度...在 Linux 中新建线程和进程的效率都是很高的,对于新建进程时内存区域拷贝的问题,Linux 采用了 copy-on-write 的策略优化,也就是并不真正复制父进程的内存空间,而是等到需要写操作时才去复制
来源:Linux阅码场, 罗玉平原创,欢迎投稿原创文章(要求投稿前未在任何平台发表),稿费500元人民币。...投稿邮箱:21cnbao@gmail.com 作者简介: 罗玉平, IT行业工作近20年,先后从事无线通讯,linux平台和firmware开发多年,目前从事ARMv8-A架构和CPU软件的客户支持和培训工作...引子 前文宝华的《宋宝华:关于ARM Linux原子操作的实现》谈到软件如何使用ARM V7之后的LDREX和STREX指令来实现spin lock和atomic 函数,这篇文章接着探讨ARM架构和总线协议如何来支持的...fill和line eviction和正常的读写操作产生的外部行为是一样的。...例如, 假如某个SOC不支持外部global exclusivemonitor,软件把MMU disabled的情况下,启动SMP Linux,系统是没法启动起来的,在spinlock处会挂掉。
大家好,又见面了,我是你们的朋友全栈君。...ThreadLocal 作用: 提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂性。...---- 各种引用用途: 强引用:最常用的一种引用 软引用:适合做缓存,比如内存中一张图片,当内存不够用的时候先把图片移动出去,当内存充足的时候再把图片load进来 弱引用:为了解决某些地方的内存泄露问题...,当DirectByteBuffer回收后,会通知队列,这时候JVM垃圾回收器就知道去系统内存请理相应的系统内存空间 ---- ThreadLocal底层: 每个ThreadLocal对应一个ThreadLocalMap...,如果一个对象只有弱引用的时候,那当垃圾回收器遇见他的时候它就会被回收。
Mysql专栏 - Linux底层交互和Raid存储架构 前言 在专栏之前的几篇文章中,我们总结了缓冲池,缓存页,redo log,undo log,以及数据页和数据行在底层是如何进行存储的,后续介绍了表空间...这一节比较特殊,讲述的是和Linux有关的交互原理,因为多数的mysql都是部署在linux的服务器上面,本节会简单介绍一下linux是如何处理mysql的请求的,以及linux系统会带来哪些问题 概述...为了IO的性能,这里需要了解两个重要的性能指标:「IOPS」和「响应延迟」。IOPS 指的是存储系统每秒可以执行多少次磁盘读写操作,底层磁盘支持每秒执行1000个随机读写和200个差距是很大的。...: mysql和linux交互步骤: 下面是mysql和llinux交互的大致流程: VFS层:当mysql发起一次数据页的随机读写,一次redo log顺序读写的时候,实际上会把io请求交给linux...最终 MySQL可以得到本次IO读写操作的结果,最终的结构图如下所示: linux底层调度流程 ERROR 1040(HY000): Too many connections问题 下面补充一个比较常见的
作为一位iOS开发者,如何才能开启自己的底层探索之路呢?每当点击系统API无法跟进实现只能浅尝辄止的时候,有没有想过怎样才能看到底层源码的真容,而不是在还没开始就结束了呢?...本文中会提供三种方式来一探底层的魅力。 Apple的小心思 这句代码应该非常熟悉了吧?可是想知道alloc具体是如何实现对象的创建呢?...没有注释,也再无法跟进,显然Apple不想让你看到底层是如何实现的?可是这样就放弃了吗?...三种源码探索的方式: 使用Xcode提供的符号断点方式 使用Xcode提供的分步调试方式 通过汇编方式 下面就这三种方式一一说明: 1. 符号断点 第一步: 添加符号断点 ?...分步调试 如果在你增加了对应API的符号断点还是无法精确找到源码库名的时候,第一种方式就不够用了。 第一步:为自己输入的代码增加断点,run后等待断点触发 这一步与之前的操作相同。
一、 漏洞概要 近日,Linux底层函数glibc 的 DNS 客户端解析器被发现存在基于栈的缓冲区溢出漏洞。...三、 漏洞影响范围 所有Debian系列、 Red Hat 系列的 Linux 发行版中glibc版本大于 2.9 均受该漏洞影响,低于2.9的有可能受此漏洞影响。...在linux命令行“输入”glibc库的名称(如,libc.so.6),就像命令一样执行。 ...输出结果会显示更多关于glibc库的详细信息,包括glibc的版本以及使用的GNU编译器,也提供了glibc扩展的信息。glibc变量的位置取决于Linux版本和处理器架构。 ...在基于Debian的64位系统上: $ /lib/x86_64-linux-gnu/libc.so.6 在基于Debian的32位系统上: $ /lib/i386-linux-gnu/libc.so
它们是一部分内核数据在用户空间的映射,为了提高应用的性能而创建。在《攻克 Linux 系统编程》中,我们再专门详细讨论。...深入理解了这些底层行为细节,就可以顺理成章地理解 fork() 的一些行为表现和正确使用规范,无需死记硬背,也可获得一些别人踩过坑后才能获得的经验。...03 监控子进程状态 在 Linux 应用中,父进程需要监控其创建的所有子进程的退出状态,可以通过如下几个系统调用来实现。...本文要重点讨论的是:即使父进程在业务逻辑上不关心子进程的终止状态,也需要使用 wait 类系统调用的底层原因。...对这些底层实现细节的充分理解,能帮助读者更好地理解各个系统调用的行为表现,并根据具体的应用需求选择正确、合适的实现方案。
ArrayList/Vector 的底层分析 ArrayList ArrayList 实现于 List、RandomAccess 接口。可以插入空数据,也支持随机访问。...将插入的值放到尾部,并将 size + 1 。...接着对数据进行复制,目的是把 index 位置空出来放本次插入的数据,并将后面的数据向后移动一个位置。...由此可见 ArrayList 的主要消耗是数组扩容以及在指定位置添加数据,在日常使用时最好是指定大小,尽量减少扩容。更要减少在指定位置插入数据的操作。...从实现中可以看出 ArrayList 只序列化了被使用的数据。 Vector Vector 也是实现于 List 接口,底层数据结构和 ArrayList 类似,也是一个动态数组存放数据。
我们经常会使用weak来解决OC中的循环引用问题,因为weak不会使引用计数加1;并且weak修饰的指针还会在对象被销毁后自动置空,这有效的解决了野指针调用的问题。...那么weak 的底层原理是怎样的呢?我们接下来就来分析一下。 首先随便在一个工程中,写入下面类似的代码,然后在weak的那行打断点: ? 运行到断点处,转成汇编分析: ?...在最后,可以通过存储的这个弱指针的地址找到其指向的弱指针,然后将弱指针置空。...3.1 weak_table_t 先来看看weak_table_t的底层代码: /** * The global weak references table....到这里位置,我们实际上就已经介绍完了【对一个对象做weak操作的时候底层所做的事情】: 首先,会有一张SideTable散列表,这个散列表包含了引用计数表、弱引用表等; 然后,散列表里面会有一张全局的弱引用表
自从上次学习了TCP/IP的拥塞控制算法后,我越发想要更加深入的了解TCP/IP的一些底层原理,搜索了很多网络上的资料,看到了陶辉大神关于高性能网络编程的专栏,收益颇多。...为什么不能阻塞读取网络信息的IO线程呢?这里就要从经典的网络C10K开始理解,服务器如何支持并发1万请求。C10K的根源在于网络的IO模型。...Linux 中网络处理都用同步阻塞的方式,也就是每个请求都分配一个进程或者线程,那么要支持1万并发,难道就要使用1万个线程处理请求嘛?这1万个线程的调度、上下文切换乃至它们占用的内存,都会成为瓶颈。...用户调用的recv接收阻塞socket上的报文,该socket的SO_RCVLOWAT值大于第一个报文的大小,并且用户分配了足够大的长度为len的内存。...p-gzmjmmna-dn.html https://blog.csdn.net/russell_tao/article/details/9950615 https://ylgrgyq.github.io/2017/08/01/linux-receive-packet
ThreadLocal 作用: 提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂性。...,用来指向对外内存(操作系统管理的内存),操作系统管理的内存JVM垃圾处理器不能回收,所以当DirectByteBuffer回收后,会在队列中有相应的记录,之后JVM会去处理对外内存。...---- 各种引用用途: 强引用:最常用的一种引用 软引用:适合做缓存,比如内存中一张图片,当内存不够用的时候先把图片移动出去,当内存充足的时候再把图片load进来 弱引用:为了解决某些地方的内存泄露问题...,当DirectByteBuffer回收后,会通知队列,这时候JVM垃圾回收器就知道去系统内存请理相应的系统内存空间 ---- ThreadLocal底层: 每个ThreadLocal对应一个ThreadLocalMap...,如果一个对象只有弱引用的时候,那当垃圾回收器遇见他的时候它就会被回收。
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++、嵌入式、Linux。 目录 动态链接要解决什么问题?...在上一篇文章中,我们一起学习了Linux系统中 GCC编译器在编译可执行程序时,静态链接过程中是如何进行符号重定位的。 为了完整性,我们这篇文章来一起探索一下:动态链接过程中是如何进行符号重定位的。...解决这个矛盾的方案,就是Linux系统中动态链接器的核心工作! 解决矛盾:增加一层间接性 David Wheeler有一句名言:“计算机科学中的大多数问题,都可以通过增加一层间接性来解决。”...动态库的加载过程 动态链接器加载动态库 当执行main程序的时候,操作系统首先把main加载到内存,然后通过.interp段信息来查看该文件依赖哪些动态库: 上图中的字符串/lib/ld-linux.so...ld-linux.so.2也是一个动态链接库,在大部分情况下动态链接库已经被加载到内存中了(动态链接库就是为了共享),操作系统此时只需要把动态链接库所在的物理内存,映射到 main进程的虚拟地址空间中就可以了
鸿蒙开发者的必修课:Linux底层IO方式深度剖析 摘要 在这篇博客中,我们将探讨Linux底层的几种IO(输入/输出)方式,为鸿蒙开发者提供一个清晰的理解。...关键词:鸿蒙OS、Linux、IO模型、阻塞非阻塞、IO多路复用、性能优化。 引言 对于鸿蒙开发者来说,深入理解Linux底层的IO方式不仅有助于优化应用性能,还能在面对复杂场景时更加得心应手。...本文将一一解析Linux IO模型的核心机制及其在鸿蒙开发中的应用价值。...底层的五种IO模型及其在鸿蒙开发中的应用。...IO流 网络应用 信号驱动IO 接收IO准备信号 及时响应IO 设备状态变化 异步IO IO操作真正完成返回 长耗时IO操作 大文件/网络通信 总结 了解和掌握Linux底层的不同IO模型对于鸿蒙开发者来说是至关重要的
1.线程的互斥 1.1.进程线程间的互斥相关背景概念 临界资源:多线程执行流共享的资源就叫做临界资源 临界区:每个线程内部,访问临界资源的代码,就叫做临界区 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区...但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互。 多个线程并发的操作共享变量,会带来一些问题 所以多线程之间为什么要有互斥?...Linux上提供的这把锁叫互斥量。...3.互斥的底层实现?...所有线程在争锁的时候,只有一个锁,交换的过程,只有一条是汇编——所以该过程是原子的 CPU寄存器硬件只有一套,但是CPU寄存器内部的数据,数据线程的硬件上下文是有多套的。
一:HashMap底层实现原理解析 我们常见的有数据结构有三种结构:1、数组结构 2、链表结构 3、哈希表结构 下面我们来看看各自的数据结构的特点: 1、数组结构: 存储区间连续、内存占用严重、空间复杂度大...,从而实现了查询和修改效率高,插入和删除效率也高的一种数据结构 常见的HashMap就是这样的一种数据结构 HashMap中的put()和get()的实现原理: 1、map.put(k,v)实现原理...(2)然后它的底层会调用K的hashCode()方法得出hash值。 (3)通过哈希表函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。...如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value。 为何随机增删、查询效率都很高的原因是?...因为equals方法默认比较的是两个对象的内存地址 二:HashMap红黑树原理分析 相比 jdk1.7 的 HashMap 而言,jdk1.8最重要的就是引入了红黑树的设计,当hash表的单一链表长度超过
go语言圣经中的解释: 数组和slice之间有着紧密的联系。 一个slice是一个轻量级的数据结构,提供了访问数组子序列(或者全部)元素的功能,而且slice的底层确实引用一个数组对象。...指针指向第一个slice元素对应的底层数组元素的地址,要注意的是slice的第一个元素并不一定就是数组的第一个元素。...长度对应slice中元素的数目;长度不能超过容量 容量一般是从slice的开始位置到底层数据的结尾位置。内置的len和cap函数分别返回slice的长度和容量。...make([]T, len, cap) len<=cap 在底层,make创建了一个匿名的数组变量,然后返回一个slice slice只引用了底层数组的前len个元素,但是容量将包含整个的数组。...额外的元素是留给未来的增长用的 从下面这个自定义函数里可以了解扩容机制: func appendInt(x []int, y int) []int { var z []int //+1个元素后新的长度
我之前的文章美团的“四大名著”里面提到了王慧文的一些底层逻辑,所以我觉得,创始人或是创始团队的底层逻辑其实决定了一家公司未来发展的规模和天花板,也决定了投资这家公司的长期收益。...因为我目前手里买的股票主要是:tx,mt,pdd,jd,所以每隔一段时间可能会分析一些这些公司背后我所吸收的一些底层逻辑,也就是我为什么准备长期持有这几家公司的原因吧,今天先简单聊下pdd吧。...消费者的时间变得更碎片化,消费者的标签变得更随机。以前的本来很有目的性的购物,慢慢的变成了基于兴趣使然的随机性的行为。在有限的碎片化的时间里去逛,引发兴趣而产生交易行为。...这是pdd底层对于效率的重视,我见过一些独角兽公司在基建这块不重视,最后导致上面的效率提不上去,所以这种公司天花板还是比较堪忧的。 既然数据在后流量时代这么重要,对于流量的使用和有效转化就更加重要。...如果可以拿到用户衣食住行全方位的数据呢?可以完善底层的零售体系,反馈给用户就可以建立新的场景,完善用户需求,形成闭环。
领取专属 10元无门槛券
手把手带您无忧上云