1.什么是源码xp框架
2.xp是什么
3.编程猫源码编辑器V3413官方XP版编程猫源码编辑器V3413官方XP版功能简介
4.疑似 Windows XP SP1 源代码泄露,真的解压是微软的吗?
5.Go看源码必会知识之unsafe包
什么是xp框架
xp框架即Xposed框架(Xposed Framework),它是密码一套开源的、在Android高权限模式下运行的源码框架服务。Xposed框架可以在不修改APK文件的解压情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的密码上涨加速源码模块,且在功能不冲突的源码情况下同时运作。
Android中一般存在两种hook:sdk hook和ndk hook。解压native hook的密码难点在于理解ELF文件与学习ELF文件,Java层Hook则需要了解虚拟机的源码特性与java上的反射使用。
另外还存在全局hook,解压即结合sdk hook和ndk hook,密码xposed就是源码一种典型的全局hook框架。
扩展资料:
Xposed框架的解压五个部分:
1、Xposed:
独立实现了一版Xposed版的密码zyogte,即生成用来替换/system/bin/app_process的可执行文件,该文件在系统启动时在init.rc中被调用,启动Zygote进程。
2、XposedBridge:
Xposed框架的Java部分,编译输出为XposedBridge.jar,为开发者提供接口。
3、android_art:
Xposed框架的C++部分,对XposedBridge的补充。
4、XposedTools:
框架编译工具,因为Xposed和XposedBridge编译依赖于Android源码,而且还有一些定制化的东西。
5、XposedInstaller:
Xposed插件管理和功能选择应用,界面如下图所示,其功能包括启动Xposed框架,下载和启用指定插件,或禁用插件等。
百度百科-Xposed框架
xp是什么
xp
极限编程(Extreme Programming,XP)是一门针对业务和软件开发的规则,它的作用在于将两者的力量集中在共同的、可以达到的目标上。它是以符合客户需要的软件为目标而产生的一种方法论,XP使开发者能够更有效 XP的响应客户的需求变化,哪怕是在软件生命周期的后期。它强调,软件开发是人与人合作进行的过程,因此成功的软件开发过程应该充分利用人的优势,而弱化人的缺点,突出了人在软件开发过程中的作用。极端编程属于轻量级的方法,认为文档、架构不如直接编程来的直接。
目录
第三方的身份的事故发生过对方规范化和规范
黑屏警告
反盗版“黑屏”举措
XP的核心思想
XP的十二种方法
四个核心价值
带给我们的变化
极限编程的有效实践
展开
编辑本段
第三方的身份的事故发生过对方规范化和规范
xp
编辑本段
黑屏警告
微软中国正式宣布 xp黑屏警告,将从年月日起同时推出两个重要更新,使用XP专业版盗版系统与OfficeXPe、Office盗版软件的用户将分别遭遇电脑“黑屏”与“提醒标记”等警告。
被称为Windows正版增值计划通知和Office正版增值计划通知的这两个项目均是可选择式的服务。用户可以通过微软更新站点或自动跟新选择下载安装、经过验证过程后了解自己使用的WindowsXP或Office产品是否为正版并获得了相应的授权。
微软方面透露,验证通过的用户直接使用WindowsXP或Office程序即可。对于因不同原因未通过验证的用户,将收到相应的系统通知。如:产品未激活或使用试用版下的“未激活验证失败”;因同步超时等原因引起的“验证无法完成”;或“非正版验证失败”。
XP
xp如果WindowsXP用户没有通过正版验证,将会体验到:用户开机进入后,桌面背景变为纯黑色,用户可以重新设置桌面背景,但是每隔分钟,桌面背景将重新变回黑色;会看到一个登录中断的对话框,并在屏幕的右下角会出现一个永久通知和持续提醒的对话框显示“您可能是软件盗版的受害者”等提示信息。
如果Office用户没有通过正版验证,用户体验将分为三个阶段:验证失败后的第1-天内,客户将在每天首次打开Office软件和此后2小时分别收到一次对话框提醒;从验证失败后的第天开始,提示信息将告知用户如不采取行动,将在天后,Office软件被添加视觉标记;客户在收到这些对话框通知天后,Office软件的Word、Excel,PowerPoint和Outlook程序的菜单栏中将被添加视觉标记。
微软方面认为,这两项计划是旨在帮助中国用户甄别电脑中安装的微软Windows操作系统和Office应用软件是否是获得授权的正版软件,从而帮助那些在不知情的情况下安装和使用了盗版软件的用户免受侵害。
XP实际上是一种经历过很多实践考验的一种软件开发的方法,它诞生了大概有5 年,它已经被成功的应用在许多大型的公司,如:Bayeris hpfilter函数源码che Landesbank,Credit Swis s Life,DaimlerChrysler,First Union National Bank Ford Motor Company and UBS.XP 的成功得益于它对客户满意度的特别强调,XP 是以开发符合客户需要的软件为目标而产生的一种方法论,XP 使开发者能够更有效的响应客户的需求变化,哪怕在软件生命周期的后期。
编辑本段
反盗版“黑屏”举措
xp微软中国正式宣布,将从年月日起同时推出两个重要更新,使用XP专业版盗版系统与OfficeXP、Office、Office盗版软件的用户将分别遭遇电脑“黑屏”与“提醒标记”等警告。
XP
新闻发布后即引起了网友的极大反应。截止:,已有4万名网友通过搜狐新闻的调查表达了自己的意见,其中.7%的网友反对“黑屏”,认为微软此举太过分了。而%的网友则坚称要将盗版使用到底。
支持微软的网友只占7.8%。
不少坚称继续使用盗版。“不是不想用正版,而是太贵了。”类似该网友,希望微软继续降价的网友也不在少数。
XP-概述
同时,XP 也很强调团队合作。团队包括:项目经理,客户,开发者。团结在一起来保证高质量的软件。XP 其实是一种保证成功的团队开发的简单而有效的方法。
XP 强调四种价值:交流,简易,回馈,勇气。XP 程序员之间紧密的相互交流,XP 程序员也和客户紧密的交流。他们总是保持他们的设计简单明了。项目一开始,XP 就强调通过对软件的不断测试来获得反馈,程序员尽可能早的把软件交给客户,并实现客户对软件需求提出的变化,有了这些基础,XP 程序员就可以自信的面对需求和软件技术的变化。
XP
XP 是与众不同的,它有点象快步的舞蹈。XP 开发过程包括许多的小卡片,独立的看,这些小卡片没有什么意义,但是当它们组合在一起,一幅完整的美丽的就可以看见,XP方法有别于传统软件开发,它是软件开发的一种新的重要的发展。它改变了用户开发程序的传统思维方式。下面用户将介绍它带给我们那些改变。
xpXP属于轻量开发方法中较有影响的一种方法。轻量开发方法是相对于传统的重量开发方法而言。简单地理解,“量”的轻重是指用于软件过程管理和控制的、除程序量以外的“文档量”的多少。XP等轻量开发方法认识到,在当前很多情况下,按传统观念建立的大量文档,一方面需要消耗大量开发资源,同时却已失去帮助“预见、管理、决策和控制的依据”的作用。因此必须重新审视开发环节,去除臃肿累赘,轻装上阵。
编辑本段
XP的核心思想
从长远看,早期发现错误以及降低复杂度可以节约成本。极限编程强调我们将任务/系统细分为可以在较短周期解决的一个个子任务/模块,并且强调测试、代码质量和及早发现问题。通常,通过一个个短小的迭代周期,我们就可以获得一个个阶段性的进展,并且可以及时形成一个版本供用户参考,以便及时对用户可能的需求变更作出响应。
编辑本段
XP的十二种方法
规划策略(The Planning Game);
结对编程(Pair programming)
测试(Testing)
重构(Refractoring)
xp简单设计(Simple Design)
代码集体所有权(Collective Code Ownership)
持续集成(Continuous Integration)
现场客户(On-site Customer)
小型发布(Small Release)
每周小时工作制(-hour Week)
编码规范(Code Standards)
系统隐喻(System Metaphor)
编辑本段
四个核心价值
极限编程中有四个核心价值是我们在开发中必须注意的:沟通(Communication)、简单(Simplicity)、反馈(Feedback)和勇气(Courage)。
XP
XP用“沟通、简单、ps源码格式反馈和勇气”来减轻开发压力和包袱;无论是术语命名、专著叙述内容和方式、过程要求,都可以从中感受到轻松愉快和主动奋发的态度和气氛。这是一种帮助理解和更容易激发人的潜力的手段。XP用自己的实践,在一定范围内成功地打破了软件工程“必须重量”才能成功的传统观念。
XP精神可以启发我们如何学习和对待快速变化、多样的开发技术。成功学习XP的关键,是用“沟通、简单、反馈和勇气”的态度来对待XP;轻松愉快地来感受XP的实践思想;自己认真实践后,通过对真实反馈的分析,来决定XP对自己的价值;有勇气接受它,或改进它。
编辑本段
带给我们的变化
通过软件工程设计的简单而优美的软件并不比那些设计复杂而难以维护的软件有价值。这是真的吗?XP认为事实并非如此。
一个典型的项目花在人力上的金钱是花在硬件上的时间的 倍,这意味着一个项目每年要花 万美元在程序员身上,而仅仅花 万美元在电脑设备上。很多聪明的程序员说:“我们如此聪明,发现一种方法可以节省%的硬件开销”,然后他们使得源程序大而且难懂和难以维护,他们会说:“但是我们节省了%或者2 万美元每年,很大的节省”。反之,如果我们写我们的程序简单而且容易扩展,我们将至少节省%的人力开销,一笔更大的节省,这是你客户一定会注意到的一些事情。
另外一个对客户来说很重要的问题就是程序的BUGS 。XP 不只是强调测试,而且要求正确的测试。测试必须是能自动进行的,以便为程序和客户提供一个安全的环境。在编码的所有阶段,我们不断增加测试用例。当找到bug 时,我们就添加新的测试,一个紧密的安全网就这样产生了。同一个BUG 不出现两次,这些一定会引起用户的注意。你的客户必须注意的另外一件事情:XP 开发者拥抱需求变化。XP 使我们能够接受需求的变化。
一般情况下,客户只有在系统被开发完成以后能真正去体会它。XP 却不一样,它通过加强客户的反馈来缩短开发的周期,同时获得足够的时间来改变功能和获得用户的认同。在XP 中,你的客户应该明确的知道这一点。
XP开发过程的大多的革命是在软件开发的方法上,代码质量的重要程度超出人们一般所认为的。仅仅因为用户的客户不能明白用户的源代码并不意味着用户可以不努力去管理代码的质量。
五、用户什么时候用XP
XP方法的产生是因为难以管理的需求变化,从一开始你的客户并不是很完全的知道他们要的系统是怎么样的,你可能面对的系统的功能一个月变化多次。在大多数软件开发环境中不断变化的需求是唯一的不变,
XP
这个时候应用XP 就可以取得别的方法不可能取得的成功。XP 方法的建立同时也是为了解决软件开发项目中的风险问题。假如你的客户在特定的时间内,需要一个相当难开发的系统,而且对于你的项目组来说,这个系统是一个新的挑战(从来没有做过),那风险就更大了,如果这个系统对于整个软件行业来说都是新的挑战,那么它的风险就更大了,采用XP 将可以减少风险,增加成功的可能。
XP方法是为小团体开发建立的,在2- 个人之间。假如你的团体恰好合适,你就不需要用其他的软件工程方法了,就用XP ,但是要注意你不能将XP 方法应用于大团体的开发项目中。用户应该注意,在需求一惯呈动态变化或者高具有高风险的项目中,你就会发现XP 方法在小团体的开发中的作用要远远高于在大团体的开发。
XP方法需要一个扩展的开发团体,XP 团体不仅仅包括开发者,经理、客户也是抽奖算法源码其中的一员,所有的工作一环扣一环,问问题,商讨方法和日程,增加功能测试,这些问题的解决不仅仅涉及到软件的开发者。
另一个需要是可测试性,你必须能增加自动的单元测试和功能测试,然而在你进行这个需求的时候,你会发现有许多的问题很难测试,这需要充分发挥你的测试的经验和智慧,而且你有时还要改变你的设计以便它可以更容易的进行测试。记住:那儿有需求,那儿就应该有测试的方法。
在XP方法的好处的清单上,最后一条是生产力。在同样的合作环境下,XP 项目都一致的表现出比使用其他方法高的多的生产力。但这从来不是XP 方法学的真正目标。XP 真实追求的目标是:在规定的时间生产出满足客户需要的软件。假如对于你的开发来说,这是很重要的方面,你就可以选择XP 了。
编辑本段
极限编程的有效实践
完整团队
XP
XP项目的所有参与者(开发人员、客户、测试人员等)一起工作在一个开放的场所中,他们是同一个团队的成员。这个场所的墙壁上随意悬挂着大幅的、显著的图表以及其他一些显示他们进度的东西。
计划游戏
计划是持续的、循序渐进的。每2周,开发人员就为下2周估算候选特性的成本,而客户则根据成本和商务价值来选择要实现的特性。
客户测试
作为选择每个所期望的特性的一部分,客户可以根据脚本语言来定义出自动验收测试来表明该特性可以工作。
简单设计
团队保持设计恰好和当前的系统功能相匹配。它通过了所有的测试,不包含任何重复,表达出了编写者想表达的所有东西,并且包含尽可能少的代码。
结对编程
所有的产品软件都是由两个程序员、并排坐在一起在同一台机器上构建的。
测试驱动开发
编写单元测试是一个验证行为,更是一个设计行为。同样,它更是一种编写文档的行为。编写单元测试避免了相当数量的反馈循环,尤其是功功能能验证方面的反馈循环。程序员以非常短的循环周期工作,他们先增加一个失败的测试,然后使之通过。
改进设计
随时利用重构方法改进已经腐化的代码,保持代码尽可能的干净、具有表达力。
持续集成
团队总是使系统完整地被集成。一个人拆入(Check in)后,其它所有人责任代码集成。
集体代码所有权
任何结对的程序员都可以在任何时候改进任何代码。没有程序员对任何一个特定的模块或技术单独负责,每个人都可以参与任何其它方面的开发。
编码标准
系统中所有的代码看起来就好像是被单独一人编写的。
隐喻
将整个系统联系在一起的全局视图;它是系统的未来影像,是它使得所有单独模块的位置和外观变得明显直观。如果模块的外观与整个隐喻不符,那么你就知道该模块是错误的。
可持续的速度
团队只有持久才有获胜的希望。他们以能够长期维持的速度努力工作,他们保存精力,他们把项目看作是马拉松长跑,而不是全速短跑。
编辑本段
程序
XP,是英文Experience(体验)的缩写, 自从微软发布windows XP后,成为软件流行命名概念。
Windows XP原来的代号是Whistler。Windows XP的外部版本是,内部版本是5.1,正式版的Build是。 微软最初发行了两个版本:专业版(Windows XP Professional)和家庭版(Windows XP Home Edition)。
年月,Windows XP问世了,这个版本在Windows 基础上开发。微软此次为Windows XP造势的规模相当大,XP(eXPerience)这个词随之深入人心,越来越多的软件公司为了搭这个顺风车,不管相干不相干都为自己的简洁企业源码软件名字后面加一个XP,甚至连AMD的0.微米Athlon也“非常巧合”地命名为Athlon XP,不过AMD对XP的解释是eXtreme Performance。
编辑本段
停售
美国微软公司从年6月日起,停止向零售商和几家主要电脑生产商销售视窗xp操作系统。
据美国媒体日报道,微软今后将不再向戴尔、惠普等主要电脑生产商提供视窗xp操作系统,但这些厂商库存的装有xp系统的电脑仍将继续销售。从这些商家购买新电脑的消费者,如果仍想安装xp,也只能先接受Vista操作系统,然后再合法地将操作系统“降级”至xp。
不过微软宣布,到年1月之前,该公司仍将允许一些家庭经营的电脑商店等小型零售商销售xp操作系统。此外,微软仍会销售一款针对超低价个人电脑的XP系统。
XP操作系统上市至今已有8年。Vista是微软继xp系统之后推出的最新版视窗操作系统,于年1月日面向普通消费者发售。但一些消费者认为,Vista系统对硬件配置的要求太高。另外,-适逢“上网本”开始快速发展。“上网本”即目前日趋成为笔记本电脑中的主流的一类个人终端,搭载有无线网卡,方便随时随地登录互联网,这类电脑的配置普遍较低,价格便宜,适合对于移动网络要求比较高而对硬件配置要求并不高的用户。Windows xp显然是这类电脑的首选。迫于上述原因,年4月日:微软决定延长国内xp主流支持服务。
编辑本段
疾病
XP也是着色性干皮病(xroderma pigmentosa)的缩写。着色性干皮病是一种发生在暴露部位的色素变化,萎缩,角化及癌变的遗传性疾病,属常染色体隐性遗传病。在某些家族中,显示性联遗传。表现暴露部位发生针头至1mm以上大小的淡暗棕色斑和皮肤干燥,日晒后可发生急性晒伤样或较持久的红斑,雀斑可相互融合成不规则的色素沉着斑。也可发生角化棘皮瘤,可自行消退,疣状角化可发生恶变。避免日晒,不宜室外工作。可用2-5%二氧化钛霜外用,肿瘤及早切除。
编辑本段
口语
在如今网络终于丰富多彩的时候,XP在一些不愿说脏字的人嘴里就代替了牛X。
基督Χριστοs 的首两位简写 ,罗马皇帝君士坦丁大帝曾在梦中梦到基督,醒来后便让手下正准备出征的战士在盾牌上刻上XP,即基督之意。后来君士坦丁使基督教获得了前所未有的地方,让基督教真正的与政治统治结合了起来。
编辑本段
eXtreme programming
XP(Extreme Programming),它是由Kent Beck大师提出的。大师在经历传统软件开发的痛苦之后,希望能够找到一种优秀的软件开发方法。大师总结了大量的软件的成功和失败的因素之后,提出了改进软件开发方法的四个要素:沟通(communication)、简单化(simplicity)、反馈(feedback)、勇气(courage)。这形成了XP的核心价值观。在经历了数年的发展,XP在软件开发的各方面都发展出了众多的方法来支持软件开发。
经验值
在某些单机游戏与网络游戏中,XP就是EXP的简称,指的是经验值。
编程猫源码编辑器V官方XP版编程猫源码编辑器V官方XP版功能简介
大家好,关于编程猫源码编辑器 V3.4. 官方XP版,编程猫源码编辑器 V3.4. 官方XP版功能简介这个很多人还不知道,现在让我们一起来看看吧!编程猫源码编辑器是一款由编程猫出品的图形化编程工具,软件支持离线编辑代码,让创作更加简单,能够让用户随时随地开展代码工作,随时都可以将瞬间的灵感和创意记录下来,更加有利于程序员的编程开发与青少年的编程学习。
功能特点
1、支持离线编辑代码,让创作更简单。
2、支持XP系统、win7及以上系统下载。
3、拥有独立的素材库,可随意使用。
4、随时可上传自己设计的作品。
5、熟悉编程猫在线编程的用户可以立刻上手使用。
6、它与编程猫一样内置了图形化编程,引起学生学习兴趣。
7、无需编程功底。
8、使用简单,鼠标点击即可。
9、条理清晰,快速完成作品。
特色介绍
1、软件采用寓教于学的方式来激发孩子的学习兴趣。
2、软件带领孩子走进编程的世界,一个神奇的世界。
3、支持源码精灵图鉴信息浏览,方便训练师获取对应信息。
4、与现实空间无缝对接,随时随地收集源码精灵。
5、扫描AR卡牌,投影3D立体虚拟角色,与虚拟角色进行互动。
更新日志
1、性能体验优化提升
2、修复了已知bug
疑似 Windows XP SP1 源代码泄露,真的是微软的吗?
深空电脑网9月日报告指出,疑似Windows XP SP1源代码在海外论坛4chan上曝光,GB的文件已广泛传播,微软尚未对此事表态。
这份声称来自微软的源代码引起了独立安全专家的深入研究,他们对其真实性表示认可,并相信它将经受住严格的审查。泄露内容涵盖了多个版本,包括MS DOS 3.、6.0,以及Windows 至Windows Embedded 7,甚至包括Windows NT 3.5至NT 4和原始Xbox的源码。 值得注意的是,泄露者声称Windows XP源代码实际上在黑客间私下流传多年,但此次首次公之于众。Windows XP,这款年月日发布的操作系统,以“体验”为名,直至年4月8日微软停止技术支持,但仍偶尔因重大安全事件发布补丁。 尽管如此,根据NetMarketShare的数据,Windows XP依然在全球网络PC中占据了约1.%的比例,表明其影响力持续不减。微软对于此次源代码泄露事件的官方立场和后续行动值得关注。Go看源码必会知识之unsafe包
前言
有看源码的朋友应该会发现,Go标准库中大量使用了unsafe.pointer,要想更好的理解源码实现,就要知道unsafe.pointer到底是什么?所以今天就与大家来聊一聊unsafe包。
什么是unsafe众所周知,Go语言被设计成一门强类型的静态语言,那么他的类型就不能改变了,静态也是意味着类型检查在运行前就做了。所以在Go语言中是不允许两个指针类型进行转换的,使用过C语言的朋友应该知道这在C语言中是可以实现的,Go中不允许这么使用是处于安全考虑,毕竟强制转型会引起各种各样的麻烦,有时这些麻烦很容易被察觉,有时他们却又隐藏极深,难以察觉。大多数读者可能不明白为什么类型转换是不安全的,这里用C语言举一个简单的例子:
int main(){ double pi = 3.;double *pv = πvoid *temp = pd;int *p = temp;}在标准C语言中,任何非void类型的指针都可以和void类型的指针相互指派,也可以通过void类型指针作为中介,实现不同类型的指针间接相互转换。上面示例中,指针pv指向的空间本是一个双精度数据,占8个字节,但是经过转换后,p指向的是一个4字节的int类型。这种发生内存截断的设计缺陷会在转换后进行内存访问是存在安全隐患。我想这就是Go语言被设计成强类型语言的原因之一吧。
虽然类型转换是不安全的,但是在一些特殊场景下,使用了它,可以打破Go的类型和内存安全机制,可以绕过类型系统低效,提高运行效率。所以Go标准库中提供了一个unsafe包,之所以叫这个名字,就是不推荐大家使用,但是不是不能用,如果你掌握的特别好,还是可以实践的。
unsafe 实现原理在使用之前我们先来看一下unsafe的源码部分,标准库unsafe包中只提供了3``种方法,分别是:
func Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptrSizeof(x ArbitrayType)方法主要作用是用返回类型x所占据的字节数,但并不包含x所指向的内容的大小,与C语言标准库中的Sizeof()方法功能一样,比如在位机器上,一个指针返回大小就是4字节。
Offsetof(x ArbitraryType)方法主要作用是返回结构体成员在内存中的位置离结构体起始处(结构体的第一个字段的偏移量都是0)的字节数,即偏移量,我们在注释中看一看到其入参必须是一个结构体,其返回值是一个常量。
Alignof(x ArbitratyType)的主要作用是返回一个类型的对齐值,也可以叫做对齐系数或者对齐倍数。对齐值是一个和内存对齐有关的值,合理的内存对齐可以提高内存读写的性能。一般对齐值是2^n,最大不会超过8(受内存对齐影响).获取对齐值还可以使用反射包的函数,也就是说:unsafe.Alignof(x)等价于reflect.TypeOf(x).Align()。对于任意类型的变量x,unsafe.Alignof(x)至少为1。对于struct结构体类型的变量x,计算x每一个字段f的unsafe.Alignof(x,f),unsafe.Alignof(x)等于其中的最大值。对于array数组类型的变量x,unsafe.Alignof(x)等于构成数组的元素类型的对齐倍数。没有任何字段的空struct{ }和没有任何元素的array占据的内存空间大小为0,不同大小为0的变量可能指向同一块地址。
细心的朋友会发发现这三个方法返回的都是uintptr类型,这个目的就是可以和unsafe.poniter类型相互转换,因为*T是不能计算偏移量的,也不能进行计算,但是uintptr是可以的,所以可以使用uintptr类型进行计算,这样就可以可以访问特定的内存了,达到对不同的内存读写的目的。三个方法的入参都是ArbitraryType类型,代表着任意类型的意思,同时还提供了一个Pointer指针类型,即像void *一样的通用型指针。
type ArbitraryType inttype Pointer *ArbitraryType// uintptr 是一个整数类型,它足够大,可以存储type uintptr uintptr上面说了这么多,可能会有点懵,在这里对三种指针类型做一个总结:
*T:普通类型指针类型,用于传递对象地址,不能进行指针运算。
unsafe.poniter:通用指针类型,用于转换不同类型的指针,不能进行指针运算,不能读取内存存储的值(需转换到某一类型的普通指针)
uintptr:用于指针运算,GC不把uintptr当指针,uintptr无法持有对象。uintptr类型的目标会被回收。
三者关系就是:unsafe.Pointer是桥梁,可以让任意类型的指针实现相互转换,也可以将任意类型的指针转换为uintptr进行指针运算,也就说uintptr是用来与unsafe.Pointer打配合,用于指针运算。画个图表示一下:
基本原理就说到这里啦,接下来我们一起来看看如何使用~
unsafe.Pointer基本使用我们在上一篇分析atomic.Value源码时,看到atomic/value.go中定义了一个ifaceWords结构,其中typ和data字段类型就是unsafe.Poniter,这里使用unsafe.Poniter类型的原因是传入的值就是interface{ }类型,使用unsafe.Pointer强转成ifaceWords类型,这样可以把类型和值都保存了下来,方便后面的写入类型检查。截取部分代码如下:
// ifaceWords is interface{ } internal representation.type ifaceWords struct { typunsafe.Pointer data unsafe.Pointer}// Load returns the value set by the most recent Store.// It returns nil if there has been no call to Store for this Value.func (v *Value) Load() (x interface{ }) { vp := (*ifaceWords)(unsafe.Pointer(v))for { typ := LoadPointer(&vp.typ) // 读取已经存在值的类型/**..... 中间省略**/// First store completed. Check type and overwrite data.if typ != xp.typ { //当前类型与要存入的类型做对比 panic("sync/atomic: store of inconsistently typed value into Value")}}上面就是源码中使用unsafe.Pointer的一个例子,有一天当你准备读源码时,unsafe.pointer的使用到处可见。好啦,接下来我们写一个简单的例子,看看unsafe.Pointer是如何使用的。
func main(){ number := 5 pointer := &number fmt.Printf("number:addr:%p, value:%d\n",pointer,*pointer) floatNumber := (*float)(unsafe.Pointer(pointer)) *floatNumber = *floatNumber + 3 fmt.Printf("float:addr:%p, value:%f\n",floatNumber,*floatNumber)}运行结果:
number:addr:0xc, value:5float:addr:0xc, value:3.由运行可知使用unsafe.Pointer强制类型转换后指针指向的地址是没有改变,只是类型发生了改变。这个例子本身没什么意义,正常项目中也不会这样使用。
总结一下基本使用:先把*T类型转换成unsafe.Pointer类型,然后在进行强制转换转成你需要的指针类型即可。
Sizeof、Alignof、Offsetof三个函数的基本使用先看一个例子:
type User struct { Name string Age uint Gender bool // 男:true 女:false 就是举个例子别吐槽我这么用。。。。}func func_example(){ // sizeof fmt.Println(unsafe.Sizeof(true)) fmt.Println(unsafe.Sizeof(int8(0))) fmt.Println(unsafe.Sizeof(int())) fmt.Println(unsafe.Sizeof(int())) fmt.Println(unsafe.Sizeof(int())) fmt.Println(unsafe.Sizeof("asong")) fmt.Println(unsafe.Sizeof([]int{ 1,3,4})) // Offsetof user := User{ Name: "Asong", Age: ,Gender: true} userNamePointer := unsafe.Pointer(&user) nNamePointer := (*string)(unsafe.Pointer(userNamePointer)) *nNamePointer = "Golang梦工厂" nAgePointer := (*uint)(unsafe.Pointer(uintptr(userNamePointer) + unsafe.Offsetof(user.Age))) *nAgePointer = nGender := (*bool)(unsafe.Pointer(uintptr(userNamePointer)+unsafe.Offsetof(user.Gender))) *nGender = false fmt.Printf("u.Name: %s, u.Age: %d,u.Gender: %v\n", user.Name, user.Age,user.Gender) // Alignof var b bool var i8 int8 var i int var i int var f float var s string var m map[string]string var p *int fmt.Println(unsafe.Alignof(b)) fmt.Println(unsafe.Alignof(i8)) fmt.Println(unsafe.Alignof(i)) fmt.Println(unsafe.Alignof(i)) fmt.Println(unsafe.Alignof(f)) fmt.Println(unsafe.Alignof(s)) fmt.Println(unsafe.Alignof(m)) fmt.Println(unsafe.Alignof(p))}为了省事,把三个函数的使用示例放到了一起,首先看sizeof方法,我们可以知道各个类型所占字节大小,这里重点说一下int类型,Go语言中的int类型的具体大小是跟机器的 CPU位数相关的。如果 CPU 是 位的,那么int就占4字节,如果 CPU是位的,那么 int 就占8 字节,这里我的电脑是位的,所以结果就是8字节。
然后我们在看Offsetof函数,我想要修改结构体中成员变量,第一个成员变量是不需要进行偏移量计算的,直接取出指针后转换为unsafe.pointer,在强制给他转换成字符串类型的指针值即可。如果要修改其他成员变量,需要进行偏移量计算,才可以对其内存地址修改,所以Offsetof方法就可返回成员变量在结构体中的偏移量,也就是返回结构体初始位置到成员变量之间的字节数。看代码时大家应该要住uintptr的使用,不可以用一个临时变量存储uintptr类型,前面我们提到过用于指针运算,GC不把uintptr当指针,uintptr无法持有对象。uintptr类型的目标会被回收,所以你不知道他什么时候会被GC掉,那样接下来的内存操作会发生什么样的错误,咱也不知道。比如这样一个例子:
// 切记不要这样使用p1 := uintptr(userNamePointer)nAgePointer := (*uint)(unsafe.Pointer(p1 + unsafe.Offsetof(user.Age)))最后看一下Alignof函数,主要是获取变量的对齐值,除了int、uintptr这些依赖CPU位数的类型,基本类型的对齐值都是固定的,结构体中对齐值取他的成员对齐值的最大值,结构体的对齐涉及到内存对齐,我们在下面详细介绍。
经典应用:string与[]byte的相互转换实现string与byte的转换,正常情况下,我们可能会写出这样的标准转换:
// string to []bytestr1 := "Golang梦工厂"by := []byte(s1)// []byte to stringstr2 := string(by)使用这种方式进行转换都会涉及底层数值的拷贝,所以想要实现零拷贝,我们可以使用unsafe.Pointer来实现,通过强转换直接完成指针的指向,从而使string和[]byte指向同一个底层数据。在reflect包中有·string和slice对应的结构体,他们的分别是:
type StringHeader struct { Data uintptr Lenint}type SliceHeader struct { Data uintptr Lenint Capint}StringHeader代表的是string运行时的表现形式(SliceHeader同理),通过对比string和slice运行时的表达可以看出,他们只有一个Cap字段不同,所以他们的内存布局是对齐的,所以可以通过unsafe.Pointer进行转换,因为可以写出如下代码:
func Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptr0上面的代码我们通过重新构造slice header和string header完成了类型转换,其实[]byte转换成string可以省略掉自己构造StringHeader的方式,直接使用强转就可以,因为string的底层也是[]byte,强转会自动构造,省略后的代码如下:
func Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptr1虽然这种方式更高效率,但是不推荐大家使用,前面也提高到了,这要是不安全的,使用当不当会出现极大的隐患,一些严重的情况recover也不能捕获。
内存对齐现在计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但是实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就对齐。
对齐的作用和原因:CPU访问内存时,并不是逐个字节访问,而是以字长(word size)单位访问。比如位的CPU,字长为4字节,那么CPU访问内存的单位也是4字节。这样设计可以减少CPU访问内存的次数,加大CPU访问内存的吞吐量。假设我们需要读取8个字节的数据,一次读取4个字节那么就只需读取2次就可以。内存对齐对实现变量的原子性操作也是有好处的,每次内存访问都是原子的,如果变量的大小不超过字长,那么内存对齐后,对该变量的访问就是原子的,这个特性在并发场景下至关重要。
我们来看这样一个例子:
func Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptr2从结果可以看出,字段放置不同的顺序,占用内存也不一样,这就是因为内存对齐影响了struct的大小,所以有时候合理的字段可以减少内存的开销。下面我们就一起来分析一下内存对齐,首先要明白什么是内存对齐的规则,C语言的对齐规则与Go语言一样,所以C语言的对齐规则对Go同样适用:
对于结构的各个成员,第一个成员位于偏移为0的位置,结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的 offset 都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员之间加上填充字节。
除了结构成员需要对齐,结构本身也需要对齐,结构的长度必须是编译器默认的对齐长度和成员中最长类型中最小的数据大小的倍数对齐。
好啦,知道规则了,我们现在来分析一下上面的例子,根据我的mac使用的位CPU,对齐参数是8来分析,int、[]int、string、bool对齐值分别是4、8、8、1,占用内存大小分别是4、、、1,我们先根据第一条对齐规则分析User1:
第一个字段类型是int,对齐值是4,大小为4,所以放在内存布局中的第一位.
第二个字段类型是[]int,对齐值是8,大小为,所以他的内存偏移值必须是8的倍数,所以在当前user1中,就不能从第4位开始了,必须从第5位开始,也就偏移量为8。第4,5,6,7位由编译器进行填充,一般为0值,也称之为空洞。第9位到第位为第二个字段B.
第三个字段类型是string,对齐值是8,大小为,所以他的内存偏移值必须是8的倍数,因为user1前两个字段就已经排到了第位,所以下一位的偏移量正好是,正好是字段C的对齐值的倍数,不用填充,可以直接排列第三个字段,也就是从第位到位第三个字段C.
第三个字段类型是bool,对齐值是1,大小为1,所以他的内存偏移值必须是1的倍数,因为user1前两个字段就已经排到了第位,所以下一位的偏移量正好是。正好是字段D的对齐值的倍数,不用填充,可以直接排列到第四个字段,也就是从到第位是第三个字段D.
好了现在第一条内存对齐规则后,内存长度已经为字节,我们开始使用内存的第2条规则进行对齐。根据第二条规则,默认对齐值是8,字段中最大类型程度是,取最小的那一个,所以求出结构体的对齐值是8,我们目前的内存长度是,不是8的倍数,所以需要补齐,所以最终的结果就是,补了7位。
说了这么多,画个图看一下吧:
现在你们应该懂了吧,按照这个思路再去分析其他两个struct吧,这里就不再分析了。
对于内存对齐这里还有一最后需要注意的知识点,空struct不占用任何存储空间,空 struct{ } 大小为 0,作为其他 struct 的字段时,一般不需要内存对齐。但是有一种情况除外:即当 struct{ } 作为结构体最后一个字段时,需要内存对齐。因为如果有指针指向该字段, 返回的地址将在结构体之外,如果此指针一直存活不释放对应的内存,就会有内存泄露的问题(该内存不因结构体释放而释放)。来看一个例子:
func Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptr3简单来说,对于任何占用0大小空间的类型,像struct { }或者[0]byte这些,如果该类型出现在结构体末尾,那么我们就假设它占用1个字节的大小。因此对于test1结构体,他看起来就是这样:`
func Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptr4因此在内存对齐时,最后结构体占用的字节就是8了。
重点要注意的问题:不要在结构体定义的最后添加零大小的类型
总结好啦,终于又到文章的末尾了,我们来简单的总结一下,unsafe 包绕过了 Go 的类型系统,达到直接操作内存的目的,使用它有一定的风险性。但是在某些场景下,使用 unsafe 包提供的函数会提升代码的效率,Go 源码中也是大量使用 unsafe 包。
unsafe 包定义了 Pointer 和三个函数:
type ArbitraryType inttype Pointer *ArbitraryTypefunc Sizeof(x ArbitraryType) uintptrfunc Offsetof(x ArbitraryType) uintptrfunc Alignof(x ArbitraryType) uintptruintptr 可以和 unsafe.Pointer 进行相互转换,uintptr 可以进行数学运算。这样,通过 uintptr 和 unsafe.Pointer 的结合就解决了 Go 指针不能进行数学运算的限制。通过 unsafe 相关函数,可以获取结构体私有成员的地址,进而对其做进一步的读写操作,突破 Go 的类型安全限制。
最后我们又学习了内存对齐的知识,这样设计可以减少CPU访问内存的次数,加大CPU访问内存的吞吐量,所以结构体中字段合理的排序可以更节省内存,注意:不要在结构体定义的最后添加零大小的类型。
原文:/post/好啦,这篇文章就到这里啦,素质三连(分享、点赞、在看)都是笔者持续创作更多优质内容的动力!
创建了一个Golang学习交流群,欢迎各位大佬们踊跃入群,我们一起学习交流。入群方式:加我vx拉你入群,或者公众号获取入群二维码
结尾给大家发一个小福利吧,最近我在看[微服务架构设计模式]这一本书,讲的很好,自己也收集了一本PDF,有需要的小伙可以到自行下载。获取方式:关注公众号:[Golang梦工厂],后台回复:[微服务],即可获取。
我翻译了一份GIN中文文档,会定期进行维护,有需要的小伙伴后台回复[gin