题目的大致意思是: 假设存在一个无序单链表,将重复结点去除后,并保原顺序。 去重前:1→3→1→5→5→7 去重后:1→3→5→7 顺序删除 通过双重循环直接在链表上执行删除操作。...在遍历链表的过程中,使用了常量个额外的指针变量来保存当前遍历的结点、前驱结点和被删除的结点,因此,空间复杂度为O(1)。...算法性能分析 这种方法与方法一类似,从本质上而言,由于这种方法需要对链表进行双重遍历,因此,时间复杂度为O(N^2)。其中,N为链表的长度。...建立一个HashSet,HashSet中的内容为已经遍历过的结点内容,并将其初始化为空。...如链表:1,3、5、5、7、7、8、9 去重后:1,3、5、7、8、9 分析与解答 上述介绍的方法也适用于链表有序的情况,但是由于以上方法没有充分利用到链表有序这个条件,因此,算法的性能肯定不是最优的。
的子类,用户可以定制类的加载方式 PC寄存器 每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,也即将 要执行的指令代码),由执行引擎读取下一条指令...方法区存放内容: • 类信息 类的版本 字段 方法 接口 • 静态变量 • 常量 • 类信息(构造方法/接口定义) • 运行时常量池 静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中...)的一个实现,jdk1.7的版本中,已经将原本放在永久代的 字符串常量池移走。...类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保 存所有引用类型的真实信息,以方便执行器执行。...)的一个实现,jdk1.7的版本中,已经将原本放在永久代的 字符串常量池移走。
典型应用就是数据库连接管理,以及独立会话管理 栈、堆、方法区的交互关系 Person 类的 .class 信息存放在方法区中 person 变量存放在 Java 栈的局部变量表中 真正的 person...对象存放在 Java 堆中 在 person 对象中,有个指针指向方法区中的 person 类型数据,表明这个 person 对象是用方法区中的 Person 类 new 出来的 2.方法区的理解...JDK 1.8之后,元空间存放在堆外内存中 我们可以将方法区类比为Java中的接口,将永久代或元空间类比为Java中具体的实现类 本质上,方法区和永久代并不等价。...而Java中的字节码需要数据支持,通常这种数据会很大以至于不能直接存到字节码里,换另一种方式,可以存到常量池 这个字节码包含了指向常量池的引用。...如果不使用常量池,就需要将用到的类信息、方法信息等记录在当前的字节码文件中,造成文件臃肿 所以我们将所需用到的结构信息记录在常量池中,并通过引用的方式,来加载、调用所需的结构 这里的代码量其实很少了,如果代码多的话
继承:通过继承机制,一个类可以从另一个类中继承某些属性和方法,并在此基础上添加新的属性和方法,从而避免了重复编写代码的冗余,提高了代码的可重用性和可维护性。...当我们访问野指针时,程序会出现不可预期的行为,甚至崩溃。 为了避免野指针,我们可以采取以下措施: 在指针使用前初始化 在定义一个指针变量的时候,我们应该立即将其初始化为一个有效的地址。...int* p = nullptr; // 初始化为空指针 在指针使用后及时置空 当指针变量不再使用时,我们应该将其置为空指针,防止误用。这样可以有效地避免产生野指针。...无论何种情况,我们应该保持谦虚、认真和热情,去面对每一个机会,以便在面试中显示出自己的技能和才能。 基类的析构函数为何要声明为虚函数?...在C++中,extern关键字用于声明一个已经在别处定义的变量、函数或类的引用,从而允许在一个文件中使用在其他文件中定义的全局变量、函数或类。
f@@YAXH@Z),该符号在函数 _main 中被引用) 补充:如何解决头文件中声明定义的函数在.cpp等文件中重复包含问题(链接错误,重定义)?...常量定义 换用const enum 短小函数定义,换用内联函数 二、 auto关键字(C++11) 随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在: 类型难于拼写 含义不明确导致容易出错...3.2 范围for的使用条件 for循环迭代的范围必须是确定的 对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin()和end()的方法,begin()和end()...(此处++, ==是在迭代器的类域中重载后的操作符,关于迭代器这个问题,后面会讲) 四、 指针空值nullptr(C++11) 在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,...在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。
const 应用到函数中:作为参数的 const 修饰符:调用函数的时候,用相应的变量初始化 const 常量,则在函数体中,按照 const 所修饰的部分进行常量化,保护了原对象的属性。...成员变量中如果想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现或者 static const。...除了基本数据类型之外,其余的都作为类对象,对象将数据和方法结合起来,把它们封装在类中,这样每个对象都可以实现自己的特点和行为。Java 中取消了 C++ 中的 struct 和 union 。...指针它指向一块内存,指针的内容是所指向的内存的地址,在编译的时候,则是将“指针变量名-指针变量的地址”添加到符号表中,所以说,指针包含的内容是可以改变的,允许拷贝和赋值,有 const 和非 const...在析构函数中也是同理,派生类执行了析构函数后,派生类的自身成员呈现未定义的状态,那么在执行基类的析构函数中是不可能调用到派生类重写的方法的。
前者表示指针p指向整型常变量(指针所指单元的内容不允许修改),而指针本身可以指向其他的常变量,即p为指向常量的指针——常量指针。...后者表示指针p本身的值不可修改,一旦p指向某个整型变量之后就不能指向其他的变量,即p是个指针常量。 (5)引用本身可以理解为指针常量,在引用前使用const没有意义。...但在某些情况下,const只能放在特定的位置,考查const配合二重指针的例子,代码如下: int main(int argc,char* argv[]) { //const配合二重指针...p1不 是指针常量,它所指向的变量的类型是int const *(指向整型常量的指针)。P2也不是指针常量,其指向的变量类型是int* const(整型指针常量)。...类对象的非静态常量成员必须在构造函数中初始化,且只能借助于初始化列表,因为初始化列表才是初始化,构造函数中通过赋值运算符进行的是赋值,并非初始化。
面试题 带着问题学习是最高效的,本次我们将尝试回答以下问题: 什么是类的加载? 哪些情况会触发类的加载? 讲一下JVM加载一个类的过程 什么时候会为变量分配内存? JVM的类加载机制是什么?...校验 顾名思义,检查Class文件的字节流中包含的信息是否符合当前虚拟机的要求。 准备 这一步中将为静态变量和静态常量分配内存,并赋值。 需要注意的是,静态变量只会给默认值。...解析 解析阶段就是jvm将常量池的符号引用替换为直接引用。 恩......啥是常量池?啥是符号引用?啥是直接引用? 常量池我们放在jvm内存结构里说。先来说下什么是符号引用和直接引用。...通过数组来引用类,不会触发类的初始化。因为new的是数组,而不是类。 调用类的静态常量不会触发类的初始化,因为静态常量在编译阶段就会被存入调用类的常量池中,不会引用到定义常量的类。...当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。 为啥要搞这么复杂?自己处理不好吗? 双亲委派的优点如下: 避免重复加载。
优点:默认将结构体初始化为“不可能的”值,使调试更加容易。 缺点:对代码编写者来说,这是多余的工作。 结论:如果类中定义了成员变量,没有提供其他构造函数,你需要定义一个默认构造函数(没有参数)。...在将类作为STL容器值得时候,你可能有使类可拷贝的冲动。类似情况下,真正该做的是使用指针指向STL容器中的对象,可以考虑使用std::tr1::shared_ptr。...struct被用在仅包含数据的消极对象(passiveobjects)上,可能包括有关联的常量,但没有存取数据成员之外的函数功能,而存取功能通过直接访问实现而无需方法调用,这儿提到的方法是指只用于处理数据成员的...(5)当重定义派生的虚函数时,在派生类中明确声明其为virtual,直观明了的指明该函数是虚函数,达到代码即注释的效果,提高代码可读性。 8....综上所述,在类数据成员中使用到自定义类型时,使用指针是一个较为明智地选择,有如下几个优点: (1)成员对象类的变化不会引起包含类的重编译; (2)支持惰性计算,不创建不使用的对象,效率更高; (3
而C++在取名的时候,是将函数名和参数类型的首字符结合起来对函数的取名,这样就可以区分函数的不同了。 拓展:说说函数重载、函数重写、函数重定义区分: 在作用域中:函数重载在需要在同一个作用域中。...函数重定义和函数重写的两个函数必须一个在父类中,一个在子类中,而且函数重写必须是虚函数。...函数重载和函数重定义需要的是函数名相同,参数列表不同,函数重写需要函数名相同、参数列表相同和返回值相同(例外情况是协变和析构函数的重写。协变是返回值可以不同,但是返回值必须是父子关系类的指针或引用。...在类中,成员变量被修饰后,是属于所有类的,所有类的对象都可以调用它,而且是不需要this指针去引用。...说一说宏的优缺点,有什么解决办法 宏的优点是增强代码的复用性,比如用宏来定义一个常量,那么在后续的代码中我或许需要多次用到这个常量。还有就是可以提高性能。
常量定义 换用const enum 2. 短小函数定义 换用内联函数 随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在: 1. 类型难于拼写 2....含义不明确导致容易出错 C++中的auto关键字(C++11) 类型别名思考 随着程序越来越复杂,程序中用到的类型也越来越复杂,经常体现在: 1. 类型难于拼写 2....; 对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。...指针空值nullptr(C++11) C++98中的指针空值 在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现 不可预料的错误,比如未初始化的指针。...在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0
引用在声明时必须初始化为另一变量,一旦出现必须为typename refname &varname形式;指针声明和定义可以分开,可以先只声明指针变量而不初始化,等用到时再指向具体变量。...),生成汇编文件 汇编阶段:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件 链接阶段:将多个目标文件及所需要的库打包连接成最终的可执行目标文件(或库文件以供其他程序使用) 6、堆和栈的区别是什么...浅拷贝: 在拥有指针成员的类中,一个对象利用拷贝构造函数或者赋值函数拷贝或者赋值给另一个对象的时候,直接将这个对象的指针成员赋值给另一个对象的指针成员,将一个指针赋值给另一个指针,就会使两个指针指向同一个空间...建立公共溢出区:这种方法的基本思想是:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。...重载则要求参数列表不同,返回值不要求 重写关系中,调用方法根据对象类型决定,重载根据调用时实参表与形参表的对应关系来选择函数体 隐藏(hide): 隐藏指的是某些情况下,派生类中的函数屏蔽了基类中的同名函数
通过分析Android代码,这种方法最终也会调用到上图中的dvmSetNativeFunc等函数,将函数地址保存到虚拟机中供下次调用。...所以要使新的so工作,那我们也必须要设法更新虚拟机已经保存的函数指针,将其指向新加载so的正确地址。...四、其他问题 以上方案主要解决了so的卸载,重加载和JNI函数调用问题。但除了这些问题之外,so代码的细节上还有许多要注意的地方。...CRASH 卸载so后,除了JNI函数的指针,其它指向so地址的指针也都会失效,包括指向静态变量,常量,native函数的指针等。所有引用到该so地址的指针都需要更新。...内存和资源泄漏 native代码中可能存在各种分配内存和资源的行为,使用以上方法更新so前,如果没有仔细处理这些资源,就会丢失原指针,造成内存泄漏。
第二部分是类型指针,即对象指向它的类的元数据指针,虚拟机通过这个指针确定这个对象是哪个类的实例。...可作为 GC Roots 的对象: 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中类静态属性引用的对象 方法区中常量引用的对象 本地方法栈中 JNI(即一般说的 Native...read 主内存 把一个变量的值从主内存传输到线程工作内存中,以便 load 操作使用 load 工作内存 把 read 操作从主内存中得到的变量值放入工作内存中 use 工作内存 把工作内存中一个变量的值传递给执行引擎...,每当虚拟机遇到一个需要使用到变量值的字节码指令时将会执行这个操作 assgin 工作内存 把一个从执行引擎接收到的值赋接收到的值赋给工作内存的变量,每当虚拟机遇到一个给变量赋值的字节码指令时执行这个操作...store 工作内存 把工作内存中的一个变量的值传送到主内存中,以便 write 操作 write 工作内存 把 store 操作从工作内存中得到的变量的值放入主内存的变量中 对于
两者不要搞混 局部变量表 局部变量表在类加载中加载 Code 属性的时候就已经被初始化 局部变量表长度 = 方法参数数量 + 本地变量数量 方法参数数量和本地变量数量记录在方法的 Code 属性中:.../** * 把堆栈中的方法调用参数存入方法本地变量 * 调用方法前,父程序把函数参数推入堆栈,方法调用时,需要把堆栈中的参数存到本地变量 * @param method method * @param...xstore_n 将栈顶x型数值存入第n个局部变量 xadd 栈顶两x型数值相加,并且结果进栈 return 当前方法返回void getstatic 获取指定类的静态域,并将其值压入栈顶 putstatic...指令将 a 和 b 从本地变量中压入操作数栈 执行 add 指令,add 指令将操作数栈的栈顶两个值相加并清空这两个操作数,产生的结果压入操作数栈顶 最后用 store 指令将运算结果存到本地变量表的...(MethodHandle) 转换成 MethodInfo * pointer,这才是真正要调用方法的指针,并且存到 bootMethod->make 缓存中 最后的最后真正执行 lambda 表达式所指向的方法
优点:默认将结构体初始化为“不可能的”值,使调试更加容易。 缺点:对代码编写者来说,这是多余的工作。 结论:如果类中定义了成员变量,没有提供其他构造函数,你需要定义一个默认构造函数(没有参数)。...在将类作为STL容器值得时候,你可能有使类可拷贝的冲动。类似情况下,真正该做的是使用指针指向STL容器中的对象,可以考虑使用std::tr1::shared_ptr。...struct被用在仅包含数据的消极对象(passiveobjects)上,可能包括有关联的常量,但没有存取数据成员之外的函数功能,而存取功能通过直接访问实现而无需方法调用,这儿提到的方法是指只用于处理数据成员的...(5)当重定义派生的虚函数时,在派生类中明确声明其为virtual。这样做的原因属于代码性注释,直观明了的指明该函数是虚函数。 8....综上所述,在类数据成员中使用到自定义类型时,使用指针是一个较为明智地选择,有如下几个优点: (1)成员对象类的变化不会引起包含类的重编译; (2)支持惰性计算,不创建不使用的对象,效率更高;
四、C++关键字 C++总计63个关键字,C语言32个关键字 后面慢慢学吧,感觉一下子也学不会…… 五、命名空间 在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中...缺省值必须是常量或者全局变量 4. C语言不支持(编译器不支持) 八、函数重载 自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重 载了。...也就是说,加了inline的函数会让编译器认为这并不是一个函数,所以不会被存到函数调用符号表里,因此不能将声明和定义分离!!正确的方法是将inline的声明和定义都放在头文件里!...12.2 范围for的使用条件 for循环迭代的范围必须是确定的 对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围...在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void*)0。
大家好,又见面了,我是全栈君 C++中的const关键字的使用方法很灵活,而使用const将大大改善程序的健壮性,本人依据各方面查到的资料进行总结例如以下,期望对朋友们有所帮助。...char* const pContent; (4)还有当中差别方法,沿着*号划一条线: 假设const位于*的左側,则const就是用来修饰指针所指向的变量,即指针指向为常量; 假设const位于*的右側...中的公有(保护)数据成员和const成员函数,而且不同意对其进行赋值操作,这在普通情况下非常少用到。...4、类相关CONST (1)const修饰成员变量 const修饰类的成员函数,表示成员常量,不能被改动,同一时候它仅仅能在初始化列表中赋值。...const应该使用引用或指针,而不是一般的对象实例,原因同上; · const在成员函数中的三种使用方法(參数、返回值、函数)要非常好的使用; · 不要轻易的将函数的返回值类型定为const; · 除了重载操作符外一般不要将返回值类型定为对某个对象的
很多小伙伴会觉得:虚函数存在虚表,虚表存在对象中,注意这种回答是错的。这里再次强调:虚表存的是虚函数的地址,不是虚函数,虚函数和普通的成员函数一样,都是存在代码段的,只是它的地址又存到了虚表中。...函数中如果去访问了成员变量,那么我们这种调用方式就会出问题。...(void*) 是为了将这个指针转换为 void* 类型,以便 printf 正确输出它的地址。...这种方式依赖于对象的实际类型(而不是变量声明的类型)。C++ 中的动态绑定依赖于虚函数(virtual 关键字)实现。 5.2.1 典型场景: 动态绑定通常在类的继承结构中使用虚函数时出现。...在未来的开发中,合理运用多态将为我们的项目带来显著的提升。希望本文的讲解能够帮助读者在实践中更好地掌握这一重要概念。
列表初始化:C++11新标准的一部分,用花括号来初始化变量,这种方法有一定的优势:当使用列表初始化且初始值存在丢失信息的风险时则编译器将报错 默认初始化:如果定义变量时没有指定初值,则变量将被默认初始化...空指针不指向任何对象,在试图使用一个指针之前最好先判断它是否为空。C++11中得到空指针最直接的方法就是字面值nullptr。 建议:初始化所有指针。...const int bufSize = 512;以编译时初始化的方式定义一个const对象时,编译器将在编译过程中把用到该变量的地方都替换成对应的值。...C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,且必须用常量表达式初始化。 处理类型 1....编写自己的头文件 为了确保各个文件中类的定义一致,类通常被定义在头文件中,而且类所在头文件的名字应与类的名字一样。
领取专属 10元无门槛券
手把手带您无忧上云