2024年9月java jni js(初级java面试,面试官是如何出题的)

 更新时间:2024-09-21 09:18:04

  ⑴javajnijs(初级java面试,面试官是如何出题的

  ⑵本地代码不能显式在删掉一个字段或者方法的ID,.混淆ID和引用本地代码中使用引用来访问JAVA对象,本地代码不应该把存储局部引用存储到全局变量中在其它地方使用,JNI把JVM的许多功能开发给了本地代码:类加载、对象创建、字段访问、方法调用、线程同步等,本地代码可以创建多个引用并让它们指向相同的对象,一个局部引用会导致它本身和它所指向的对象都得不到回收,而且本地代码中的错误检查很麻烦,尽量让所有的本地方法都在同一个包甚至同一个类中。

  ⑶初级java面试,面试官是如何出题的

  ⑷您好,赣州中公教育为您解答:Java技术题:问题一:会前端开发么,都会用哪些开发技术呢?答案:如果熟悉前端的,就说:我对前端这块还是比较熟练的,能够熟悉运用html、css、js、jQuery等前端开发技术;如果不太熟悉的,就答前台js写的比较熟练,html+css的框架写得也不错,只是jQuery特效能力比较差。问题二:Java是什么?(此题%的公司必问)解答:这个结合自己的理解回答,不要将百科上的知识生搬硬套。问题三:jjvmGC的原理是什么?答案:JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完成,通过下面步来完成JVM环境..创建JVM装载环境和配置.装载JVM.dll.初始化JVM.dll并挂界到JNIENV(JNI调用接口)实例.调用JNIEnv实例装载并处理class类。问题四:springiocaop的原理是什么?答案:IOC(反转控制):对成员变量的赋值的控制权从代码中反转到配置文件中。AOP:Aspect(切面)Oriented(面向)Programming(编程),面向切面编程。差不多就够了,再看就是Spring的事务处理,基本就这些。问题五:Java的集合都有哪些?答案:集合主要有Collection和Map接口。Collection接口定义了一个包含一批对象的集合。Map接口在Collection的基础上,为其中的每个对象指定了一个key,并使用Entry保存每个key-value对,以实现通过key快速定位到对象(value)。问题六:java创建对象有几种常用方法?答案:四种,分别是:.用new语句创建对象,这是最常用的创建对象的方式。.运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。.调用对象的clone()方法。.运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法。

  ⑸大牛们看看小弟我的JNI为什么出错

  ⑹本章总结了JNI实际应用中容易出错的一些情况供JNI程序员参考。.错误检查编写本地方法时最常见的错误就是忘记检查是否发生了异常。我承认,JNI里面的异常检查确实比较麻烦,但是,这很重要。.向JNI函数传递非法参数JNI不会检查参数是否正确,如果你自己不保证参数的正确有效,那么出现什么样的错误是未知的。通常,不检查参数的有效性在C/C++库中是比较常见的。.把jclass和jobject弄混一开始使用JNI时,很容易把对象引用(jobject类型的值和类引用(jclass类型的值弄混。对象引用对应的是数组或者java.lang.Object及其子类的对象实例,而类引用对应的是java.lang.Class的实例。像GetFieldID这样需要传入jclass作为参数的方法做的是一个类操作,因为它是从一个类中获取字段的描述。而GetIntField这样需要传入jobject作为参数的方法做的是一个对象操作,因为它从一个对象实例中获取字段的值。.jboolean会面临数据截取的问题Jboolean是一个-bitunsigned的C类型,可以存储~的值。其中,对应常量JNI_FALSE,而~对应常量JNI_TRUE。但是,或者位的值,如果最低的位是的话,就会引起问题。假设你定义了一个函数print,需要传入一个jboolean类型的condition作为参数:voidprint(jbooleancondition){/*ompilersgeneratecodethattruncatesconditiontoitslowerbits.*/if(condition){printf("true

  ⑺");}else{printf("false

  ⑻");}}对上面这段代码来说,下面这样用就会出现问题:intn=;/*thevaluex,whoselowerbitsareall*/print(n);我们传入了一个非的值(X,因为这个值的低位(即,被截出来使用,上面的代码会打印“false”。根据经验,这里有一个常用的解决方案:n=;print(n?JNI_TRUE:JNI_FALSE);.编程的时候,什么用JAVA,什么时候用C?这里有一些经验性的注意事项:、尽量让JAVA和C之间的接口简单化,C和JAVA间的调用过于复杂的话,会使得BUG调试、代码维护和JVM对代码进行优化都会变得很难。比如虚拟机很容易对一些JAVA方法进行内联,但对本地方法却无能为力。、尽量少写本地代码。因为本地代码即不安全又是不可移植的,而且本地代码中的错误检查很麻烦。、让本地代码尽量独立。也就是说,实际使用的时候,尽量让所有的本地方法都在同一个包甚至同一个类中。JNI把JVM的许多功能开发给了本地代码:类加载、对象创建、字段访问、方法调用、线程同步等。虽然用JAVA来做这些事情的时候很容易,但有时候,用本地代码来做很诱人。下面的代码会告诉你,为什么用本地代码进行JAVA编程是愚蠢的。假设我们需要创建一个线程并启动它,JAVA代码这样写:newJobThread().start();而用本地代码却需要这样:/*Assumethesevariablesarepreputedandcached:*Class_JobThread:theclass"JobThread"*MID_Thread_init:methodIDofconstructor*MID_Thread_start:methodIDofThread.start()*/aThreadObject=(*env)-》NewObject(env,Class_JobThread,MID_Thread_init);if(aThreadObject==NULL){.../*outofmemory*/}(*env)-》CallVoidMethod(env,aThreadObject,MID_Thread_start);if((*env)-》ExceptionOurred(env)){.../*threaddidnotstart*/}比较起来,本地代码写会使用编程变得复杂,代码量大,错误处理多。通常,如果不得不用本地代码来做这些事的话,在JAVA中提供一个辅助函数,并在本地代码中对这个辅助函数进行回调。.混淆ID和引用本地代码中使用引用来访问JAVA对象,使用ID来访问方法和字段。引用指向的是可以由本地代码来管理的JVM中的资源。比如DeleteLocalRef这个本地函数,允许本地代码删除一个局部引用。而字段和方法的ID由JVM来管理,只有它所属的类被unload时,才会失效。本地代码不能显式在删掉一个字段或者方法的ID。本地代码可以创建多个引用并让它们指向相同的对象。比如,一个全局引用和一个局部引用可能指向相同的对象。而字段ID和方法ID是唯一的。比如类A定义了一个方法f,而类B从类A中继承了方法f,那么下面的调用结果是相同的:jmethodIDMID_A_f=(*env)-》GetMethodID(env,A,"f","()V");jmethodIDMID_B_f=(*env)-》GetMethodID(env,B,"f","()V");.缓存字段ID和方法ID这里有一个缓存ID的例子:classC{privateinti;nativevoidf();}下面是本地方法的实现,没有使用缓存ID。//NofieldIDscached.JNIEXPORTvoidJNICALLJava_C_f(JNIEnv*env,jobjectthis){jclasscls=(*env)-》GetObjectClass(env,this);.../*errorchecking*/jfieldIDfid=(*env)-》GetFieldID(env,cls,"i","I");.../*errorchecking*/ival=(*env)-》GetIntField(env,this,fid);.../*ivalnowhasthevalueofthis.i*/}上面的这些代码一般可以运行正确,但是下面的情况下,就出错了://TroubleintheabsenceofIDcachingclassDextendsC{privateinti;D(){f();//inheritedfromC}}类D继承了类C,并且也有一个私有的字段i。当在D的构造方法中调用f时,本地方法接收到的参数中,cls指向提类D的对象,fid指向的是D.i这个字段。在这个本地方法的末尾,ival里面是D.i的值,而不是C.i的值。这与你想象的是不一样的。上面这种问题的解决方案是://VersionthatcachesIDsinstaticinitializersclassC{privateinti;nativevoidf();privatestatiativevoidinitIDs();static{initIDs();//Callaninitializingnativemethod}}本地方法这样实现:staticjfieldIDFID_C_i;JNIEXPORTvoidJNICALLJava_C_initIDs(JNIEnv*env,jclasscls){/*GetIDstoallfields/methodsofCthatnativemethodswillneed.*/FID_C_i=(*env)-》GetFieldID(env,cls,"i","I");}JNIEXPORTvoidJNICALLJava_C_f(JNIEnv*env,jobjectthis){ival=(*env)-》GetIntField(env,this,FID_C_i);.../*ivalisalwaysC.i,notD.i*/}字段ID在类C的静态初始时被计算并缓存下来,这样就可以确保缓存的是C.i的ID,因此,不管本地方法中接收到的jobject是哪个类的实例,访问的永远是C.i的值。另外,同样的情况也可能会出现在方法ID上面。.Unicode字符串结尾从GetStringChars和GetStringCritical两个方法获得的Unicode字符串不是以NULL结尾的,需要调用GetStringLength来获取字符串的长度。一些操作系统,如WindowsNT中,Unicode字符串必须以两个’’结尾,这样的话,就不能直接把GetStringChars得到的字符串传递给WindowsNT系统的API,而必须复制一份并在字符串的结尾加入两个“”.访问权限失效在本地代码中,访问方法和变量时不受JAVA语言规定的限制。比如,可以修改private和final修饰的字段。并且,JNI中可以访问和修改heap中任意位置的内存。这些都会造成意想不到的结果。比如,本地代码中不应该修改java.lang.String和java.lang.Integer这样的不可变对象的内容。否则,会破坏JAVA规范。.忽视国际化JVM中的字符串是Unicode字符序列,而本地字符串采用的是本地化的编码。实际编码的时候,我们经常需要使用像JNU_NewStringNative和JNU_GetStringNativeChars这样的工具函数来把Unicode编码的jstring转化成本地字符串,要对消息和文件名尤其关注,它们经常是需要国际化的,可能包含各种字符。如果一个本地方法得到了一个文件名,必须把它转化成本地字符串之后才能传递给C库函数使用:JNIEXPORTjintJNICALLJava_MyFile_open(JNIEnv*env,jobjectself,jstringname,jintmode){jintresult;char*ame=JNU_GetStringNativeChars(env,name);if(ame==NULL){return;}result=open(ame,mode);free(ame);returnresult;}上例中,我们使用JNU_GetStringNativeChars把Unicode字符串转化成本地字符串。.确保释放VM资源JNI编程时常见的错误之一就是忘记释放VM资源,尤其是在执行路径分支时,比如,有异常发生的时候:JNIEXPORTvoidJNICALLJava_pkg_Cls_f(JNIEnv*env,jclasscls,jstringjstr){constjchar*cstr=(*env)-》GetStringChars(env,jstr,NULL);if(cstr==NULL){return;}...if(...){/*exceptionourred*//*missesaReleaseStringCharscall*/return;}.../*normalreturn*/(*env)-》ReleaseStringChars(env,jstr,cstr);}忘记调用ReleaseStringChars可能导致jstring永远被VM给pin着不被回收。一个GetStringChars必然要对应着一个ReleaseStringChars,下面的代码就没有正确地释放VM资源:/*TheisCopyargumentismisusedhere!*/JNIEXPORTvoidJNICALLJava_pkg_Cls_f(JNIEnv*env,jclasscls,jstringjstr){jbooleanisCopy;constjchar*cstr=(*env)-》GetStringChars(env,jstr,&isCopy);if(cstr==NULL){return;}.../*usecstr*//*Thisiswrong.AlwaysneedtocallReleaseStringChars.*/if(isCopy){(*env)-》ReleaseStringChars(env,jstr,cstr);}}即使在isCopy的值是JNI_FALSE时,也应该调用ReleaseStringChars在unpin掉jstring。.过多的创建局部引用大量的局部引用创建会浪费不必要的内存。一个局部引用会导致它本身和它所指向的对象都得不到回收。尤其要注意那些长时间运行的方法、创建局部引用的循环和工具函数,充分得利用Pus/PopLocalFrame来高效地管理局部引用。.使用已经失效的局部引用局部引用只在一个本地方法的调用期间有效,方法执行完成后会被自动释放。本地代码不应该把存储局部引用存储到全局变量中在其它地方使用。.跨进程使用JNIEnvJNIEnv这个指针只能在当前线程中使用,不要在其它线程中使用。.错误的线程模型(ThreadModels

  ⑼JNIc语言里的char数组怎么转成java的char数组

  ⑽在c语言里(默认JNI传参)jstringjstr;charwords="中文

  ⑾";jstr=(*env)-》NewStringUTF(env,words);returnjstrjava的方法返回类型是String这样就能在c语言的方法里一个字符串然后传回给java、JNI是JavaNativeInterface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++。从Java.开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java虚拟机环境下。

您可能感兴趣的文章:

相关文章