Java常见面试题及答案

更新时间:2023-06-24 09:46:25 阅读: 评论:0

Java常见⾯试题及答案
1、⾯向对象的特征有哪些⽅⾯?
答:⾯向对象的特征主要有以下⼏个⽅⾯:
1)抽象:抽象是将⼀类对象的共同特征总结出来构造类的过程,包括数据抽象和⾏为抽象两⽅⾯。抽象只关注对象有哪些属性和⾏为,并不关注这些⾏为的细节是什么。
2)继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为⽗类(超类、基类);得到继承信息的类被称为⼦类(派⽣类)。继承让变化中的软件系统有了⼀定的延续性,同时继承也是封装程序中可变因素的重要⼿段(如果不能理解请阅读阎宏博⼠的《Java 与模式》或《设计模式精解》中关于桥梁模式的部分)。
3)封装:通常认为封装是把数据和操作数据的⽅法绑定起来,对数据的访问只能通过已定义的接⼝。⾯向对象的本质就是将现实世界描绘成⼀系列完全⾃治、封闭的对象。我们在类中编写的⽅法就是对实现细节的⼀种封装;我们编写⼀个类就是对数据和数据操作的封装。可以说,封装就是隐藏⼀切可隐藏的东西,只向外界提供最简单的编程接⼝(可以想想普通洗⾐机和全⾃动洗⾐机的差别,明显全⾃动洗⾐机封装更好因此操作起来更简单;我们现在使⽤的智能⼿机也是封装得⾜够好的,因为⼏个按键就搞定了所有的事情)。
4)多态性:多态性是指允许不同⼦类型的对象对同⼀消息作出不同的响应。简单的说就是⽤同样的对象引⽤调⽤同样的⽅法但是做了不同的事情。多态性分为编译时的多态性和运⾏时的多态性。如果将对象的⽅法视为对象向外界提供的服务,那么运⾏时的多态性可以解释为:当 A 系统访问 B 系统提供的服务时,B系统有多种提供服务的⽅式,但⼀切对 A系统来说都是透明的(就像电动剃须⼑是A系统,它的供电系统是 B系统,B系统可以使⽤电池供电或者⽤交流电,甚⾄还有可能是太阳能,A系统只会通过B类对象调⽤供电的⽅法,但并不知道供电系统的底层实现是什么,究竟通过何种⽅式获得了动⼒)。⽅法重载(overload)实现的是编译时的多态性(也称为前绑定),⽽⽅法重写(override)实现的是运⾏时的多态性(也称为后绑定)。运⾏时的多态是⾯向对象最精髓的东西,要实现多态需要做两件事:1. ⽅法重写(⼦类继承⽗类并重写⽗类中已有的或抽象的⽅法);2. 对象造型(⽤⽗类型引⽤引⽤⼦类型对象,这样同样的引⽤调⽤同样的⽅法就会根据⼦类对象的不同⽽表现出不同的⾏为)。
2、String 是最基本的数据类型吗?
答:不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type)和枚举类型(enumeration type),剩下的都是引⽤类型(reference type)。
3、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗? 答:对于short s1 = 1; s1 = s1 + 1;由于1 是int类型,因此
s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型。⽽short s1 = 1; s1+= 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。
4、int 和Integer 有什么区别?
答:Java 是⼀个近乎纯洁的⾯向对象编程语⾔,但是为了编程的⽅便还是引⼊不是对象的基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每⼀个基本数据类型都引⼊了对应的包装类型(wrapper class),int 的包装类就是Integer,从JDK 1.5 开始引⼊了⾃动装箱/拆箱机制,使得⼆者可以相互转换。
Java 为每个原始类型提供了包装类型:
原始类型: boolean,char,byte,short,int,long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
补充:最近还遇到⼀个⾯试题,也是和⾃动装箱和拆箱相关的,代码如下所⽰:如果不明就⾥很容易
认为两个输出要么都是true要么都是 fal。⾸先需要注意的是f1、 f2、f3、f4四个变量都是 Integer 对象,所以下⾯的==运算⽐较的不是值⽽是引⽤。装箱的本质是什么呢?当我们给⼀个 Integer 对象赋⼀个int值的时候,会调⽤Integer 类的静态⽅法valueOf,如果看看valueOf 的源代码就知道发⽣了什么。
温州瘦肉丸简单的说,如果字⾯量的值在-128 到 127 之间,那么不会 new 新的Integer对象,⽽是直接引⽤常量池中的Integer对象,所以上⾯的⾯试题中f1==f2的结果是true,⽽ f3==f4的结果是 fal。越是貌似简单的⾯试题其中的⽞机就越多,需要⾯试者有相当深厚的功⼒。
5、解释内存中的栈(stack)、堆(heap)和静态存储区的⽤法。
答:通常我们定义⼀个基本数据类型的变量,⼀个对象的引⽤,还有就是函数调⽤的现场保存都使⽤内存中的栈空间;⽽通过new 关键字和构造器创建的对象放在堆空间;程序中的字⾯量(literal)如直接书写的100、“hello”和常量都是放在静态存储区中。栈空间操作最快但是也很⼩,通常⼤量的对象都是放在堆空间,整个内存包括硬盘上的虚拟内存都可以被当成堆空间来使⽤。String str = new String(“hello”);
上⾯的语句中str 放在栈上,⽤new创建出来的字符串对象放在堆上,⽽“hello”这个字⾯量放在静态存储区。
补充:较新版本的Java中使⽤了⼀项叫“逃逸分析“的技术,可以将⼀些局部对象放在栈上以提升对象的操作性能。
6、swtich 是否能作⽤在byte 上,是否能作⽤在long 上,是否能作⽤在String上?
答:早期的 JDK中,switch(expr)中,expr可以是byte、short、char、int。从1.5版开始,Java中引⼊了枚举类型(enum),expr也可以是枚举,从JDK 1.7版开始,还可以是字符串(String)。长整型(long)是不可以的。
7、数组有没有length()⽅法?String 有没有length()⽅法?
答:数组没有 length()⽅法,有length 的属性。String 有length()⽅法。JavaScript中,获得字符串的长度是通过length属性得到的,这⼀点容易和Java混淆。
8、构造器(constructor)是否可被重写(override)?
答:构造器不能被继承,因此不能被重写,但可以被重载。
9、是否可以继承String 类?
答:String 类是final类,不可以被继承。补充:继承String本⾝就是⼀个错误的⾏为,对String类型最好的重⽤⽅式是关联(HAS-A)⽽不是继承(IS-A)。
10、String 和StringBuilder、StringBuffer 的区别?
答:Java 平台提供了两种类型的字符串:String 和StringBuffer / StringBuilder,它们可以储存和操作字符串。其中String是只读字符串,也就意味着String引⽤的字符串内容是不能被改变的。⽽ StringBuffer 和StringBuilder 类表⽰的字符串对象可以直接进⾏修改。StringBuilder是JDK 1.5中引⼊的,它和StringBuffer的⽅法完全相同,区别在于它是在单线程环境下使⽤的,因为它的所有⽅⾯都没有被synchronized修饰,因此它的效率也⽐StringBuffer略⾼。
补充1:有⼀个⾯试题问:有没有哪种情况⽤+做字符串连接⽐调⽤StringBuffer / StringBuilder 对象的 append ⽅法性能更好?如果连接后得到的字符串在静态存储区中是早已存在的,那么⽤+做字符串连接是优于StringBuffer / StringBuilder的append⽅法的。
补充2:下⾯也是⼀个⾯试题,问程序的输出,看看⾃⼰能不能说出正确
答案。
11、描述⼀下JVM 加载class⽂件的原理机制?
答:JVM 中类的装载是由类加载器(ClassLoader)和它的⼦类来实现的,Java中的类加载器是⼀个重要的 Java 运⾏时系统组件,它负责在运⾏时查找和装⼊类⽂件中的类。
补充:
1.由于 Java的跨平台性,经过编译的 Java源程序并不是⼀个可执⾏程序,⽽是⼀个或多个类⽂件。当Java程序需要使⽤某个类时,JVM会确保这个类已经被加载、连接(验证、准备和解析)和初始化。类的加载是指把类
的.class ⽂件中的数据读⼊到内存中,通常是创建⼀个字节数组读⼊.class
⽂件,然后产⽣与所加载类对应的Class对象。加载完成后,Class对象还不
完整,所以此时的类还不可⽤。当类被加载后就进⼊连接阶段,这⼀阶段包括验证、准备(为静态变量分配内存并设置默认的初始值)和解析(将符号引⽤替换为直接引⽤)三个步骤。最后JVM 对类进⾏初始化,包括:1 如果类存在直接
的⽗类并且这个类还没有被初始化,那么就先初始化⽗类;2如果类中存在初
始化语句,就依次执⾏这些初始化语句。
2.类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和⽤户⾃定义类加载器(/doc/5f51345cb34e852458fb770bf78a6529657d355a.html
ng.ClassLoader 的⼦类)。从 JDK 1.2 开始,类加载过程采取了⽗亲委托机制(PDM)。PDM更好的保证了Java 平台的安全性,在该机制中,JVM⾃带的 Bootstrap 是根加载器,其他的加载器都有且仅有⼀个⽗类加载器。类的加载⾸先请求⽗类加载器加载,⽗类加载器⽆能为⼒时才由其⼦
类加载器⾃⾏加载。 JVM不会向Java程序提供对 Bootstrap的引⽤。下⾯是关于⼏个类加载器的说明:
a)Bootstrap:⼀般⽤本地代码实现,负责加载JVM基础核⼼类库(rt.jar);
b)Extension:从 dirs系统属性所指定的⽬录中加载类库,它的⽗加载器是Bootstrap;
c)System:⼜叫应⽤类加载器,其⽗类是 Extension。它是应⽤最⼴泛的类加载器。它从环境变量classpath 或者系统属性java.class.path 所指定的⽬录中记载类,是⽤户⾃定义加载器的默认⽗加载器。
12、抽象类(abstract class)和接⼝(interface)有什么异同?
答:抽象类和接⼝都不能够实例化,但可以定义抽象类和接⼝类型的引⽤。⼀个类如果继承了某个抽象类或者实现了某个接⼝都需要对其中的抽象⽅法全部进⾏实现,否则该类仍然需要被声明为抽象类。接⼝⽐抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象⽅法和具体⽅法,⽽接⼝中不能定义构造器⽽且其中的⽅法全部都是抽象⽅法。抽象类中的成员可以是private、默认、protected、public 的,⽽接⼝中的成员全都是public 的。抽象类中可以定义成员变量,⽽接⼝中定义的成员变量实际上都是常量。有抽象⽅法的类必须被声明为抽象类,⽽抽象类未必要有抽象⽅法。
13、Java 中会存在内存泄漏吗,请简单描述。
答:理论上Java因为有垃圾回收机制(GC)不会存在内存泄露问题(这也是Java被⼴泛使⽤于服务器端编程的⼀个重要原因);然⽽在实际开发中,可能会存在⽆⽤但可达的对象,这些对象不能被GC回收也会发⽣内存泄露。⼀个例⼦就是Hibernate 的Session(⼀级缓存)中的对象属于持久态,垃圾回收器是不会回收这些对象的,然⽽这些对象中可能存在⽆⽤的垃圾对象。下⾯的例⼦也展⽰了Java中发⽣内存泄露的情况:上⾯的代码实现了⼀个栈(先进后出(FILO))结构,乍看之下似乎没有什么明显的问题,它甚⾄可以通过你编写的各种单元测试。然⽽其中的pop⽅法却存在内存泄露的问题,当我们⽤pop ⽅法弹出栈中的对象时,该对象不会被当作垃圾回收,即使使⽤栈的程序不再引⽤这些对象,因为栈内部维护着对这些对象的过期引⽤(obsoletereference)。在⽀持垃圾回收的语⾔中,内存泄露是很隐蔽的,这种内存泄露其实就是⽆意识的对象保持。如果⼀个对象引⽤被⽆意识的
保留起来了,那么垃圾回收器不会处理这个对象,也不会处理该对象引⽤的其他对象,即使这样的对象只有少数⼏个,也可能会导致很多的对象被排除在垃圾回收之外,从⽽对性能造成重⼤影响,极端情况下会引发 Disk Paging(物理内存与硬盘的虚拟内存交换数据),甚⾄造成 OutOfMemoryError。
14、静态变量和实例变量的区别?
答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何⼀个对象,⼀个类不管创建多少个对象,静态变量在内存中有且仅有⼀个拷贝;实例变量必须依存于某⼀实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。在Java开发中,上下⽂类和⼯具类中通常会有⼤量的静态成员。
15、如何实现对象克隆?
答:有两种⽅式:
1.实现Cloneable接⼝并重写Object类中的clone()⽅法;
2.实现 Serializable接⼝,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆,代码如下。
小熊不刷牙的故事
注意:基于序列化和反序列化实现的克隆不仅仅是深度克隆,更重要的是通过泛型限定,可以检查出要克隆的对象是否⽀持序列化,这项检查是编译器完成的,不是在运⾏时抛出异常,这种是⽅案明显优于使⽤Object 类的 clone ⽅法克隆对象。
小飞虹16、String s=new String(“xyz”);创建了⼏个字符串对象?
答:两个对象,⼀个是静态存储区的"xyz",⼀个是⽤new创建在堆上的对象。
17、⼀个“.java”源⽂件中是否可以包含多个类(不是内部类)?有什么限制?
答:可以,但⼀个源⽂件中最多只能有⼀个公开类(public class)⽽且⽂件名必须和公开类的类名完全保持⼀致。
18、内部类可以引⽤它的包含类(外部类)的成员吗?有没有什么限制?
答:⼀个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。
19、指出下⾯程序的运⾏结果:
答:执⾏结果:1a2b2b。创建对象时构造器的调⽤顺序是:先初始化静态成员,然后调⽤⽗类构造器,再初始化⾮静态成员,最后调⽤⾃⾝构造器。
20、如何实现字符串的反转及替换?
答:⽅法很多,可以⾃⼰写实现也可以使⽤String或StringBuffer / StringBuilder 中的⽅法。有⼀道很常见的⾯试题是⽤递归实现字符串反转。
21、⽇期和时间:
1)如何取得年⽉⽇、⼩时分钟秒?
2)如何取得从1970年1⽉1⽇0时0分0秒到现在的毫秒数?
3)如何取得某⽉的最后⼀天?
4)如何格式化⽇期?
答:操作⽅法如下所⽰:
1)创建 java.util.Calendar 实例,调⽤其get()⽅法传⼊不同的参数即可获得参数所对应的值
2)以下⽅法均可获得该毫秒数:
3)⽰例代码如下:
4)利⽤DataFormat 的⼦类(如SimpleDateFormat 类)中的format(Date)⽅法可将⽇期格式化。
22、⽐较⼀下Java 和JavaSciprt。
答:JavaScript 与 Java 是两个公司开发的不同的两个产品。Java 是原 Sun
公司推出的⾯向对象的程序设计语⾔,特别适合于互联⽹应⽤程序开发;⽽JavaScript是 Netscape 公司的产品,为了扩展Netscape 浏览器的功能⽽开发的⼀种可以嵌⼊Web页⾯中运⾏的基于对象和事件驱动的解释性语⾔,它的前⾝是LiveScript;⽽Java 的前⾝是Oak 语⾔。
下⾯对两种语⾔间的异同作如下⽐较:
1)基于对象和⾯向对象:Java是⼀种真正的⾯向对象的语⾔,即使是开发简单的程序,必须设计对象;JavaScript是种脚本语⾔,它可以⽤来制作与⽹络⽆关的,与⽤户交互作⽤的复杂软件。它是⼀种基于对象(Object-Bad)和事件驱动(Event-Driven)的编程语⾔。因⽽它本⾝提供了⾮常丰富的内部对象供设计⼈员使⽤;
2)解释和编译:Java 的源代码在执⾏之前,必须经过编译;JavaScript 是⼀种解释性编程语⾔,其源代码不需经过编译,由浏览器解释执⾏;
边界意识
国内热点新闻
3)强类型变量和类型弱变量:Java采⽤强类型变量检查,即所有变量在编译之前必须作声明;JavaScript中变量声明,采⽤其弱类型。即变量在使⽤前不需作声明,⽽是解释器在运⾏时检查其数据类型;
4)代码格式不⼀样。
补充:上⾯列出的四点是原来所谓的标准答案中给出的。其实Java和JavaScript 最重要的区别是⼀个是静态语⾔,⼀个是动态语⾔。⽬前的编程语⾔的发展趋势是函数式语⾔和动态语⾔。在Java 中类(class)是⼀等公民,⽽JavaScript 中函数(function)是⼀等公民。对于这种问题,在⾯试时还是⽤⾃⼰的语⾔回答会更加靠谱。
23、Error 和Exception 有什么区别?
答:Error 表⽰系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的⼀种严重问题;⽐如内存溢出,不可能指望程序能处理这样的情况;Exception 表⽰需要捕捉或者需要程序进⾏处理的异常,是⼀种设计或实现问题;也就是说,它表⽰如果程序运⾏正常,从不会发⽣的情况。
补充:2005年摩托罗拉的⾯试中曾经问过这么⼀个问题“If a process reports a stack overflow run-time error, what’s the most possible cau?”,给了四个选项a. lack of memory; b. write on an invalid mem
ory space; c. recursive function calling; d. array index out of boundary. Java 程序在运⾏时也可能会遭遇StackOverflowError,这是⼀个错误⽆法恢复,只能重新修改代码了,这个⾯试题的答案是c。如果写了不能迅速收敛的递归,则很有可能引发栈溢出的错误,如下所⽰:
武则天语录因此,⽤递归编写程序时⼀定要牢记两点:1. 递归公式;2. 收敛条件(什么时候就不再递归⽽是回溯了)。
24、Java 语⾔如何进⾏异常处理,关键字:throws、throw、try、catch、finally分别如何使⽤?
答:Java 通过⾯向对象的⽅法进⾏异常处理,把各种不同的异常进⾏分类,并提供了良好的接⼝。在Java 中,每个异常都是⼀个对象,它是Throwable 类或其⼦类的实例。当⼀个⽅法出现异常后便抛出⼀个异常对象,该对象中包含有异常信息,调⽤这个对象的⽅法可以捕获到这个异常并进⾏处理。Java 的异常处理是通过5 个关键词来实现的:try、catch、throw、throws 和
finally。⼀般情况下是⽤try 来执⾏⼀段程序,如果出现异常,系统会抛出(throw)⼀个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;try ⽤来指定⼀块预防所有“异常”的程序;catch ⼦句紧跟在try块后⾯,⽤来指定你想要捕捉的“异常”的类型;throw 语句⽤来明确地抛出⼀个“异常”;throws⽤来标明⼀个成员函数可能抛出的各种“异常”;finally 为确保⼀段代码不管发⽣什么“异常”都被执⾏⼀段代码;可以在⼀个成员函数调⽤的外⾯写⼀个try 语句,在这个
成员函数内部写另⼀个try 语句保护其他代码。每当遇到⼀个try 语句,“异常”的框架就放到栈上⾯,直到所有的try 语句都
完成。如果下⼀级的 try 语句没有对某种“异常”进⾏处理,栈就会展开,直到遇到有处理这种“异常”的
try 语句。xx网址
25、final, finally, finalize 的区别?
答:final:修饰符(关键字)有三种⽤法:如果⼀个类被声明为 final,意味着它不能再派⽣出新的⼦类,即不能被继承,因此它和abstract 是反义词。将变量声明为final,可以保证它们在使⽤中不被改变,被声明为final 的变量必须在声明时给定初值,⽽在以后的引⽤中只能读取不可修改。被声明为final 的⽅法也同样只能使⽤,不能在⼦类中被重写。finally:通常放在try…catch的后⾯构造总是执⾏代码块,这就意味着程序⽆论正常执⾏还是发⽣异常,这⾥的代码只要JVM不关闭都能执⾏,可以将释放外部资源的代码写在 finally块中。finalize:Object类中定义的⽅法, Java中允许使⽤finalize() ⽅法在垃圾收集器将对象从内存中清除出去之前做必要的清理⼯作。这个⽅法是由垃圾收集器在销毁对象时调⽤的,通过重写 finalize() ⽅法可以整理系统资源或者执⾏其他清理⼯作。
VM 内存可简单分为三个区:
1、堆区(heap):⽤于存放所有对象,是线程共享的(注:数组也属于对象)
2、栈区(stack):⽤于存放基本数据类型的数据和对象的引⽤,是线程私有的(分为:虚拟机栈和本地⽅法栈)
3、⽅法区(method):⽤于存放类信息、常量、静态变量、编译后的字节码等,是线程共享的(也被称为⾮堆,即 None-Heap)Java 的垃圾回收器(GC)主要针对堆区。
26、如何停⽌⼀个正在运⾏的线程
1、使⽤退出标志,使线程正常退出,也就是当run⽅法完成后线程终⽌。
2、使⽤stop⽅法强⾏终⽌,但是不推荐这个⽅法,因为stop和suspend及resume⼀样都是过期作废的⽅法。
3、使⽤interrupt⽅法中断线程。
27、notify()和notifyAll()有什么区别?
notify可能会导致死锁,⽽notifyAll则不会任何时候只有⼀个线程可以获得锁,也就是说只有⼀个线程
可以运⾏synchronized 中的代码使⽤notifyall,可以唤醒所有处于wait状态的线程,使其重新进⼊锁的争夺队列中,⽽notify只能唤醒⼀个。
wait() 应配合while循环使⽤,不应使⽤if,务必在wait()调⽤前后都
检查条件,如果不满⾜,必须调⽤ notify()唤醒另外的线程来处理,⾃⼰继续wait()直⾄条件满⾜再往下执⾏。
28、sleep()和wait() 有什么区别?
对于sleep()⽅法,我们⾸先要知道该⽅法是属于Thread类中的。⽽
wait()⽅法,则是属于Object类中的。
sleep()⽅法导致了程序暂停执⾏指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了⼜会⾃动恢复运⾏状态。在调⽤sleep()⽅法的过程中,线程不会释放对象锁。当调⽤wait()⽅法的时候,线程会放弃对象锁,进⼊等待此对象的等待锁定池,只有针对此对象调⽤
notify()⽅法后本线程才进⼊对象锁定池准备,获取对象锁进⼊运⾏状态。
29、Thread 类中的start() 和 run() ⽅法有什么区别?
start()⽅法被⽤来启动新创建的线程,⽽且start()内部调⽤了run()⽅法,这和直接调⽤run()⽅法的效果不⼀样。当你调⽤run()⽅法的时候,只会是在原来的线程中调⽤,没有新的线程启动,start()⽅法才会启动新线程。
30、为什么wait和notify⽅法要在同步块中调⽤?
1. 只有在调⽤线程拥有某个对象的独占锁时,才能够调⽤该对象的
wait(),notify()和notifyAll()⽅法。
2. 如果你不这么做,你的代码会抛出IllegalMonitorStateException异常。
检讨书5000
3. 还有⼀个原因是为了避免wait和notify之间产⽣竞态条件。
wait()⽅法强制当前线程释放对象锁。这意味着在调⽤某对象的wait()⽅法之前,当前线程必须已经获得该对象的锁。因此,线

本文发布于:2023-06-24 09:46:25,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1027814.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:对象   变量   实现
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图