面试:有时候还需要多些自信

时间:2024-09-15 00:16:42 综合指导

面试:有时候还需要多些自信

今天遇到了个面试,其中有的问题我当时还真不能确定,遂发出来,大家分享。

面试:有时候还需要多些自信


先大致讲一下流程,一面还挺顺利,游刃有余;二面就有些紧张了,是个额头头发不多但是显得很精干的男士(下文简称为a)。


只摘录其中的部分我很“为难”的地方:


a:string是值类型是引用类型?


me:(我心想string是class,肯定是)引用类型


a:那我有个方法,参数为string,我在里面改变他的值,原来的会变吗?


me:(这个我当时很犹豫,虽说string平时用,但是还真考虑过这个。我要是说会不会变吧,岂不是自打嘴巴?string是引用类型,怎么还值专递呢?)


当时我就记得园子里有句话:string是引用类型,但是用起来像值类型。我就说的是不变。


下面上一段代码分析一下:





static  void  foo(string    s)
{
s  =  "bbb" 
}
string  s  =  "aaa" 
foo(s) 
console.writeline(s) 
这个确实是不会变的,调用完之后还是“aaa”,这是为什么呢?




1  string  s  =  "aaa" 
  2  00000051  8b  05  88  20  c0  02  mov                  eax,dword  ptr  ds:[02c02088h]  
  3  00000057  89  45  b8                  mov                  dword  ptr  [ebp-48h],eax  
  4          92:                          foo(s) 
  5  0000005a  8b  4d  b8                  mov                  ecx,dword  ptr  [ebp-48h]  
  6  0000005d  e8  a6  af  d4  ff      call                ffd4b008  
  7  00000062  90                              nop                            
  8          93:                          console.writeline(s) 
  9  00000063  8b  4d  b8                  mov                  ecx,dword  ptr  [ebp-48h]  
10  00000066  e8  95  24  3f  67      call                673f2500  
11  
12  
13  
14  
15  
16    static  void  foo(string    s)
17          82:                  {
18  00000000  55                              push                ebp    
19  00000001  8b  ec                        mov                  ebp,esp  
20  00000003  57                              push                edi    
21  00000004  56                              push                esi    
22  00000005  53                              push                ebx    
23  00000006  83  ec  30                  sub                  esp,30h  
24  00000009  33  c0                        xor                  eax,eax  
25  0000000b  89  45  f0                  mov                  dword  ptr  [ebp-10h],eax  
26  0000000e  33  c0                        xor                  eax,eax  
27  00000010  89  45  e4                  mov                  dword  ptr  [ebp-1ch],eax  
28  00000013  89  4d  c4                  mov                  dword  ptr  [ebp-3ch],ecx  
29  00000016  83  3d  e0  8c  7b  00  00  cmp                  dword  ptr  ds:[007b8ce0h],0  
30  0000001d  74  05                        je                    00000024  
31  0000001f  e8  1d  91  57  68      call                68579141  
32  00000024  90                              nop                            
33          83:                          s  =  "bbb" 
34  00000025  8b  05  90  20  c0  02  mov                  eax,dword  ptr  ds:[02c02090h]  
35  0000002b  89  45  c4                  mov                  dword  ptr  [ebp-3ch],eax  
36          84:                  }
37  0000002e  90                              nop                            
38  0000002f  8d  65  f4                  lea                  esp,[ebp-0ch]  
39  00000032  5b                              pop                  ebx    
40  00000033  5e                              pop                  esi    
41  00000034  5f                              pop                  edi    
42  00000035  5d                              pop                  ebp    
43  00000036  c3                              ret                            

可以看到第2行将字符串的地址写入到 eax,然后写到堆栈的【ebp-48h】处;


调用foo方法前,放到ecx中。


在方法foo中,可以看到又经ecx放到了【ebp-3ch】处;


在执行s=“bbb”的时候,同样将新字符串的地址放到了【ebp-3ch】处,但是原来的字符串并为更改,只是更改了临时变量s的引用。


所以在调用完方法foo之后,原来的字符串还是“aaa”,没有改变。


所以这个时候我回答不变是对的,但是我不知道为什么string的传递是类似于值传递的,有点运气了。


接下来,他又问


a:那如果我有个类,里面有string成员,我同样改变他的值,外面的会变吗?这个时候我回答的是可以改变。


是不是这样呢?同样,上代码:





1  class  c1
  2          {
  3                  public  string  s1="aaa" 
  4          }
  5  
  6    static  void  foo(c1      c1)
  7                  {
  8                          c1.s1    =  "bbb" 
  9                  }
10  
11    c1  c1  =  new  c1() 
12                          foo(c1) 
13                          console.writeline(c1.s1  ) 





1    foo(c1) 
  2  0000006c  8b  4d  b8                  mov                  ecx,dword  ptr  [ebp-48h]  
  3  0000006f  e8  94  af  7f  ff      call                ff7fb008  
  4  00000074  90                              nop                            
  5          93:                          console.writeline(c1.s1  ) 
  6  00000075  8b  45  b8                  mov                  eax,dword  ptr  [ebp-48h]  
  7  00000078  8b  48  04                  mov                  ecx,dword  ptr  [eax+4]  
  8  0000007b  e8  80  24  52  67      call                67522500  
  9  
10  
11  
12    static  void  foo(c1      c1)
13          82:                  {
14  00000000  55                              push                ebp    
15  00000001  8b  ec                        mov                  ebp,esp  
16  00000003  57                              push                edi    
17  00000004  56                              push                esi    
18  00000005  53                              push                ebx    
19  00000006  83  ec  30                  sub                  esp,30h  
20  00000009  33  c0                        xor                  eax,eax  
21  0000000b  89  45  f0                  mov                  dword  ptr  [ebp-10h],eax  
22  0000000e  33  c0                        xor                  eax,eax  
23  00000010  89  45  e4                  mov                  dword  ptr  [ebp-1ch],eax  
24  00000013  89  4d  c4                  mov                  dword  ptr  [ebp-3ch],ecx  
25  00000016  83  3d  e0  8c  13  00  00  cmp                  dword  ptr  ds:[00138ce0h],0  
26  0000001d  74  05                        je                    00000024  
27  0000001f  e8  ad  90  6a  68      call                686a90d1  
28  00000024  90                              nop                            
29          83:                          c1.s1    =  "bbb" 
30  00000025  8b  05  90  20  d7  02  mov                  eax,dword  ptr  ds:[02d72090h]  
31  0000002b  8b  4d  c4                  mov                  ecx,dword  ptr  [ebp-3ch]  
32  0000002e  8d  51  04                  lea                  edx,[ecx+4]  
33  00000031  e8  9a  16  45  68      call                684516d0  
34          84:                  }
35  00000036  90                              nop                            
36  00000037  8d  65  f4                  lea                  esp,[ebp-0ch]  
37  0000003a  5b                              pop                  ebx    
38  0000003b  5e                              pop                  esi    
39  0000003c  5f                              pop                  edi    
40  0000003d  5d                              pop                  ebp    
41  0000003e  c3                              ret                            

在执行30行的时候eax是01dbc268,其内存的内容拷贝出来是:





54  0b  a0  67  04  00  00  00  03  00  00  00  62  00  62  00  62  00  00  00  00  
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

可以看出这是一个string的实例,前面的67a00b54是mt的地址,后面的00000004是字符串的实际长度,00000003是字符串有效内容的长度,


后面的3个0062是连着三个字符‘b’,看来确实是字符串“bbb”。再后面00的就不管了。


接着依次执行31和32行,则ecx是01d9eec8,edx是01d9eecc;据猜测ecx应该是c1的地址,把内存考出来看一下:





d0  99  41  00  94  ee  d9  01  00  00  00  00  24  43  9d  67  0a  00  00  00  70  07  a0  67  
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

而此时edx就应该是s1的地址,可以看出edx就比ecx相差4,所以01d9ee94就应该是字符串“aaa”的地址,同样考出来看看:





54  0b  a0  67  04  00  00  00  03  00  00  00  61  00  61  00  61  00  00  00  00  00  00

可以看出,“aaa”和“bbb”的头几个部分完全是一样的,就是后面的一个是61,一个是62.


那么问题很简单了,知道把c1里的字符串地址从01d9ee94换成01dbc268就算ok了。事实上33行就是做这个事情的。


看一下执行完33行后的c1的内容:





d0  99  41  00  68  c2  db  01  00  00  00  00  24  43  9d  67  0a  00  00  00  70  07  a0  67  
00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00

可以看出,确实是换了。


所以到这里,问题解决了。

【面试:有时候还需要多些自信】相关文章:

面试后还需要做的……10-21

面试,自信是关键09-22

面试结束后还需要注意哪些问题10-03

面试技巧:自信是关键10-09

面试别不自信07-04

自信,敲开面试之门06-04

面试:自信 细节 执着10-12

面试技巧:自信、细节、执着07-10

自信是面试制胜的关键10-14

进度显示笔试阶段还需要那个所谓的面试预选吗08-08