1.Spring框架@PostConstruct注解详解
2.外包公司面试有什么技巧呢?
3.llvm是内存内存什么
4.VB怎么做动态内存地址的修改器?
5.C/C++ 恨透了 double free or corruption error
Spring框架@PostConstruct注解详解
业务背景:在特定业务场景下,如程序启动时需从数据库加载数据并缓存于内存中,注入注入传统的源码源码依赖查找实现方法可满足需求,但寻求更优雅解决方案时,设置@PostConstruct注解应运而生。内存内存
@PostConstruct注解的注入注入fa源码商店实现:此注解标记的方法会在Spring容器启动时自动执行。实现原理涉及注解功能描述、源码源码源码分析以及方法调用流程追溯。设置
源码分析:@PostConstruct注解的内存内存原理核心在于依赖注入完成后的执行。通过CommonAnnotationBeanPostProcessor类的注入注入构造方法初始化注解类型,随后在PostProcessMergedBeanDefinition方法中,源码源码通过调用父类InitDestroyAnnotationBeanPostProcessor,设置实现对被@PostConstruct注解方法的内存内存调用。此过程中,注入注入通过反射机制执行方法。源码源码
具体流程:在创建和初始化bean时,执行PostConstructTest实例的生命周期元数据方法,先进行依赖注入检查和属性赋值。当依赖注入完成,调用@PostConstruct注解方法。这一过程在bean属性赋值阶段完成,并在初始化前通过CommonAnnotationBeanPostProcessor调用postProcessBeforeInitialization方法,进一步通过反射执行@PostConstruct注解方法。
总结:@PostConstruct注解在Spring容器刷新创建bean实例时构建生命周期元数据,在此元数据中保存注解方法,确保在属性赋值阶段完成依赖检查与注入。在初始化过程中,执行postProcessBeforeInitialization方法,利用反射机制调用@PostConstruct注解方法,实现特定业务场景下的linkedhashmap源码分析自动执行。
外包公司面试有什么技巧呢?
一般来说面试我都记下印象深刻的面试题,其他感觉都没什么好记的,但是今天这个面试的过程感觉是我职业生涯中比较有意思的一次面试,遂分享出来。
今天顶着大太阳出去面试,找了好久终于找到了这家公司的位置,貌似是集体办公区域,就是一层楼有N个公司在办公,也没什么隔断。心想创业公司吧,这样也正常。在这之前已经面过三家公司都挺顺利,公司规模都还可以,还有一家一面也是过了等二面。之所以来这家公司面呢是因为对公司的产品还挺感兴趣的,想来看看。
然后到地方后面试官先给了我一份卷子做,都是些很简单的题,写完后等了好久面试官来了,开始进行面试。面试官先看了下我的简历,然后说你怎么两年才做这么4个项目,尤其是第一家才1个项目。我说外包公司项目多,没必要挨个写上,写上最近一家公司的项目,和之前公司代表性的项目就行了。然后他就教育了我一番,说怎么写这么点儿呢,notepad 源码 分析很容易让人觉得你啥都没做,做过的都得写上。我之前一直以为我这种两年多经验的写一页简历足够了,不过他说了下我觉得确实可以考虑考虑多写一些。。。不过老实说我在想。。难道他毕业四五年了还把刚毕业的项目往简历上写?
吐槽完项目。面试官不知道为什么看着我的简历以为是培训班出来的,然后就旁敲侧击的问我毕业是否有参加过什么培训啊。我满脸黑线,我简历写的我第一份工作毕业就进去的,而且我项目都是专业领域性很强的项目,这是从哪儿看出来的。然后这面试官又问我那你大学都学什么课程啊,我又耐着性子解释了一圈。然后他看问不出啥的就没问了。然后就问了一个项目有关的正常问题。开始问我技术了。
第一个技术就问我spring框架,然后问我spring主要注重哪些技术,我说了就依赖注入和自动化配置,然后这人问我如何学习spring,我说看了spring实战,深入理解spring架构,然后还看了源码,然后这人说你看了官方文档吗,我说看了小部分,eclipse jdk源码然后他说你怎么不多看官方说明文档呢,我说我更多喜欢直接看看源码设计,而且官方文档更多就是说明书的意思,我觉得用来入门还行,要真正了解肯定还是要深入底层去看下。然后争论了一番后他问我springboot自动化配置如何实现的。我从实现原理,源码流程说了一圈,我估计他应该不懂这块儿,然后我说完后他和我说你觉得看这些东西用处大吗,你为什么不看官方文档。我当时真是满脸黑线,合着这官方文档在他眼中是圣经啊。然后又问我springboot如何实现的tomcat启动,我源码解释了一圈后我估计他还是不懂源码这块儿,所以又和我死磕说你这些东西为什么不看官方文档说明呢。。嗨,我第一次看到对官方文档如此执着的人..。。当然了他举了个有意思的例子,说比如你买了个冰箱,你不看说明书你怎么知道如何使用呢。。我真的很想说我看过这台冰箱深入介绍的几本书并且连内部零件构造都了解你觉得我不会用这台冰箱吗。。
然后框架就没问了,老实说我觉得可能是他也不太了解。。leveldb 源码分析然后就问我sql了,说有没有用过索引,sql优化。我说了一些,然后他说下mysql索引类型呢? 我说你指的哪种类型,是hash/b+tree ,还是聚集索引/非聚集索引,还是普通索引/唯一索引/主键索引/..... 这种。然后我估计他对前两个应该不了解,然后恼羞成怒的来了句你觉得我问的是哪个? 我去,这个我哪能知道。然后我就说了下 hash/b+树索引,然后这个人来了句b+树你觉得是什么,是一种算法,还是xxx,我当时很无语,名字都叫树了这难道不应该是一种数据结构吗。 然后又解释了一圈我感觉他可能也不了解这块也就没问了。然后问我算法。
其实就简单的问了句,你了解哪些排序,我说冒泡排序,插入排序,快排,堆排序.....,然后这面试官嘲讽的笑了一声,我赶紧回想了哪个有问题,结果想了下没想到哪个字说的有问题我就问 你为什么笑,然后他说堆排序是什么东西。老实说听到这句话我是真的很想直接走的,但是想下这对不起我请的一上午假。然后我很克制的说了句,你不知道不代表没有,这是任何一本讲数据结构与算法的书都应该会讲到的东西,建议去百度下。然后这个时候我估计他本就有点儿恼羞成怒的心情被彻底点着了,然后开始问我jmm。哦对了,他看着我写笔试题的时候排序那儿说了句这是什么排序。(我觉得快排方法应该还是挺好认的)
jmm问我五大数据区域,我说了后最后我提了一下直接内存,然后这人我估计也不懂,然后就开始说我问你这个了吗?我让你说五大区域你为什么提这个? 你有听清楚我的问题吗? 我当时就?,合着我这多提了一嘴直接给戳高潮了。。。然后赶紧闭嘴了,让他接着问后面的问题。
然后问了我期望薪资,我说了个期望薪资,结果这人说,你觉得你在项目中能承担部门负责人? 还是项目经理? 合着我期望的薪资在这家公司是部门负责人才有的待遇,看这意思应该是觉得我漫天要价。我觉得我要再说我已经有的三个offer都比我刚提的要多怕不是能让他当场爆炸。。当然了,为了不自讨没趣我就说我只能承担个中级开发吧。。。
最后问我有什么想问的,我就照例问了下公司技术栈,然后他说后端用java nodeJs ,我就问为什么后端会用两种技术栈? 然后他回答道,这么用肯定是处于公司技术考量啊,巴拉巴拉的,反正最后也没说个明白为啥会用两种技术。。然后这个时候提了一嘴既然采用nodeJs是觉得更加方便为什么不考虑考虑使用Python。老实说我觉得我这句话作为大家都是技术人员,技术探讨性的问题应该很正常吧,结果这句话不知道为什么又把他戳高潮了,他直接回到 为什么要用Python?我在严肃的和你讲公司技术栈,你觉得这样好吗? 你觉得这样提问好吗?你这样随意的一问觉得合适吗?
最后伴随着这几个疑问,面试结束了。。。老实说我被面的有点稀奇古怪的,尽管他问的问题我觉得我应该全都回答上了,但看他的样子似乎很不高兴
llvm是什么
LLVM是一个开源的编译器基础设施项目。它是采用LLVM技术的工具的集合体,包含了静态编译器,全局共享环境的完整程序构造以及能够重构优化的动态二进制执行系统等重要部分。LLVM的目标是提供一种可扩展的、模块化的框架,允许开发人员以一种统一的方式来处理程序的编译过程。 关于LLVM的详细解释: 1. LLVM的基本概念:LLVM是Low Level Virtual Machine的缩写,这是一个通用的编译工具和库集合,这些工具与库旨在以高度优化的方式生成代码。它不仅包含一套编译器工具链,如Clang前端工具,还包含一系列运行时库,这些库为各种语言提供了高效的运行时支持。 2. LLVM的特性:LLVM提供了许多重要的特性来支持程序的编译与执行过程。其中包括支持多种语言编程的通用编译器架构、代码生成的高效性和灵活性以及高度的模块化设计,使得开发人员能够根据需要选择不同的工具和库来实现不同的功能。此外,LLVM还提供了丰富的优化选项和调试支持,使得开发者能够更容易地调试和优化他们的代码。 3. LLVM的应用场景:由于LLVM的强大功能和高效性能,它被广泛用于多种场景。无论是操作系统开发、高性能计算还是嵌入式系统等领域,都可以看到LLVM的身影。同时,许多知名的软件项目也采用了LLVM技术来提高其性能和稳定性。此外,由于LLVM是开源的,开发者可以自由地访问和使用其源代码,这使得LLVM能够在开源社区中得到广泛的应用和推广。最后值得一提的是,使用LLVM的静态编译功能可以有效避免运行时内存注入漏洞带来的安全隐患问题,因而很多行业应用的软件和嵌入式系统中都开始采用LLVM技术。VB怎么做动态内存地址的修改器?
vb改内存跟位操作没关系,只要你会用ReadProcessMemory和WriteProcessMemory就能做修改器
修改动态地址一般两种方法:找基址和偏移,代码注入
我以前做了个植物大战僵尸修改器,部分源码我贴上来,是代码注入的,你参考下:
Option Explicit
Private Declare Function FindWindow Lib "user" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel.dll" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel" (ByVal hObject As Long) As Long
Const PROCESS_ALL_ACCESS = &H1F0FFF
Dim hHwnd As Long
Dim pid As Long
Dim hProcess As Long
Dim base(5) As Long
Private Sub doSun() '无限阳光
WriteProcessMemory hProcess, ByVal &HBAB5, &HE9, 1, 0 'jmp E
WriteProcessMemory hProcess, ByVal &HBAB6, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HBAB7, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HBAB8, &HE3, 1, 0
WriteProcessMemory hProcess, ByVal &HBAB9, &HFF, 1, 0
WriteProcessMemory hProcess, ByVal &HBABA, &H, 1, 0 'nop
WriteProcessMemory hProcess, ByVal &HE, &H3E, 1, 0 'add eax,dword ptr ds:[edx+]
WriteProcessMemory hProcess, ByVal &HE, &H3, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H0, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H0, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0 'mov dword ptr [E],edx
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HEA, &HE1, 1, 0
WriteProcessMemory hProcess, ByVal &HEB, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HEC, &H0, 1, 0
WriteProcessMemory hProcess, ByVal &HED, &HE9, 1, 0 'jmp BABB
WriteProcessMemory hProcess, ByVal &HEE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HEF, &HD9, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H1C, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H0, 1, 0
End Sub
Private Sub doFreeze() '冻结时间
WriteProcessMemory hProcess, ByVal &HE, &HE9, 1, 0 'jmp E
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE7A, &HDC, 1, 0
WriteProcessMemory hProcess, ByVal &HE7B, &HFF, 1, 0
WriteProcessMemory hProcess, ByVal &HE7C, &H, 1, 0 'nop
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0 'mov dword ptr ss:[ebp+],eax
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0 'mov dword ptr [E],ebp
WriteProcessMemory hProcess, ByVal &HE, &H2D, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &HE1, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H0, 1, 0
WriteProcessMemory hProcess, ByVal &HEA, &H, 1, 0 'mov dword ptr ss:[ebp+],eax
WriteProcessMemory hProcess, ByVal &HEB, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HEC, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HED, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HEE, &HE9, 1, 0 'jmp E7D
WriteProcessMemory hProcess, ByVal &HEF, &H6A, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &HAD, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H0, 1, 0
WriteProcessMemory hProcess, ByVal &HE, &H, 1, 0 'nop
End Sub
Private Sub Timer1_Timer()
Static isChange As Boolean
hHwnd = FindWindow(vbNullString, "植物大战僵尸中文版")
If hHwnd <> 0 Then
Call GetWindowThreadProcessId(hHwnd, pid)
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
If hProcess <> 0 Then
If isChange = False Then
'代码注入
Call doSun
Call doFreeze
isChange = True
End If
If myCheck(0).Value = 1 Then '无限阳光
ReadProcessMemory hProcess, &HE, base(0), 4, 0
WriteProcessMemory hProcess, base(0) + &H, , 4, 0 '阳光数量改成
End If
If myCheck(1).Value = 1 Then '冻结时间
ReadProcessMemory hProcess, &HE, base(1), 4, 0
WriteProcessMemory hProcess, base(1) + &H, , 4, 0 '冻结时间
End If
End If
End If
End Sub
C/C++ 恨透了 double free or corruption error
在C/C++编程中,动态内存的管理至关重要,不当的管理方式会导致诸如"double free or corruption"这样的运行时错误。动态内存允许程序员根据需要分配和释放内存空间,这种灵活性同时伴随着管理的挑战。在C语言中,通过`malloc`和`free`函数实现内存的分配与释放,而在C++中,除了这两个函数,还提供了`new`和`delete`操作符进行内存的动态管理。
`malloc`函数用于申请一块内存空间,返回该空间的首地址,`free`函数用于释放内存空间。在C++中,`new`操作符用于动态分配内存,`delete`操作符用于释放由`new`分配的内存。正确使用这些函数对于避免内存泄漏至关重要。
然而,问题往往出现在内存的释放上。不当的释放会导致“double free”或内存损坏。例如,在一个程序的不同地方,错误地释放了同一块内存,或者释放已经释放过的内存,这都可能导致内存管理数据结构破坏,进而引发程序崩溃。更严重的情况下,攻击者可能利用这种错误,在内存中写入恶意代码,从而执行任意指令。
内存释放之后,系统通常会将其加入到一个链表中,以备后续分配使用。这个链表使得较小的空闲内存可以组合成更大的内存块,更灵活地满足分配需求。然而,如果攻击者能够破坏这个链表,如覆盖寄存器值,就有可能将恶意代码注入内存,进而改变程序执行流程或提升权限。
要避免“double free or corruption”错误,一个关键的实践是初始化内存指针,并在释放内存后立即置为`NULL`。此外,负责释放内存的责任应尽量集中在单一模块或文件中,避免在不同源代码文件间分散管理责任,以减少出错的机会。通过这些方法,可以显著降低内存管理错误的发生率,确保程序的稳定性和安全性。