前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >居安思危,面试题还是可以多看看的

居安思危,面试题还是可以多看看的

作者头像
陈宇明
发布2020-12-16 10:22:59
3520
发布2020-12-16 10:22:59
举报
文章被收录于专栏:设计模式
01
ART和Dalvik区别

什么是Dalvik: Dalvik是Google公司自己设计用于Android平台的Java虚拟机。 它可以支持已转换为.dex(即Dalvik Executable)格式的Java应用程序的运行。 .dex格式是专为Dalvik应用设计的一种压缩格式,适合内存和处理器速度有限的系统。 Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik应用作为独立的Linux进程执行。 独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。

什么是ART: 与Dalvik不同,ART使用预编译(AOT,Ahead-Of-Time)。 也就是在APK运行之前,就对其包含的Dex字节码进行翻译,得到对应的本地机器指令,于是就可以在运行时直接执行了。 ART应用安装的时候把dex中的字节码将被编译成本地机器码,之后每次打开应用,执行的都是本地机器码。 去除了运行时的解释执行,效率更高,启动更快。

区别:

  1. Dalvik每次都要编译再运行,Art只会首次启动编译
  2. Art占用空间比Dalvik大(原生代码占用的存储空间更大),就是用“空间换时间”
  3. Art减少编译,减少了CPU使用频率,使用明显改善电池续航
  4. Art应用启动更快、运行更快、体验更流畅、触感反馈更及时

02

简单算法题

解题思路分析: 1、n=0 和 n=1 的时候 并没有其他可选择的,所以可以得出f(0)=0;f(1)=1; 2、n>=2时情况就变复杂起来,但是这个时候可以操作的步骤也就2种 也就是走1步(n-1)与走2步(n-2)。所以可以得到f(n)=f(n-1)+f(n-2); 从当前状态转为下一状态的通用算法既可。 3、 验证,使用2以上的数字验证几次。

答案: 1.递归

代码语言:javascript
复制
public static int f(int n){
if(n<=2) return n;
int x = f(n-1) + f(n-2);
return x;
}

2.迭代

代码语言:javascript
复制
public static int f(int n){
if(n<=2) return n;
if first=1,second=2;
int third=0;
for(int i=3;i<=n;i++){
		third = first+second;
		first = second;
		second = third;
	}
return third;
}

3.动态规划

代码语言:javascript
复制
public static int[] A = new int[100];
public static int f(int n){
if(n<=2){
A[n] = n;
	}
if(A[n]>0){
return A[n];
	} else {
A[n] = f(n-1)+f(n-2);
return A[n];
	}
}

03

谈谈JDK8开始的双冒号::用法及详解

概念

类名::方法名,相当于对这个方法闭包的引用,类似 js 中的一个 function。比如:

代码语言:javascript
复制
Function<String,String> func =  String::toUpperCase;

Function 在 java.util.function 包下,也是 jdk8 新加入的类,同级目录下有很多函数式编程模型接口,比如 Consumer/Predicate/Operator 等,func 相当于一个入参和出参都为 String 的函数,可以直接如下:

代码语言:javascript
复制
func.apply("abc")

接收一个参数,返回一个结果("ABC")。也可以用于代替下面的 Lambda 表达式:

代码语言:javascript
复制
List<String> l = Arrays.asList("a","b","c");
l.stream().map(s -> s.toUpperCase());
l.stream().map(func);

下面自定义一个函数式接口:

代码语言:javascript
复制
public class MyConsumer<String> implements Consumer<String> {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
}

下面这俩种写法等价:

代码语言:javascript
复制
List<String> l = Arrays.asList("a","b","c");

l.forEach(new MyConsumer<>());
l.forEach(s -> System.out.println(s));

但是,这种写法却不行,编译失败:

代码语言:javascript
复制
l.forEach(MyConsumer::accept);

因为 MyConsumer 的 accept 方法不是静态的,如果想使用这个方法,需要一个实例,还需要一个入参,共俩个参数。而 List.forEach 中需要的是 consumer 类型,相当于 s -> {...},只有一个参数。

下面详细分析双冒号使用的各种情况

新建一个类,里面声明四个代表各种情况的方法:

代码语言:javascript
复制
public class DoubleColon {

    public static void printStr(String str) {
        System.out.println("printStr : " + str);
    }

    public void toUpper(){
        System.out.println("toUpper : " + this.toString());
    }

    public void toLower(String str){
        System.out.println("toLower : " + str);
    }

    public int toInt(String str){
        System.out.println("toInt : " + str);
        return 1;
    }
}

把它们用::提取为函数,再使用:

代码语言:javascript
复制
Consumer<String> printStrConsumer = DoubleColon::printStr;
printStrConsumer.accept("printStrConsumer");

Consumer<DoubleColon> toUpperConsumer = DoubleColon::toUpper;
toUpperConsumer.accept(new DoubleColon());

BiConsumer<DoubleColon,String> toLowerConsumer = DoubleColon::toLower;
toLowerConsumer.accept(new DoubleColon(),"toLowerConsumer");

BiFunction<DoubleColon,String,Integer> toIntFunction = DoubleColon::toInt;
int i = toIntFunction.apply(new DoubleColon(),"toInt");

非静态方法的第一个参数为被调用的对象,后面是入参。静态方法因为 jvm 已有对象,直接接收入参。再写一个方法使用提取出来的函数:

代码语言:javascript
复制
public class TestBiConsumer {
    public void test(BiConsumer<DoubleColon,String> consumer){
        System.out.println("do something ...");
    }
}

下面这俩种传入的函数是一样的:

代码语言:javascript
复制
TestBiConsumer obj = new TestBiConsumer();
obj.test((x,y) -> System.out.println("do something ..."));
obj.test(DoubleColon::toLower);
总结

用::提取的函数,最主要的区别在于静态与非静态方法,非静态方法比静态方法多一个参数,就是被调用的实例。

04

Android平台的优势和不足

Android平台手机 5大优势:

1、开放性:Android平台首先就是其开放性,开发的平台允许任何移动终端厂商加入到Android联盟中来。显著的开放性可以使其拥有更多的开发者;

2、挣脱运营商的束缚:在过去很长的一段时间,手机应用往往受到运营商制约,使用什么功能接入什么网络,几乎都受到运营商的控制,而Android用户可以更加方便地连接网络,运营商的制约减少;

3、丰富的硬件选择:由于Android的开放性,众多的厂商会推出千奇百怪,功能特色各具的多种产品。功能上的差异和特色,却不会影响到数据同步、甚至软件的兼容;

4、开发商不受任何限制:Android平台提供给第三方开发商一个十分宽泛、自由的环境,不会受到各种条条框框的阻扰;

5、无缝结合的Google应用: Android平台手机将无缝结合这些优秀的Google服务如地图、邮件、搜索等;

Android平台手机几大不足:

1、安全和隐私:由于手机与互联网的紧密联系,个人隐私很难得到保守。除了上网过程中经意或不经意留下的个人足迹,Google这个巨人也时时站在你的身后,洞穿一切;

2、过分依赖开发商缺少标准配置:在Android平台中,由于其开放性,软件更多依赖第三方厂商,比如Android系统的SDK中就没有内置音乐播放器,全部依赖第三方开发,缺少了产品的统一性;

3、同类机型用户很少:在不少手机论坛都会有针对某一型号的子论坛,对一款手机的使用心得交流,并分享软件资源。而对于Android平台手机,由于厂商丰富,产品类型多样,这样使用同一款机型的用户越来越少,缺少统一机型的程序强化。

05

谈谈Static关键字的用法

代码语言:javascript
复制

Static 修饰的方法/变量等资源是静态资源 在内存中存放在方法区,所有允许访问的对象都可以访问(参考变量的修饰符 public protected等)

static修饰的变量只存在一份,所有可以访问的对象都允许进行修改

static 修饰的变量/方法在内存中被root引用,因此不会被GC回收,

static修饰的变量在类被加载的时候就会被加载

被static修饰的方法/代码块只能引用被static修饰的方法/变量

static的主要用法

  1. 用来修饰变量 可以不需要实例化对象就可以直接引用变量,引用方法ClassName.field;
  2. 修饰方法 可以不需要实例化对象就可以直接引用方法,引用方法 ClassName.method();
  3. 静态块 用来实现需要在类加载时就需要加载的逻辑

06

结束语

如果你有好的答案可以提交至:

https://github.com/codeegginterviewgroup/CodeEggDailyInterview

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码个蛋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ART和Dalvik区别
  • 概念
    • 下面详细分析双冒号使用的各种情况
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档