我要做 Android 之面笔试

简介: 二:如何进制转换二进制 → 十进制方法:二进制数从低位到高位(即从右往左)计算,第0位的权值是2的0次方,第1位的权值是2的1次方,第2位的权值是2的2次方,依次递增下去,把最后的结果相加的值就是十进制的值了。

二:如何进制转换

  • 二进制 → 十进制

方法:二进制数从低位到高位(即从右往左)计算,第0位的权值是2的0次方,第1位的权值是2的1次方,第2位的权值是2的2次方,依次递增下去,把最后的结果相加的值就是十进制的值了。

例:将二进制的(101011)B转换为十进制的步骤如下:

\1. 第0位 1 x 2^0 = 1;

\2. 第1位 1 x 2^1 = 2;

\3. 第2位 0 x 2^2 = 0;

\4. 第3位 1 x 2^3 = 8;

\5. 第4位 0 x 2^4 = 0;

\6. 第5位 1 x 2^5 = 32;

\7. 读数,把结果值相加,1+2+0+8+0+32=43,即(101011)B=(43)D。

  • 八进制 → 十进制

方法:八进制数从低位到高位(即从右往左)计算,第0位的权值是8的0次方,第1位的权值是8的1次方,第2位的权值是8的2次方,依次递增下去,把最后的结果相加的值就是十进制的值了。

八进制就是逢8进1,八进制数采用 0~7这八数来表达一个数。

例:将八进制的(53)O转换为十进制的步骤如下:

\1. 第0位 3 x 8^0 = 3;

\2. 第1位 5 x 8^1 = 40;

\3. 读数,把结果值相加,3+40=

(二) (十进制) → (二、八、十六进制)


img_414c206a9d6fd0dd577bbc86e4a90c07.png
04.png

(Figure3:十进制转换为其它进制)

  • 十进制 → 二进制

方法:除2取余法,即每次将整数部分除以2,余数为该位权上的数,而商继续除以2,余数又为上一个位权上的数,这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数读起,一直到最前面的一个余数。

例:将十进制的(43)D转换为二进制的步骤如下:

\1. 将商43除以2,商21余数为1;

\2. 将商21除以2,商10余数为1;

\3. 将商10除以2,商5余数为0;

\4. 将商5除以2,商2余数为1;

\5. 将商2除以2,商1余数为0;

\6. 将商1除以2,商0余数为1;

\7. 读数,因为最后一位是经过多次除以2才得到的,因此它是最高位,读数字从最后的余数向前读,101011,即(43)D=(101011)B。

img_1b2aa3f7c412a15f58082f219a2f1c41.png
05.png

(Figure4:图解十进制 → 二进制)

  • 十进制 → 八进制

方法1:除8取余法,即每次将整数部分除以8,余数为该位权上的数,而商继续除以8,余数又为上一个位权上的数,这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数起,一直到最前面的一个余数。

例:将十进制的(796)D转换为八进制的步骤如下:

\1. 将商796除以8,商99余数为4;

\2. 将商99除以8,商12余数为3;

\3. 将商12除以8,商1余数为4;

\4. 将商1除以8,商0余数为1;

\5. 读数,因为最后一位是经过多次除以8才得到的,因此它是最高位,读数字从最后的余数向前读,1434,即(796)D=(1434)O。


img_a6d50bfa097c7fe7763b5bc4734b0162.png
06.png

43,即(53)O=(43)D。

算法实现:

public static void toBin(int num){
    StringBuffer sb = new StringBuffer();
    while(num>0){
        sb.append(num%2);
        num = num / 2;
    }
    System.out.ptintln(sb.reverse());
}

三:如何正确结束 Java 线程

使用标志位

很简单地设置一个标志位,名称就叫做 isCancelled。启动线程后,定期检查这个标志位。如果 isCancelled = true,那么线程就马上结束。

public class MyThread implements Runnable {
    
    private volatile boolean isCancelled;
    
    public void run() {
        while(!isCancelled){
            //do something
        }
    }
    
    public void cancel() {   isCancelled=true;    }
}

注意的是,isCancelled 需要为 volatile,保证线程读取时 isCancelled 是最新数据。

我以前经常用这种简单方法,在大多时候也很有效,但并不完善。考虑下,如果线程执行的方法被阻塞,那么如何执行isCancelled的检查呢?线程有可能永远不会去检查标志位,也就卡住了。

使用中断

Java提供了中断机制,Thread类下有三个重要方法。

  • public void interrupt()
  • public boolean isInterrupted()
  • public static boolean interrupted(); // 清除中断标志,并返回原状态

每个线程都有个boolean类型的中断状态。当使用Thread的interrupt()方法时,线程的中断状态会被设置为true。

下面的例子启动了一个线程,循环执行打印一些信息。使用isInterrupted()方法判断线程是否被中断,如果是就结束线程。

public class InterruptedExample {

    public static void main(String[] args) throws Exception {
        InterruptedExample interruptedExample = new InterruptedExample();
        interruptedExample.start();
    }

    public void start() {
        MyThread myThread = new MyThread();
        myThread.start();

        try {
            Thread.sleep(3000);
            myThread.cancel();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private class MyThread extends Thread {

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    System.out.println("test");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    System.out.println("interrupt");
                    //抛出InterruptedException后中断标志被清除,标准做法是再次调用interrupt恢复中断
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println("stop");
        }

        public void cancel() {
            interrupt();
        }
    }
}

对线程调用interrupt()方法,不会真正中断正在运行的线程,只是发出一个请求,由线程在合适时候结束自己。

例如 Thread.sleep 这个阻塞方法,接收到中断请求,会抛出 InterruptedException,让上层代码处理。这个时候,你可以什么都不做,但等于吞掉了中断。因为抛出 InterruptedException 后,中断标记会被重新设置为false!看 sleep() 的注释,也强调了这点。

记得这个规则:什么时候都不应该吞掉中断!每个线程都应该有合适的方法响应中断!

所以在InterruptedExample例子里,在接收到中断请求时,标准做法是执行Thread.currentThread().interrupt()恢复中断,让线程退出。

从另一方面谈起,你不能吞掉中断,也不能中断你不熟悉的线程。如果线程没有响应中断的方法,你无论调用多少次interrupt()方法,也像泥牛入海。

目录
相关文章
|
算法 调度 Android开发
我要做 Android 之面笔试总结
说说什么是工厂模式 ps:之前只是单纯了解过工厂模式,不知道其实有三种工厂模式 一:工厂模式 工厂模式就有三种,它们分别是简单工厂模式(并不在23中模式之中),工厂方法模式以及抽象工厂模式,其中我们通常所说的工厂模式指的是工厂方法模式,工厂方法模式是日常开发中使用频率最高的一种设计模式。
1175 0
|
20天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
22天前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
22 1
|
25天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
7天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
34 19
|
20天前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
7天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
31 14
|
10天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
8天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
18 5
|
7天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。