热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

嵌入式C编程经典面试题

上个星期,去深圳一家搞ARM开发的公司面试,HR叫我做了一份卷子,里面都是C编程,心中暗喜,因为这些题基本
上个星期,去深圳一家搞
ARM
开发的公司面试,HR叫我做了一份卷子,里面都是C编程,心中暗喜,因为这些题基本上都在程序员面试宝典里见过。后来回到学校,在网上搜索,原来这些题都是
嵌入式
工程师的经典面试题目,很多网站上都可以找得到。现把他贴出来,附上网上的答案,跟大家分享,因为这些题实在太经典了。




预处理器(Preprocessor)




1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)


      #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL


我在这想看到几件事情:


1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)


2) 懂得预处理器将为你计算常数表达式的值,因此直接写出你如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。


3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。


4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。




2 . 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。


      #define MIN(A,B) &#xff08;&#xff08;A&#xff09; <&#61; (B) ? (A) : (B))


这个测试是为下面的目的而设的&#xff1a;


1) 标识#define在宏中应用的基本知识。这是很重要的。因为在  嵌入(inline)操作符 变为标准C的一部分之前&#xff0c;宏是方便产生嵌入代码的唯一方法&#xff0c;对于嵌入式系统来说&#xff0c;为了能达到要求的性能&#xff0c;嵌入代码经常是必须的方法。


2) 三重条件操作符的知识。这个操作符存在
C语言
中的原因是它使得编译器能产生比if-then-else更优的代码&#xff0c;了解这个用法是很重要的。


3) 懂得在宏中小心地把参数用括号括起来


4) 我也用这个问题开始讨论宏的副作用&#xff0c;例如&#xff1a;当你写下面的代码时会发生什么事&#xff1f;


      least &#61; MIN(*p&#43;&#43;, b);




3. 预处理器标识#error的目的是什么&#xff1f;


      如果你不知道答案&#xff0c;请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子&#xff0c;那么应试者最好希望自己不要知道答案。




死循环&#xff08;Infinite loops&#xff09;




4. 嵌入式系统中经常要用到无限循环&#xff0c;你怎么样用C编写死循环呢&#xff1f;


这个问题用几个解决方案。我首选的方案是&#xff1a;




while(1)


{




}




一些程序员更喜欢如下方案&#xff1a;




for(;;)


{




}




      这个实现方式让我为难&#xff0c;因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案&#xff0c;我将用这个作为一个机会去探究他们这样做的基本原理。如果他们的基本答案是&#xff1a;"我被教着这样做&#xff0c;但从没有想到过为什么。"这会给我留下一个坏印象。




第三个方案是用 goto


Loop:


...


goto Loop;


应试者如给出上面的方案&#xff0c;这说明或者他是一个汇编语言程序员&#xff08;这也许是好事&#xff09;或者他是一个想进入新领域的BASIC/FORTRAN程序员。




数据声明&#xff08;Data declarations&#xff09;




5. 用变量a给出下面的定义


a) 一个整型数&#xff08;An integer&#xff09;


b)一个指向整型数的指针&#xff08; A pointer to an integer&#xff09;


c)一个指向指针的的指针&#xff0c;它指向的指针是指向一个整型数&#xff08; A pointer to a pointer to an intege&#xff09;r


d)一个有10个整型数的数组&#xff08; An array of 10 integers&#xff09;


e) 一个有10个指针的数组&#xff0c;该指针是指向一个整型数的。&#xff08;An array of 10 pointers to integers&#xff09;


f) 一个指向有10个整型数数组的指针&#xff08; A pointer to an array of 10 integers&#xff09;


g) 一个指向函数的指针&#xff0c;该函数有一个整型参数并返回一个整型数&#xff08;A pointer to a function that takes an integer as an argument and returns an integer&#xff09;


h) 一个有10个指针的数组&#xff0c;该指针指向一个函数&#xff0c;该函数有一个整型参数并返回一个整型数&#xff08; An array of ten pointers to functions that take an integer argument and return an integer &#xff09;




答案是&#xff1a;


a) int a; // An integer


b) int *a; // A pointer to an integer


c) int **a; // A pointer to a pointer to an integer


d) int a[10]; // An array of 10 integers


e) int *a[10]; // An array of 10 pointers to integers


f) int (*a)[10]; // A pointer to an array of 10 integers


g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer


h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer




      人们经常声称这里有几个问题是那种要翻一下书才能回答的问题&#xff0c;我同意这种说法。当我写这篇文章时&#xff0c;为了确定语法的正确性&#xff0c;我的确查了一下书。但是当我被面试的时候&#xff0c;我期望被问到这个问题&#xff08;或者相近的问题&#xff09;。因为在被面试的这段时间里&#xff0c;我确定我知道这个问题的答案。应试者如果不知道所有的答案&#xff08;或至少大部分答案&#xff09;&#xff0c;那么也就没有为这次面试做准备&#xff0c;如果该面试者没有为这次面试做准备&#xff0c;那么他又能为什么出准备呢&#xff1f;




Static


本帖隐藏的内容

6. 关键字static的作用是什么&#xff1f;
      这个简单的问题很少有人能回答完全。在C语言中&#xff0c;关键字static有三个明显的作用&#xff1a;
1) 在函数体&#xff0c;一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2) 在模块内&#xff08;但在函数体外&#xff09;&#xff0c;一个被声明为静态的变量可以被模块内所用函数访问&#xff0c;但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内&#xff0c;一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是&#xff0c;这个函数被限制在声明它的模块的本地范围内使用。

      大多数应试者能正确回答第一部分&#xff0c;一部分能正确回答第二部分&#xff0c;同是很少的人能懂得第三部分。这是一个应试者的严重的缺点&#xff0c;因为他显然不懂得本地化数据和代码范围的好处和重要性。

Const

7&#xff0e;关键字const有什么含意&#xff1f;
      我只要一听到被面试者说&#xff1a;"const意味着常数"&#xff0c;我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法&#xff0c;因此ESP(译者&#xff1a;Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章&#xff0c;只要能说出const意味着"只读"就可以了。尽管这个答案不是完全的答案&#xff0c;但我接受它作为一个正确的答案。&#xff08;如果你想知道更详细的答案&#xff0c;仔细读一下Saks的文章吧。&#xff09;
      如果应试者能正确回答这个问题&#xff0c;我将问他一个附加的问题&#xff1a;
      下面的声明都是什么意思&#xff1f;

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

/******/
      前两个的作用是一样&#xff0c;a是一个常整型数。第三个意味着a是一个指向常整型数的指针&#xff08;也就是&#xff0c;整型数是不可修改的&#xff0c;但指针可以&#xff09;。第四个意思a是一个指向整型数的常指针&#xff08;也就是说&#xff0c;指针指向的整型数是可以修改的&#xff0c;但指针是不可修改的&#xff09;。最后一个意味着a是一个指向常整型数的常指针&#xff08;也就是说&#xff0c;指针指向的整型数是不可修改的&#xff0c;同时指针也是不可修改的&#xff09;。如果应试者能正确回答这些问题&#xff0c;那么他就给我留下了一个好印象。顺带提一句&#xff0c;也许你可能会问&#xff0c;即使不用关键字 const&#xff0c;也还是能很容易写出功能正确的程序&#xff0c;那么我为什么还要如此看重关键字const呢&#xff1f;我也如下的几下理由&#xff1a;
1) 关键字const的作用是为给读你代码的人传达非常有用的信息&#xff0c;实际上&#xff0c;声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾&#xff0c;你就会很快学会感谢这点多余的信息。&#xff08;当然&#xff0c;懂得用const的程序员很少会留下的垃圾让别人来清理的。&#xff09;
2) 通过给优化器一些附加的信息&#xff0c;使用关键字const也许能产生更紧凑的代码。
3) 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数&#xff0c;防止其被无意的代码修改。简而言之&#xff0c;这样可以减少bug的出现。

Volatile

8. 关键字volatile有什么含意?并给出三个不同的例子。
      一个定义为volatile的变量是说这变量可能会被意想不到地改变&#xff0c;这样&#xff0c;编译器就不会去假设这个变量的值了。精确地说就是&#xff0c;优化器在用到这个变量时必须每次都小心地重新读取这个变量的值&#xff0c;而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子&#xff1a;
1) 并行设备的硬件寄存器&#xff08;如&#xff1a;状态寄存器&#xff09;
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量

      回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道&#xff0c;所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。
      假设被面试者正确地回答了这是问题&#xff08;嗯&#xff0c;怀疑是否会是这样&#xff09;&#xff0c;我将稍微深究一下&#xff0c;看一下这家伙是不是直正懂得volatile完全的重要性。
1) 一个参数既可以是const还可以是volatile吗&#xff1f;解释为什么。
2) 一个指针可以是volatile 吗&#xff1f;解释为什么。
3) 下面的函数有什么错误&#xff1a;

int square(volatile int *ptr)
{
        return *ptr * *ptr;
}

下面是答案&#xff1a;
1) 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2) 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方&#xff0c;但是&#xff0c;由于*ptr指向一个volatile型参数&#xff0c;编译器将产生类似下面的代码&#xff1a;

int square(volatile int *ptr)
{
    int a,b;
    a &#61; *ptr;
    b &#61; *ptr;
    return a * b;
}

由于*ptr的值可能被意想不到地该变&#xff0c;因此a和b可能是不同的。结果&#xff0c;这段代码可能返不是你所期望的平方值&#xff01;正确的代码如下&#xff1a;

long square(volatile int *ptr)
{
    int a;
    a &#61; *ptr;
    return a * a;
}

位操作&#xff08;Bit manipulation&#xff09;

9. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a&#xff0c;写两段代码&#xff0c;第一个设置a的bit 3&#xff0c;第二个清除a 的bit 3。在以上两个操作中&#xff0c;要保持其它位不变。
      对这个问题有三种基本的反应
1) 不知道如何下手。该被面者从没做过任何嵌入式系统的工作。
2) 用bit fields。Bit fields是被扔到C语言死角的东西&#xff0c;它保证你的代码在不同编译器之间是不可移植的&#xff0c;同时也保证了的你的代码是不可重用的。我最近不幸看到 Infineon为其较复杂的通信芯片写的驱动程序&#xff0c;它用到了bit fields因此完全对我无用&#xff0c;因为我的编译器用其它的方式来实现bit fields的。从道德讲&#xff1a;永远不要让一个非嵌入式的家伙粘实际硬件的边。
3) 用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法&#xff0c;是应该被用到的方法。最佳的解决方案如下&#xff1a;

#define BIT3 (0x1 <<3)
static int a;

void set_bit3(void)
{
    a |&#61; BIT3;
}
void clear_bit3(void)
{
    a &&#61; ~BIT3;
}

      一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数&#xff0c;这也是可以接受的。我希望看到几个要点&#xff1a;说明常数、|&#61;和&&#61;~操作。

访问固定的内存位置&#xff08;Accessing fixed memory locations&#xff09;

10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中&#xff0c;要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
      这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换&#xff08;typecast&#xff09;为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下&#xff1a;
    int *ptr;
    ptr &#61; (int *)0x67a9;
    *ptr &#61; 0xaa55;

  A more obscure approach is:
一个较晦涩的方法是&#xff1a;

    *(int * const)(0x67a9) &#61; 0xaa55;

即使你的品味更接近第二种方案&#xff0c;但我建议你在面试时使用第一种方案。

中断&#xff08;Interrupts&#xff09;

11. 中断是嵌入式系统中重要的组成部分&#xff0c;这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是&#xff0c;产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR)&#xff0c;请评论一下这段代码的。

__interrupt double compute_area (double radius)
{
    double area &#61; PI * radius * radius;
    printf("\nArea &#61; %f", area);
    return area;
}

这个函数有太多的错误了&#xff0c;以至让人不知从何说起了&#xff1a;
1) ISR 不能返回一个值。如果你不懂这个&#xff0c;那么你不会被雇用的。
2) ISR 不能传递参数。如果你没有看到这一点&#xff0c;你被雇用的机会等同第一项。
3) 在许多的处理器/编译器中&#xff0c;浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈&#xff0c;有些处理器/编译器就是不允许在ISR中做浮点运算。此外&#xff0c;ISR应该是短而有效率的&#xff0c;在ISR中做浮点运算是不明智的。
4) 与第三点一脉相承&#xff0c;printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点&#xff0c;我不会太为难你的。不用说&#xff0c;如果你能得到后两点&#xff0c;那么你的被雇用前景越来越光明了。

代码例子&#xff08;Code examples&#xff09;





12 . 下面的代码输出是什么&#xff0c;为什么&#xff1f;




void foo(void)


{


    unsigned int a &#61; 6;


    int b &#61; -20;


    (a&#43;b > 6) ? puts("> 6") : puts("<&#61; 6");


}


      这个问题测试你是否懂得C语言中的整数自动转换原则&#xff0c;我发现有些开发者懂得极少这些东西。不管如何&#xff0c;这无符号整型问题的答案是输出是 ">6"。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数&#xff0c;所以该表达式计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题&#xff0c;你也就到了得不到这份工作的边缘。




13. 评价下面的代码片断&#xff1a;




unsigned int zero &#61; 0;


unsigned int compzero &#61; 0xFFFF;


/*1&#39;&#39;s complement of zero */




对于一个int型不是16位的处理器为说&#xff0c;上面的代码是不正确的。应编写如下&#xff1a;




unsigned int compzero &#61; ~0;




      这一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的经验里&#xff0c;好的嵌入式程序员非常准确地明白硬件的细节和它的局限&#xff0c;然而PC机程序往往把硬件作为一个无法避免的烦恼。


      到了这个阶段&#xff0c;应试者或者完全垂头丧气了或者信心满满志在必得。如果显然应试者不是很好&#xff0c;那么这个测试就在这里结束了。但如果显然应试者做得不错&#xff0c;那么我就扔出下面的追加问题&#xff0c;这些问题是比较难的&#xff0c;我想仅仅非常优秀的应试者能做得不错。提出这些问题&#xff0c;我希望更多看到应试者应付问题的方法&#xff0c;而不是答案。不管如何&#xff0c;你就当是这个娱乐吧...




动态内存分配&#xff08;Dynamic memory allocation&#xff09;




14. 尽管不像非嵌入式计算机那么常见&#xff0c;嵌入式系统还是有从堆&#xff08;heap&#xff09;中动态分配内存的过程的。那么嵌入式系统中&#xff0c;动态分配内存可能发生的问题是什么&#xff1f;


      这里&#xff0c;我期望应试者能提到内存碎片&#xff0c;碎片收集的问题&#xff0c;变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了&#xff08;主要是 P.J. Plauger, 他的解释远远超过我这里能提到的任何解释&#xff09;&#xff0c;所有回过头看一下这些杂志吧&#xff01;让应试者进入一种虚假的安全感觉后&#xff0c;我拿出这么一个小节目&#xff1a;


      下面的代码片段的输出是什么&#xff0c;为什么&#xff1f;




char *ptr;


if ((ptr &#61; (char *)malloc(0)) &#61;&#61; NULL)


    puts("Got a null pointer");


else


    puts("Got a valid pointer");




      这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc&#xff0c;得到了一个合法的指针之后&#xff0c;我才想到这个问题。这就是上面的代码&#xff0c;该代码的输出是"Got a valid pointer"。我用这个来开始讨论这样的一问题&#xff0c;看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要&#xff0c;但解决问题的方法和你做决定的基本原理更重要些。




Typedef




15 Typedef 在C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。例如&#xff0c;思考一下下面的例子&#xff1a;




#define dPS struct s *


typedef struct s * tPS;




      以上两种情况的意图都是要定义dPS 和 tPS 作为一个指向结构s指针。哪种方法更好呢&#xff1f;&#xff08;如果有的话&#xff09;为什么&#xff1f;


这是一个非常微妙的问题&#xff0c;任何人答对这个问题&#xff08;正当的原因&#xff09;是应当被恭喜的。答案是&#xff1a;typedef更好。思考下面的例子&#xff1a;




dPS p1,p2;


tPS p3,p4;




第一个扩展为




struct s * p1, p2;


.


上面的代码定义p1为一个指向结构的指&#xff0c;p2为一个实际的结构&#xff0c;这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针。




晦涩的语法




16 . C语言同意一些令人震惊的结构,下面的结构是合法的吗&#xff0c;如果是它做些什么&#xff1f;




int a &#61; 5, b &#61; 7, c;


c &#61; a&#43;&#43;&#43;b;




      这个问题将做为这个测验的一个愉快的结尾。不管你相不相信&#xff0c;上面的例子是完全合乎语法的。问题是编译器如何处理它&#xff1f;水平不高的编译作者实际上会争论这个问题&#xff0c;根据最处理原则&#xff0c;编译器应当能处理尽可能所有合法的用法。因此&#xff0c;上面的代码被处理成&#xff1a;




c &#61; a&#43;&#43; &#43; b;




      因此, 这段代码持行后a &#61; 6, b &#61; 7, c &#61; 12。


      如果你知道答案&#xff0c;或猜出正确答案&#xff0c;做得好。如果你不知道答案&#xff0c;我也不把这个当作问题。我发现这个问题的最大好处是这是一个关于代码编写风格&#xff0c;代码的可读性&#xff0c;代码的可修改性的好的话题。

推荐阅读
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • MATLAB函数重名问题解决方法及数据导入导出操作详解
    本文介绍了解决MATLAB函数重名的方法,并详细讲解了数据导入和导出的操作。包括使用菜单导入数据、在工作区直接新建变量、粘贴数据到.m文件或.txt文件并用load命令调用、使用save命令导出数据等方法。同时还介绍了使用dlmread函数调用数据的方法。通过本文的内容,读者可以更好地处理MATLAB中的函数重名问题,并掌握数据导入导出的各种操作。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
author-avatar
恨透这一切_249
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有