SDK是什么意思
SDK是Software Development Kit的缩写,即软件开发工具包。它是一组开发工具和文档的集合,提供给开发人员用于构建应用程序、软件框架、操作系统等。SDK包含各种API、库、示例代码、编译器、调试器和其他工具,使开发人员更容易地创建、测试和调试应用程序或软件组件。不同类型的SDK可用于各种平台和操作系统,如Windows、iOS、Android等。
解释型语言是可移植的吗?
解释型语言(如Python、JavaScript、Ruby等)一般而言也是可移植的。因为这些语言在运行时不需要像编译型语言一样生成可执行文件,而是直接解析源代码并将其翻译成机器语言实现功能。所以,这些语言的程序源代码本身是可移植的,可以不加修改地在不同平台上运行。
然而,不同平台的解释器对同一份代码的解释可能存在差异,导致其执行结果可能会受到不同操作系统、硬件配置等的影响。此外,解释型语言的执行速度通常较慢,因为每次运行代码时都需要解析和翻译成机器语言,而无法像编译型语言一样在执行前将所有代码编译为可执行文件。
解释一下AOT
AOT是Ahead-Of-Time的缩写,意为“提前编译”,是一种将程序在运行前编译成本地机器代码的技术。与传统的解释型语言不同,AOT使用编译器将代码编译为与系统硬件和操作系统兼容的本地机器代码,执行时无需再解释和翻译,可以直接运行。
相比于传统的解释型语言,AOT能够提高程序的执行速度和执行效率,减少程序的启动时间,从而更好地满足用户对响应速度和性能的需求。AOT还可以提高程序在安全性方面的表现,因为在编译时可以进行优化和排除一些运行时可能会出现的安全漏洞。
通常,AOT主要应用于计算资源有限或者安全要求高的场景,例如移动设备、Web程序、容器、云服务等。Java、.NET、Rust、Go等编程语言及其框架都支持AOT技术,从而提高程序的性能和安全性。
为什么不全部使用 AOT 呢?
虽然AOT可以提高程序的性能和安全性,但也存在一些使用限制和适用场景的限制。
首先,AOT编译会将程序代码编译成本地机器代码,这意味着程序的大小会变得更大,占用更多的存储空间;而且将代码编译成本地机器码意味着具有跨平台特性的好处会减少。
其次,AOT编译需要花费更多的时间,这对于需要频繁迭代的动态语言和开发环境不利。而且,由于AOT编译是在编译时进行的,意味着程序无法动态地修改和调整其执行环境。
另外,AOT编译不适合动态生成代码,因为生成的代码无法进行AOT编译,只能采用解释执行的方式。
因此,对于需要频繁迭代、动态生成代码、或者需要大量动态性能优化的应用,AOT可能不是最优解决方案。而对于需要更高性能、更高安全性、静态编译、和预编译代码的应用,则可以考虑使用AOT。
continue、break 和 return 的区别是什么?
在循环结构中,当循环条件不满足或者循环次数达到要求时,循环会正常结束。但是,有时候可能需要在循环的过程中,当发生了某种条件之后 ,提前终止循环,这就需要用到下面几个关键词:
- continue :指跳出当前的这一次循环,继续下一次循环。
- break :指跳出整个循环体,继续执行循环下面的语句。
return 用于跳出所在方法,结束该方法的运行。return 一般有两种用法:
- return; :直接使用 return 结束方法执行,用于没有返回值函数的方法
- return value; :return 一个特定值,用于有返回值函数的方法
两层循环内层break会咋样
只会跳出内层循环。
如何跳出两层循环?
使用 OUT 标识符(任意,不一定是OUT)。
public static void main(String[] args) {
test();
}
public static void test(){
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 1; ++j){
if(i == 1) break ;
System.out.println(i + ":" + j);
}
}
}
Output:
0:0
2:0
public static void main(String[] args) {
test();
}
public static void test(){
OUT:
for(int i = 0; i < 3; ++i){
for(int j = 0; j < 1; ++j){
if(i == 1) break OUT;
System.out.println(i + ":" + j);
}
}
}
Output:
0:0
String#equals() 和 Object#equals() 有何区别?
String 中的 equals 方法是被重写过的,比较的是 String 字符串的值是否相等。 Object 的 equals 方法是比较的对象的内存地址。
重载和重写有什么区别?
重载就是同样的一个方法能够根据输入数据的不同,做出不同的处理
重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法
重载
发生在同一个类中(或者父类和子类之间),方法名必须相同,参数列表不同(参数类型不同、个数不同、顺序不同),方法返回值和访问修饰符可以不同。
重载就是同一个类中多个同名方法根据不同的传参来执行不同的逻辑处理。
重写
重写发生在运行期,是子类对父类的允许访问的方法的实现过程进行重新编写。
-
方法名、参数列表必须相同,子类方法返回值类型应比父类方法返回值类型更小或相等,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
-
如果父类方法访问修饰符为 private/final/static 则子类就不能重写该方法,但是被 static 修饰的方法能够被再次声明。
-
构造方法无法被重写。
综上:重写就是子类对父类方法的重新改造,外部样子不能改变,内部逻辑可以改变。
区别点 | 重载方法 | 重写方法 |
---|---|---|
发生范围 | 同一个类 | 子类 |
参数列表 | 必须修改 | 不可以修改 |
返回类型 | 可修改 | 子类方法返回值类型应比父类方法返回值类型更小或相等 |
异常 | 可修改 | 子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等 |
访问修饰符 | 可修改 | 一定不能做更严格的限制(可以降低限制) |
发生阶段 | 编译期 | 运行期 |
方法的重写要遵循“两同两小一大”
- “两同”即方法名相同、形参列表相同;
- “两小”指的是子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;
- “一大”指的是子类方法的访问权限应比父类方法的访问权限更大或相等。
关于 重写的返回值类型 这里需要额外多说明一下,上面的表述不太清晰准确:如果方法的返回类型是 void 和基本数据类型,则返回值重写时不可修改。但是如果方法的返回值是引用类型,重写时是可以返回该引用类型的子类的。
为什么说Java中重载的方法在编译时就确定了
Java 中的方法重载是静态多态性(编译时多态性)的一种表现形式,也就是在编译期间就能够确定具体调用哪个方法。其原因是在方法重载的时候,编译器会根据方法的名称、参数类型、参数个数和参数顺序等信息,生成一个唯一的方法签名,将其作为方法的唯一标识符。在调用该方法时,编译器会根据方法名、参数的类型、个数和顺序等信息,匹配该方法的唯一标识符,从而确定具体调用哪个方法。
例如,下面是一个简单的方法重载示例:
public class Test {
public static void main(String[] args) {
int a = 1, b = 2;
double c = 1.5, d = 2.5;
System.out.println(add(a, b)); // 调用 add(int, int)
System.out.println(add(c, d)); // 调用 add(double, double)
}
public static int add(int a, int b) {
return a + b;
}
public static double add(double a, double b) {
return a + b;
}
}
遇到方法重载的情况怎么办呢?会优先匹配固定参数还是可变参数的方法呢?
答案是会优先匹配固定参数的方法,因为固定参数的方法匹配度更高。
另外,Java 的可变参数编译后实际会被转换成一个数组,我们看编译后生成的 class文件就可以看出来了。