面试题2

2019-05-17  本文已影响0人  XDgbh

四、数据结构和算法

1、求一串数字序列中的连续子串最大和,比如arr=1 -2 3 -1 2,连续子串最大和就是3 -1 2组成的max_sum=4。

int MaxSubSum(int *arr, int n)
{
    int sum=0, b=0;  //只用一个b记录dp[i],更节省内存
    for (int i=1;i<=n; i++)
    {
        if (b>0) b+=a[i];
        else b=a[i];
        if (b>sum) sum=b;
    }
    return sum;
}

2、寻找100范围内的素数的算法,对于找到的前面的每个素数的n倍都必然不是素数,都可以剔除检查

五、网络

1、TCP三次握手,四次挥手状态改变过程?




为什么就需要3次握手,不是2次或者4次?
三次握手的目的:是为了确认双方都有收发数据的能力或者说想确定双通道通畅
Client->Server:表明C有发数据的能力,发了seq序列号x。
S->C:回应x+1表明S有收数据的能力收到过x,也有发数据的能力并且发了序列号y。
C->S:回应y+1表明C也有收数据的能力。
至此C S都互相确认了对方有收发数据的能力,然后就可以放心的向对方数据了。若是只有两次,那么Server是不能确认Client能够收数据的。两次达不到目的,3次能搞定的事情,4次就显得多余了。
》从另一方面来讲,若是默认双方都能收发数据,两次握手时,如果因为网络拥塞先前的client某个连接请求被延迟,而超时重发连接请求后连接成功然后收发数据结束后断开连接了。但是之前延迟的连接请求又最终发到了server端,server以为是个新连接然后就准备给client发送数据,但是client此时并没有连接,因此收不到server的数据,导致server不停的重发数据直至认为应该断开连接,但是也会造成资源浪费。
》假设不采用“三次握手”而是两次,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。
这个问题的本质是, 信道不可靠, 但是通信双方需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了. 因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了.”。这可视为对“三次握手”目的的另一种解答思路。后面一段话意思就是如果想确定双通道通畅,必须使用三个包的发送接收,也就是三次握手。

为什么需要4次挥手?
那可能有人会有疑问,在tcp连接握手时为何ACK是和SYN一起发送,这里ACK却没有和FIN一起发送呢。原因是因为tcp是全双工模式,接收到FIN时意味着对方将没有数据再发来,但是本方还是可以继续发送数据到对方。因为每两次握手确认一边不再发数据,两边都不发数据就需要4次握手了。

2、TIME_WAIT状态存在的理由和作用?

3、ping网络主机之间通不通用到什么协议?

4、什么时候使用TCP,什么时候使用UDP?

5、为什么 TCP 叫数据流模式? UDP 叫数据报模式?

6、IP地址的分类?私有IP(局域网IP)是哪些——相对于公网IP来说?

7、http协议和各个状态码表示什么意思?

<method> <request-URL> <version>
<headers>

<entity-body>

200 OK 客户端请求成功
301 Moved Permanently 请求的资源永久移动
302 Moved Temporarily 请求的资源临时移动
304 Not Modified 文件未修改,可以直接使用浏览器缓存的文件,无需再从服务器下载。
400 Bad Request 由于客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized 请求未经授权,则要求客户端再次发送用户名密码等认证信息。这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden 服务器收到请求,但是拒绝提供服务。服务器通常会在响应正文中给出不提供服务的原因
404 Not Found 请求的资源不存在,例如,输入了错误的URL
500 Internal Server Error 服务器内部发生不可预期的错误,导致无法完成客户端的请求。
503 Service Unavailable 服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常。

8、 sip协议和上面的http非常像,包含了并且扩展了HTTP/1.1的一些状态码:

临时应答(1XX)
100 Trying 正在处理中
180 Ringing 振铃
181 call being forwarder 呼叫正在前向
182 queue 排队
181* session progress 会话进行
305 use proxy 用户代理
380 alternative service 替代服务
请求失败(4XX)
405 method no allowed 方法不允许
406 not acceptable 不可接受
407 proxy authentication required 代理需要认证
408 request timeout 请求超时
服务器失败(5XX)
501 not implemented 不可执行
502 bad gateway 坏网关
503 service unavailable 服务无效
504 server time-out 服务器超时
505 version not supported 版本不支持
全局性错误(6XX)
600 busy everywhere 全忙
603 decline 丢弃
604 does not exist anywhere 不存在
606 not acceptable 不可接受

9、访问一个网站失败,如何定位故障?


六、linux操作系统

1、举几个常用的linux命令?

2、linux中想要将一个文件中的字符串A全部用字符串B替换,命令怎么写?

3、正则表达式的匹配规则?

^ 表示一行的开头。如:/^#/ 以#开头的匹配。
$表示一行的结尾。如:/}$/ 以}结尾的匹配。
< 表示词首。 如:<abc 表示以 abc 为首的詞。
> 表示词尾。 如:abc> 表示以 abc 結尾的詞。
. 表示任何单个字符。
* 表示任何0或多个字符。
[ ] 字符集合。 如:[abc] 表示匹配a或b或c,还有 [a-zA-Z] 表示匹配所有的26个字符中的一个。如果其中有^表示反,如 [^a] 表示非a的一个字符。[0-9]表示匹配0到9的一个数字。

4、awk命令选定分隔符?

5、Linux命令去重统计排序(awk命令去重保留原顺序,sort, uniq命令排序去重统计)?

6、Nginx服务器架构?

7、C/S架构和B/S结构?


8、gdb调试常用命令?


https://blog.csdn.net/sunxiaopengsun/article/details/72974548
》》》造成segment fault,产生core dump的可能原因
1.内存访问越界
a) 由于使用错误的下标,导致数组访问越界
b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符
c) 使用strcpy, strcat, sprintf, strcmp, strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。
2 多线程程序使用了线程不安全的函数。
3 多线程读写的数据未加锁保护。对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成core dump
4 非法指针
a) 使用空指针
b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump.
5 堆栈溢出.不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。

9、从C源代码到可执行文件的编译链接过程?

gcc test.c -o test ,这一行命令就可以将test.c源代码生成可执行文件test,下面是拆解这个过程。预处理》编译》汇编》链接》可执行文件总结这个变化过程为test.c 》 test.i 》 test.s 》 test.o 》 test

我们用gcc编译程序时,常常会用到“-I”(大写i)后接头文件地址,“-L”(大写l)后接链接库文件地址,“-l”(小写l)指定需链接的库文件等参数(当既有动态库world.so又有静态库world.a时默认使用动态库,若要首选静态库则要加上-static选项),下面做个记录:例:
gcc -o hello hello1.c hello2.c hello3.c -I/home/hello/include -L/home/hello/lib -lworld

10、静态库和动态库生成和区别?

头文件<dlfcn.h>
void* handle = dlopen("libtest.so", RTLD_LAZY); //根据地址加载动态库,并选定加载模式是立即加载RTLD_NOW还是用到时再加载RTLD_LAZY。加载失败时返回空。
void (*test_func)() = dlsym(handle, "test");根据提供的函数名test从动态库中返回该函数的调用地址并赋给一个函数指针。
(*test_func)();执行该函数,也可以是test_func();
int flag = dlclose(handle);动态库卸载函数,传入的参数是加载时返回的句柄,返回值为0表示成功,非0错误。

七、数据库管理系统(DBMS——MySQL是一种关系型DBMS)

0、MySQL基于tcp协议?

问题
(1).Unix socket方式登陆与TCP方式登陆有什么区别和联系?
Unix socket是实现进程间通信的一种方式,mysql支持利用Unix socket来实现客户端-服务端的通信,但要求客户端和服务端在同一台机器上。对于unix socket而言,同样也是一种套接字,监听线程会同时监听TCP socket和Unix socket,接受到请求然后处理,后续的处理逻辑都是一致的,只不过底层通信方式不一样罢了。
mysql -h127.0.0.1 –P3306 –uxxx –pxxx [TCP通信方式,需要指明host、Port]
mysql -uxxx –pxxx –S/usr/mysql/mysql.sock [unix socket通信方式,不需要h\P]
(2).监听socket是否与通信socket公用一个端口?
我们知道,服务端一直有一个监听socket在3306端口监听,等待新进来的客户请求,一旦一个请求过来,服务端会重新创建一个新的通信socket,这个新的socket专门用于与这个客户通信,而监听socket则继续监听。虽然是2个套接字,但监听socket和通信socket都是同一个端口,通过netstat可以确认这个问题。
(3).连接超时参数connect_timeout在何时作用?
这个参数实质就是在MYSQL认证过程起作用,如果在这个过程中,客户端超过connect_timeout时间仍然没有发送密码认证包过来,则会主动断开连接。

1、事务(transaction)是什么?

2、事务有几个特性?分别是什么?

3、MySQL数据库基本操作命令

create table students
(
  id int unsigned not null auto_increment primary key,
  name char(8) not null,
  sex char(4) not null,
  age tinyint unsigned not null,
  tel char(13) null default "-"
     );

4、mysql默认是不区分列名大小写的(输入的大写会先转为小写再保存),如何使字段查询区分大小写?

CREATE TABLE test(
id INT PRIMARY KEY,
name VARCHAR(32) NOT NULL  //或者在后面直接指定BINARY二进制形式存储
) ENGINE = INNODB COLLATE =utf8_bin;

如果表已经创建,则修改表结构中Collation字段

5、sql的查询优化原则?

mysql> SELECT * FROM product LEFT JOIN product_details
       ON (product.id = product_details.id)
       AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id   | weight | exist |
+----+--------+------+--------+-------+
|  1 |    100 | NULL |   NULL |  NULL |
|  2 |    200 |    2 |     22 |     0 |
|  3 |    300 | NULL |   NULL |  NULL |
|  4 |    400 | NULL |   NULL |  NULL |
+----+--------+------+--------+-------+
rows in set (0.00 sec)
 
mysql> SELECT * FROM product LEFT JOIN product_details
       ON (product.id = product_details.id)
       WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
|  2 |    200 |  2 |     22 |     0 |
+----+--------+----+--------+-------+
row in set (0.01 sec)

从上可知,第一条查询使用 ON 条件决定了从 LEFT JOIN的 product_details表中检索符合的所有数据行。
第二条查询做了简单的LEFT JOIN,然后使用 WHERE 子句从 LEFT JOIN的数据中过滤掉不符合条件的数据行。

6、数据库的备份和恢复?

小量的数据库可以每天进行完整备份,因为这也用不了多少时间,但当数据库很大时,就不太可能每天进行一次完整备份了,这时候就可以使用增量备份。增量备份的原理就是使用了mysql的binlog志。
1、首先做一次完整备份:
mysqldump -h10.6.208.183 -utest2 -p123 -P3310 --single-transaction --master-data=2 test>test.sql这时候就会得到一个全备文件test.sql
在sql文件中我们会看到:
-- CHANGE MASTER TO MASTER_LOG_FILE='bin-log.000002', MASTER_LOG_POS=107;是指备份后所有的更改将会保存到bin-log.000002二进制文件中。
2、在test库的t_student表中增加两条记录,然后执行flush logs命令。这时将会产生一个新的二进制日志文件bin-log.000003,bin-log.000002则保存了全备过后的所有更改,既增加记录的操作也保存在了bin-log.00002中。
3、再在test库中的a表中增加两条记录,然后误删除t_student表和a表。a中增加记录的操作和删除表a和t_student的操作都记录在bin-log.000003中。

1、首先导入全备数据
mysql -h10.6.208.183 -utest2 -p123 -P3310 < test.sql,也可以直接在mysql命令行下面用source导入
2、恢复bin-log.000002
mysqlbinlog bin-log.000002 |mysql -h10.6.208.183 -utest2 -p123 -P3310
3、恢复部分 bin-log.000003
在general_log中找到误删除的时间点,然后更加对应的时间点到bin-log.000003中找到相应的position点,需要恢复到误删除的前面一个position点。
可以用如下参数来控制binlog的区间
--start-position 开始点 --stop-position 结束点
--start-date 开始时间 --stop-date 结束时间
找到恢复点后,既可以开始恢复。
mysqlbinlog mysql-bin.000003 --stop-position=208 |mysql -h10.6.208.183 -utest2 -p123 -P3310
https://www.cnblogs.com/Cherie/p/3309456.html

7、数据库的3大范式?反范式?

1、第一范式
确保数据表中每列(字段)的原子性。
如果数据表中每个字段都是不可再分的最小数据单元,则满足第一范式。
例如:user用户表,包含字段id,username,password
例如:顾客表(姓名、编号、地址、……)其中"地址"列还可以细分为国家、省、市、区等。需要拆分成两个表:
顾客表——姓名、编号、地址ID
地址表——主键、国家、省份、市区
2、第二范式
在第一范式的基础上更进一步,目标是确保表中的每列都和主键相关。
如果一个关系满足第一范式,并且除了主键之外的其他列,都依赖于该主键,则满足第二范式。
例如:一个用户只有一种角色,而一个角色对应多个用户。则可以按如下方式建立数据表关系,使其满足第二范式。
user用户表,字段id,username,password,role_id
role角色表,字段id,name
用户表通过角色id(role_id)来关联角色表
3.第三范式
在第二范式的基础上更进一步,目标是确保表中的列都和主键直接相关,而不是间接相关。
例如:一个用户可以对应多个角色,一个角色也可以对应多个用户。则可以按如下方式建立数据表关系,使其满足第三范式。
user用户表,字段id,username,password
role角色表,字段id,name
user_role用户-角色中间表,id,user_id,role_id
像这样,通过第三张表(中间表)来建立用户表和角色表之间的关系,同时又符合范式化的原则,就可以称为第三范式。
4.反范式化
反范式化指的是通过增加冗余或重复的数据来提高数据库的读性能。
例如:在上例中的user_role用户-角色中间表增加字段role_name。
反范式化可以减少关联查询时,join表的次数。

8、常用的MySQL函数处理select查询的返回值?

9、分组查询GROUP BY?分组过滤HAVING(和where过滤的区别)?


注意上面的HAVING后的表达式必须写完整的而不能用上面的别名。

10、MySQL引擎的区别?

通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、更新数据更快、视图、存储过程、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,硬件资源有限也可以使用存储空间少的MyISAM,这个具体情况可以自己斟酌。

11、视图的使用?



12、存储过程?

DELIMITER //
create procedure order_total(
   IN order_num int,
   OUT order_sum decimal(8,2)
)
BEGIN
   select sum(item_price*quantity) 
   from orderitems where order_id = order_num
   into order_sum;
END //
DELIMITER ;  


// 调用这个存储过程
call order_total(1001,@total);
// 查看订单1001的结果:切记此处需要@
select @total;
//显示存储过程的创建语句
show CREATE PROCEDURE order_total;
// 删除过程:切记此处没有括号
dorp prodedure order_total;
//列出所有存储过程,包括显示何时由谁创建等信息。
show PROCEDURE STATUS;  // LIKE "order_total"; 则是显示指定的存储过程的状态

13、触发器?


14、数据库的索引?

15、创建索引的方式?

16、sqlite3数据库和MySQL数据库的区别?

上一篇 下一篇

猜你喜欢

热点阅读