面试绞肉机——基础知识版
笔试部分(易)
1.在Java中,负责对字节代码解释执行的是(B)
A. 应用服务器
B. 虚拟机
C. 垃圾回收器
D. 编译器
2.静态变量通常存储在进程哪个区?(C)
A.栈区
B.堆区
C.全局区
D.代码区
3.浏览器访问某页面,HTTP协议返回状态码为403时表(B)
A. 找不到该页面
B. 禁止访问
C. 内部服务器访问
D. 服务器繁忙
4.下面代码的运行结果是(C)
public class Test{
public static void main (String[] args){
List<String> a = null;
test(a);
System.out.println(a.size());
}
public static void test(List<String> a){
a=new arrayList<String>();
a.add(“abc”);
}
}
A.0
B.1
C.Java.lang.NullPointerException
D.以上都不正确
5.下面代码的运行结果是()
public class Test {
public int aMethod() {
static int i = 0;
i++;
return i;
}
public static void main (String args[]) {
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
A.0
B.1
C.2
D.编译失败
笔试部分(中)
1.如何提供查询Name字段的性能(B)
A. 在 Name 字段上添加主键
B. 在 Name 字段上添加索引
C. 在 Age 字段上添加主键
D. 在 Age 字段上添加索引
2.在 Servlet 的生命周期中,容器只调用一次的方法是:(C、D)
A. service
B. getServletConfig
C. init
D. destroy
3.以下关于异常的说法正确的是:(D)
A.一旦出现异常,程序运行就终止了
B.如果一个方法申明将抛出某个异常,它就必须真的抛出那个异常
C.在catch子句中匹配异常是一种精确匹配
D.可能抛出系统异常的方法是不需要申明异常的
4.下面哪个不是JAVA关键字(A)
A integer
B double
C float
D default
5.哪个语句创建了一个数组实例(A)
A int[] ia = new int [15];
B. float fa = new float [20];
C. char[] ca = “Some String”;
D. int ia [][] = {4, 5, 6} {1, 2, 3};
笔试部分(难)
(多选)
1.下列说法错误的有(ACD)
A. 在类方法中可用this来调用本类的类方法
B. 在类方法中调用本类的类方法时可直接调用
C. 在类方法中只能调用本类中的类方法
D. 在类方法中绝对不能调用实例方法
2.下面哪些描述是正确的?(BCE)
A. 默认构造器初始化方法变量
B. 默认构造器有和它所在类相同的访问修饰词.
C. 默认构造器调用其父类的无参构造器.
D. 如果一个类没有无参构造器,编译器会它创建一个默认构造器.
E. 只有当一个类没有任何构造器时,编译器会为它创建一个默认构造器
3.哪些声明防止方法覆盖?(AD)
A、final void methoda() {}
B、void final methoda() {}
C、static void methoda() {}
D、static final void methoda() {}
E、final abstract void methoda() {}
4.下列说法错误的有(BCD)
A. 数组是一种对象
B. 数组属于一种原生类
C.int number=[]={31,23,33,43,35,63}
D. 数组的大小可以任意改变
面试部分(易)
1.& 和 && 的区别
参考答案:
&运算符有两种用法:(1)按位与;(2)逻辑与。
&&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true。
&&之所以称为短路运算是因为,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是 null 而且不是空字符串,应当写为 username != null &&!username.equals(""),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的 equals 比较,否则会产生 NullPointerException 异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
2.new 一个对象的过程和 clone 一个对象的过程区别
参考答案:
new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。
clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象(即调用 clone 方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填充完成之后,clone 方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。
3.为什么函数不能根据返回类型来区分重载?
参考答案:
因为调用时不能指定类型信息,编译器不知道你要调用哪个函数。
例如:
float max(int a, int b);
int max(int a, int b);
当调用 max(1, 2);时无法确定调用的是哪个,单从这一点上来说,仅返回值类型不同的重载是不应该允许的。
再比如对下面这两个方法来说,虽然它们有同样的名字和自变量,但其实是很容易区分的:
void f() {}
int f() {}
若编译器可根据上下文(语境)明确判断出含义,比如在 int x=f()中,那么这样做完全没有问题。
然而,我们也可能调用一个方法,同时忽略返回值;我们通常把这称为“为它的副作用去调用一个方法”,因为我们关心的不是返回值,而是方法调用的其他效果。所以假如我们像下面这样调用方法: f(); Java 怎样判断 f()的具体调用方式呢?而且别人如何识别并理解代码呢?由于存在这一类的问题,所以不能。
4.抽象类和接口有什么异同?
参考答案:
不同:
抽象类:
1.抽象类中可以定义构造器
2.可以有抽象方法和具体方法
3.接口中的成员全都是 public 的
4.抽象类中可以定义成员变量
5.有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法
6.抽象类中可以包含静态方法感恩于心,回报于行。
7.一个类只能继承一个抽象类
接口:
1.接口中不能定义构造器
2.方法全部都是抽象方法
3.抽象类中的成员可以是 private、默认、protected、public
4.接口中定义的成员变量实际上都是常量
5.接口中不能有静态方法
6.一个类可以实现多个接口
相同:
1.不能够实例化
2.可以将抽象类和接口类型作为引用类型
3.一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类
5.http 常见的状态码有哪些?
参考答案:
200 OK //客户端请求成功
301 Moved Permanently(永久移除),请求的 URL 已移走。Response 中应该包含一个 Location URL, 说明资
源现在所处的位置
302 found 重定向
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的 URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
面试部分(中)
1.Java 中引用类型都有哪些?
参考答案:
Java 中对象的引用分为四种级别,这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
2.Java8 的“新”特性
参考答案:(可以就一两个问题点深入提问一下)
1、Lamdba表达式
2、函数式接口
3、方法引用和构造引用
4、Stream API
5、接口中的默认方法和静态方法
6、新时间日期API
7、OPtional
8、其他等等
3.GET 和 POST 的区别?
参考答案:
1. GET 请求的数据会附在 URL 之后(就是把数据放置在 HTTP 协议头中),以?分割 URL 和传输数据,参数之间以&相连,如:login.action?name=zhagnsan&password=123456。POST 把提交的数据则放置在是 HTTP 包的包体中。
2. GET 方式提交的数据最多只能是 1024 字节,理论上 POST 没有限制,可传较大量的数据。其实这样说是错误的,不准确的:“GET 方式提交的数据最多只能是 1024 字节",因为 GET 是通过 URL 提交数据,那么 GET 可提交的数据量就跟URL 的长度有直接关系了。而实际上,URL 不存在参数上限的问题,HTTP 协议规范没有对 URL 长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox 等,理论上没有长度限制,其限制取决于操作系统的支持。
3.POST 的安全性要比 GET 的安全性高。注意:这里所说的安全性和上面 GET 提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的 Security 的含义,比如:通过 GET 提交数据,用户名和密码将明文出现在 URL 上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用 GET 提交数据还可能会造成 Cross-site request forgery 攻击。
Get 是向服务器发索取数据的一种请求,而 Post 是向服务器提交数据的一种请求,在 FORM(表单)中,Method默认为"GET",实质上,GET 和 POST 只是发送机制不同,并不是一个取一个发!
4.Cookie 和 Session 的区别
参考答案:
Cookie 是 web 服务器发送给浏览器的一块信息,浏览器会在本地一个文件中给每个 web 服务器存储 cookie。以后浏览器再给特定的 web 服务器发送请求时,同时会发送所有为该服务器存储的 cookie。
Session 是存储在 web 服务器端的一块信息。session 对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
Cookie 和 session 的不同点:
1、无论客户端做怎样的设置,session 都能够正常工作。当客户端禁用 cookie 时将无法使用 cookie。
2、在存储的数据量方面:session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象。
5.字节流和字符流的区别
参考答案:
字节流读取的时候,读到一个字节就返回一个字节; 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在 UTF-8 码表中是 3 个字节)时。先去查指定的编码表,将查到的字符返回。 字节流可以处理所有类型数据,如:图片,MP3,AVI 视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。字节流主要是操作 byte 类型数据,以 byte 数组为准,主要操作类就是 OutputStream、InputStream
字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组。所以字符流是由 Java 虚拟机将字节转化为 2 个字节的 Unicode 字符为单位的字符而成的,所以它对多国语言支持性比较好!如果是音频文件、图片、歌曲,就用字节流好点,如果是关系到中文(文本)的,用字符流好点。在程序中一个字符等于两个字节,java 提供了 Reader、Writer 两个专门操作字符流的类。
面试部分(难)
1.什么是线程池,为什么要用线程池
参考答案:
线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程。
使用线程池的好处
1、线程池改进了一个应用程序的响应时间。由于线程池中的线程已经准备好且等待被分配任务,应用程序可以直接拿来使用而不用新建一个线程。
2、线程池节省了CLR 为每个短生存周期任务创建一个完整的线程的开销并可以在任务完成后回收资源。
3、线程池根据当前在系统中运行的进程来优化线程时间片。
4、线程池允许我们开启多个任务而不用为每个线程设置属性。
5、线程池允许我们为正在执行的任务的程序参数传递一个包含状态信息的对象引用。
6、线程池可以用来解决处理一个特定请求最大线程数量限制问题。
2.悲观锁和乐观锁的区别,怎么实现
参考答案:
悲观锁:一段执行逻辑加上悲观锁,不同线程同时执行时,只能有一个线程执行,其他的线程在入口处等待,直到锁被释放。
乐观锁:一段执行逻辑加上乐观锁,不同线程同时执行时,可以同时进入执行,在最后更新数据的时候要检查这些数据是否被其他线程修改了(版本和执行初是否相同),没有修改则进行更新,否则放弃本次操作。
3.什么是线程死锁?死锁如何产生?如何避免线程死锁?
参考答案:
死锁的介绍:
线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。
死锁的产生的一些特定条件:
1、互斥条件:进程对于所分配到的资源具有排它性,即一个资源只能被一个进程占用,直到被该进程释放 。
2、请求和保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。
3、不剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用。
4、循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。
如何避免:
1、加锁顺序:
当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。当然这种方式需要你事先知道所有可能会用到的锁,然而总有些时候是无法预知的。
2、加锁时限:
加上一个超时时间,若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得的锁,然后等待一段随机的时间再重试。但是如果有非常多的线程同一时间去竞争同一批资源,就算有超时和回退机制,还是可能会导致这些线程重复地尝试但却始终得不到锁。
3、死锁检测:
死锁检测即每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。
4.分布式微服务有哪些技术,各自都有什么作用以及其代表有哪些?
参考答案:
1、服务集群
拆分会根据业务逻辑模块,将单体的项目,拆分成多个独立的项目。每个项目完成一部分业务功能。将每一个独立的项目称之为“服务”。一个 大型的互联网项目,往往有数百上千的服务。从而成为服务集群。一个业务往往需要多个服务共同完成。
2、注册中心:拉取和注册服务信息(如:Nacos、Eureka)
注册中心就可以记录微服务中的,每个服务的ip、端口。当服务A想调用服务B的时候,它不需要自己去记录服务B的IP。只需要去找服务中心即可。
3、配置中心 (如:SpringCloudConfig、Nacos)
统一的管理整个服务群里整千上百的配置,如果有配置需要变更,只需要去配置中心进行更改即可。
4、服务网关 (如:SpringCloudGateway、Zuul)
因为微服务中有很多服务,用户不知道该访问哪一个服务,并且也不是随意访问某一个服务。
所以功能是:【校验身份、请求路由、负载均衡】
·一方面对用户身份进行校验
·另一方面可以将用户的请求路由到具体的服务
·路由中可以做一些负载均衡。
5、分布式缓存 (如:redis)
数据库数据放到内存当中。内存的查询效率会比磁盘(数据库)查询效率高很多。那么也会将缓存作为集群。 用户简单请求先到缓存,缓存未命中,再去数据库。
6、分布式搜索 (如:elasticsearch)
复杂的搜索功能,而海量的复杂搜索必须交给分布式搜索。是因为缓存中的空间有限,不适合海量的数据存储。
7、消息队列 (如:rabbitmq)
异步通信的消息队列组件,对于分布式的服务,业务往往跨越多个服务。例如一个请求来了,先调用A,在调用B…。从而整个业务的链路就很长,调用时长就等于 调用每个服务的时长之和。从而会导致性能的下降。
异步通信的意思是:当请求来了,调用了服务A,A并不是去调用服务B和C,而是发一条消息,通知B和C去工作。然后服务A结束工作。从而业务链路变短了。从而相应时间变短了。从而异步通信可以提高服务的并发,例如在一些秒杀高并发的场景下,就可以去利用了。
8、分布式日志服务 (如:ELK )
那么如此庞大的服务,运行的过程当中,如果出现了问题非常不好排查,从而就有了两个组件:分布式日志组件、分布式日志组件:整个集群当中的服务日志,进行统计、存储、分析。将来出现了问题容易定位。
9、系统监控,链路追踪 (如:SkyWalking)
实时监控整个集群当中,每一个服务节点的运营状态,CPU的负载,占用情况。一旦出现任何问题,直接可以定位到具体的方法。从而快速定位信息。
10、持续集成
成千上万的微服务,那么还需要人工去一点点部署吗?微服务集群还需要进行自动化部署,JenKiins工具可以对微服务项目进行自动化编译,基于doker进行打包,形成镜像。在基于KBS、RANCHER,去实现自动化部署。
机试部分(易)
1.字符串中有重复的内容去重
/**
*
* 题目
*
*/
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("新");
list.add("新");
list.add("华");
list.add("项");
list.add("项");
list.add("项");
list.add("目");
list.add("开");
list.add("开");
list.add("发");
list.add("组");
list.add("组");
System.out.println("没有去重前的数据为>>>"+list.toString());
(_______可多行______)
System.out.println("去重后的数据为>>>"+list.toString());
}
}
/**
*
* 参考答案
*
*/
for(int i = 0;i<list.size()-1;i++){
for(int j = list.size()-1;j>i;j--) {
if(list.get(j).equals(list.get(i))){
list.remove(j);
}
}
}
2.实现一个对象的深拷贝
参考答案:(略,合理即可)
3.代码实现单例模式的懒汉式和饿汉式
参考答案:(略,合理即可)
4.(计算三角形的周长)编写程序,读入三角形的三边,如果输入有效,计算它的周长;否则,显示 输入无效。如果任意两边的和大于第三边,输入有效。
参考答案:(略,合理即可)
5.编程打印下列图案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qZS3gqtt-1675068033447)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230108191145038.png)]
参考答案:(略,合理即可)
机试部分(中)
1.编程打印下列图案
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dbjSvz9o-1675068033448)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230108191225585.png)]
参考答案:(略,合理即可)
2.给你一个字符串数组 names ,和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。
对于每个下标 i,names[i] 和 heights[i] 表示第 i 个人的名字和身高。
请按身高 降序 顺序返回对应的名字数组 names 。
示例 1:
输入:names = ["Mary","John","Emma"], heights = [180,165,170]
输出:["Mary","Emma","John"]
解释:Mary 最高,接着是 Emma 和 John 。
示例 2:
输入:names = ["Alice","Bob","Bob"], heights = [155,185,150]
输出:["Bob","Alice","Bob"]
解释:第一个 Bob 最高,然后是 Alice 和第二个 Bob 。
参考答案:
class Solution {
public String[] sortPeople(String[] names, int[] heights) {
int len = names.length;
String[] rs = new String[len];
// 构造哈希表,key=身高值,value=索引位
HashMap<Integer, Integer> heightMap = new HashMap<>();
for (int i = 0; i < len; i++) {
heightMap.put(heights[i], i);
}
// 对身高从小到大排序
Arrays.sort(heights);
// 倒序遍历身高
for (int i = len - 1, j = 0; i >= 0; i--, j++) {
// 从哈希表,根据身高查找对应的索引
// 根据索引访问姓名数组
rs[j] = names[heightMap.get(heights[i])];
}
return rs;
}
}
3.给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SaKMZZK9-1675068033449)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230108194925665.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R7zxKt2T-1675068033449)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20230108194903962.png)]
参考答案:
class Solution {
public int maxDepth(Node root) {
if (root == null) {
return 0;
}
int maxChildDepth = 0;
List<Node> children = root.children;
for (Node child : children) {
int childDepth = maxDepth(child);
maxChildDepth = Math.max(maxChildDepth, childDepth);
}
return maxChildDepth + 1;
}
}
4.[SQL题]超过经理收入的员工
编写一个SQL查询来查找收入比经理高的员工。
以 任意顺序 返回结果表。
表:Employee
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
| salary | int |
| managerId | int |
+-------------+---------+
Id是该表的主键。
该表的每一行都表示雇员的ID、姓名、工资和经理的ID。
查询结果格式如下所示。
输入:
Employee 表:
+----+-------+--------+-----------+
| id | name | salary | managerId |
+----+-------+--------+-----------+
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | Null |
| 4 | Max | 90000 | Null |
+----+-------+--------+-----------+
输出:
+----------+
| Employee |
+----------+
| Joe |
+----------+
解释: Joe 是唯一挣得比经理多的雇员。
参考答案:
SELECT
a.NAME AS Employee
FROM Employee AS a JOIN Employee AS b
ON a.ManagerId = b.Id
AND a.Salary > b.Salary
;
机试部分(难)
**1.给定一个非负整数 numRows
,生成「杨辉三角」的前 numRows
行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: numRows = 5
输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
示例 2:
输入: numRows = 1
输出: [[1]]
参考答案:
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret = new ArrayList<List<Integer>>();
for (int i = 0; i < numRows; ++i) {
List<Integer> row = new ArrayList<Integer>();
for (int j = 0; j <= i; ++j) {
if (j == 0 || j == i) {
row.add(1);
} else {
row.add(ret.get(i - 1).get(j - 1) + ret.get(i - 1).get(j));
}
}
ret.add(row);
}
return ret;
}
}
2.颠倒给定的 32 位无符号整数的二进制位。
提示:
请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。
在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。
示例 1:
输入:n = 00000010100101000001111010011100
输出:964176192 (00111001011110000010100101000000)
解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。
示例 2:
输入:n = 11111111111111111111111111111101
输出:3221225471 (10111111111111111111111111111111)
解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
因此返回 3221225471 其二进制表示形式为 10111111111111111111111111111111 。
参考答案:
public class Solution {
public int reverseBits(int n) {
int rev = 0;
for (int i = 0; i < 32 && n != 0; ++i) {
rev |= (n & 1) << (31 - i);
n >>>= 1;
}
return rev;
}
}
符号整数 -3,输出表示有符号整数 -1073741825。
示例 1:
输入:n = 00000010100101000001111010011100
输出:964176192 (00111001011110000010100101000000)
解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。
示例 2:
输入:n = 11111111111111111111111111111101
输出:3221225471 (10111111111111111111111111111111)
解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293,
因此返回 3221225471 其二进制表示形式为 10111111111111111111111111111111 。
````java
参考答案:
public class Solution {
public int reverseBits(int n) {
int rev = 0;
for (int i = 0; i < 32 && n != 0; ++i) {
rev |= (n & 1) << (31 - i);
n >>>= 1;
}
return rev;
}
}