岗位:软件开发岗位
初面,远程视频
以下为个别问题,我进行详细记录,以便后续参考:
-
cURL—— 参考https://baike.baidu.com/item/curl/10098606?fr=aladdin;https://baike.baidu.com/item/libcurl/5256898?fr=aladdin
- 解释:cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。
- libcurl主要功能就是用不同的协议连接和沟通不同的服务器~也就是相当封装了的sockPHP 支持libcurl(允许你用不同的协议连接和沟通不同的服务器)。, libcurl当前支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传(当然你也可以使用PHP的ftp扩展), HTTP基本表单上传,代理,cookies,和用户认证。
- 它支持的通信协议:FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。----curl还支持SSL认证、HTTP POST、HTTP PUT、FTP上传, HTTP form based upload、proxies、HTTP/2、cookies、用户名+密码认证(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos)、file transfer resume、proxy tunneling。
- 以下介绍两种方法以及使用curl获取它们的命令:
4.1、在表单中,使用get()方法,提交数据:
代码:
<form method="GET" action="junk.cgi">
<input type=text name="birthyear">
<input type=submit name=press value="OK">
</form>
那么浏览器上会出现一个文本框和一个标为“OK”的按钮。按下这个按钮,表单就用GET方法向服务器提交文本框的数据。
例如原始页面是在 www.hotmail. com/when/birth.html看到的,然后您在文本框中输入1905,然后按OK按钮,那么浏览器的URL现在应该是:“www.hotmail. com/when/junk.cgi?birthyear=1905&press=OK”
对于这种网页,curl可以直接处理,例如想获取上面的网页,只要输入:
curl "www.hotmail. com/when/junk.cgi?birthyear=1905&press=OK"
就可以了~
4.2、使用POST方法用来提交表单信息,POST方法和GET方法的区别在于GET方法使用的时候,浏览器中会产生目标URL,而POST不会。类似GET,这里有一个网页:
<form method="POST" action="junk.cgi">
<input type=text name="birthyear">
<input type=submit name=press value="OK">
</form>
浏览器上也会出现一个文本框和一个标为“OK”的按钮。按下这个按钮,表单用POST方法向服务器提交数据。
这时的URL是看不到的,因此需要使用特殊的方法来抓取这个页面,使用curl来执行这一操作,其命令如下:
curl -d "birthyear=1905&press=OK" www.hotmail. com/when/junk.cgi
-
给定一个数,如何快速判断这个数是否为2的x次方所对应的数?
- 先说一下我的思路:当时一片茫然,首先想到的是用除法来做,可是除法一般都是基于整数来做的,例如5/2得到的结果就是2,而4/2的结果也是2,行不通,我进而转向取余来做,长时间没有碰这些东西,取余一时间也认为不可以。后来我想到了java强大的封装功能,虽然没有实际用到过java中的数学函数,但是我想应该是会有基于对数运算的函数。接下来思考完毕,我将第一个解决方法:使用java封装好的函数进行运算,给面试官说了;显然他不满意;
- 后来我又说一个笨方法。首先想到了除法,但是想到了除法的缺陷,我就转向取余,后来和面试官沟通之后,取余是可以的,显然还要高效一点;
- 可能面试官已经不想再说这个问题了,但是当时我也想知道是什么高效的方法,面试官给我提示说2是一个特殊的数字,最后他给我说使用进制转换,例如说二进制。我顺着他的思路,想了一下,2的二进制是10,4的二进制是100,8的二进制是1000,那么2^n的二进制应该是1后面n个0。说到这里,我就想是不是将两个数转换为二进制,再进行对比呢?我给面试官说了以这个想法,他说那需要一个一个对比吗?这下我有迷茫了,见我又开始埋头思考,他最后终于说要使用与或运算,就这样,第一个压轴题结束了。
- 先顺便复习一下对数函数的性质:
参考:https://blog.csdn.net/f1024042400/article/details/52064652
性质:
1、a^(log(a)(b))=b
2、log(a)(a^b)=b
3、log(a)(MN)=log(a)(M)+log(a)(N);
4、log(a)(M÷N)=log(a)(M)-log(a)(N);
5、log(a)(M^n)=nlog(a)(M)
6、利用换底公式:log(x)(y) =log(e)(x) / log(e)(y),我们可以这样做:Math.log(1000*10000) / Math.log(2);
解法一:使用java中数学函数对数的方法解决这个问题的代码:
有一点需要注意:这个函数的返回值为double类型,我是强制转换为int类型的;
/**
* @author 橙橙橙。
* Date:2019年03月28日
* 描述:利用Math封装的函数,求出对数的值
*/
public class AboutLog {
public static void main(String[] args) {
int value = 32;
int base = 2;
int res = logFunction(value, base);
System.out.println(res);
}
//写一个函数,利用换底公式进行计算。换底公式:log(x)(y) =log(e)(x)/log(e)(y)
public static int logFunction(int value, int base) {
return (int) (Math.log(value)/Math.log(base));
}
}
结果如下:
5
解法二:今天看到了博客园上有一个写法,我觉得很好,链接为:https://www.cnblogs.com/daisy0707/p/5279078.html使用位运算进行,看了几遍之后,我也自己写了一下;
在写之前,先复习一下移位是怎么回事?
来自百度百科的说法:移位运算符在程序设计中,是位操作运算符的一种。移位运算符可以在二进制的基础上对数字进行平移。按照平移的方向和填充数字的规则分为三种:<<(左移)、>>(带符号右移)和>>>(无符号右移)。
更加通俗易懂的说法可以理解为:左移就是给一个数乘2,右移就是给一个数除2;所以,对于任意一个数,我们都可以使用移位的方法来运算出它是否为2的n次方的数;代码如下:
/**
* @author 橙橙橙。
* Date:2019年3月28日
* 描述:使用位运算,实现快速判断某个数是否为2^n所对应的数之一
*/
public class TransBin {
public static void main(String[] args) {
boolean b1 = removeShift(4);
boolean b2 = removeShift(6);
System.out.println("4是否为2的n次方所对应的数: " + b1 + "\n6是否为2的n次方所对应的数: " + b2);
}
public static boolean removeShift(int n) {
//这个判断主要是为了程序的健壮性;
if(n < 1)
return false;
//当n是大于1的整数时,定义一个基数为1
int count = 1;
while(count <= n){ //当我们要检验的这个数小于等于1时,进入循环
if(count == n) //如果两者 相等,则直接返回true
return true;
if(count < n) //如果检验的数较大时,对我们对应的基准数进行左移一位操作。也就是乘2操作
count <<= 1;
System.out.println(count);
}
return false; //如果到了这里还没返回的话,就是false了,例如n=5时
}
}
结果:
2
4
2
4
8
4是否为2的n次方所对应的数: true
6是否为2的n次方所对应的数: false
解法三:根据2与2的n次方所对应的数的特征,使用“与”运算。 2对于的二进制为10,4对应的为100,8对应的为1000……以此类推,2的n次方,对应1后面是n个0,但是当1000 - 1之后,就是0111,1000与0111按位相与,得到的就是0,因此,最简单的方法就是放这个数与它前一位进行相与运算,即可立即算出这个数是否为2的n次方所对应的数!参考:https://www.cnblogs.com/daisy0707/p/5279078.html
代码:
/**
* @author 橙橙橙。
* Date:2019年3月28日
* 描述:使用二进制的特殊性,快速判断一个数是否为2的n次方所对应的数
*/
public class BestMethod {
public static void main(String[] args) {
boolean b1 = SimpePanDuan(1024);
System.out.println("刚才输入的数是否为2的n次方所对应的数? " + b1);
}
public static boolean SimpePanDuan(int n) {
if(n < 1)
return false;
if((n&(n - 1)) == 0)
return true;
return false;
}
}
结果为:
刚才输入的数是否为2的n次方所对应的数? true
-
描述一个url从执行到获取数据的过程:
- 参考:https://blog.csdn.net/xingxingba123/article/details/52743335
- 参考:https://blog.csdn.net/weixin_38150378/article/details/79443584
- 参考:https://blog.csdn.net/wlk2064819994/article/details/79756669
-
一个未知长度的单链表,寻找它的中间元素的值,注意时间复杂度
- 首先可以根据Java语言的特点创建一个链表的节点,定义两个属性,一个value,一个节点类型的next;如下所示:
public class LinkedNode { int value; LinkedNode next; public LinkedNode(int value) { this.value = value; } }
- 写一个函数,传入一个参数值,如果参数值只有一个或者为空,则直接返回。如果有值,则定义两个指针,一个指向当前节点,一个指向当前节点的两倍的节点;这样做主要是当快的指针指向末尾的时候,慢指针正好在中间位置,这时候就可以得到我们想要的值了。如下:
public static LinkedNode findMidPoint(LinkedNode head) { if(head == null || head.next == null) { return head; } LinkedNode fastPoint = head; //定义一个快指针,初始位置在头结点 LinkedNode slowPoint = head; //定义一个慢指针,初始位置在头节点 while(fastPoint.next != null) { //如果当前指针的下一个指针不为空 if(fastPoint.next.next != null) { //如果当前指针的下下位指针不为空 slowPoint = slowPoint.next; //如果满足条件,则慢的指针指向下一个节点; fastPoint = fastPoint.next.next; //快指针指向下一个节点的下一个节点 } else { slowPoint = slowPoint.next; //如果不满足条件,则指向慢指针的下一个节点 return slowPoint; //此时可以ruturn了 } } return slowPoint; }
其实fastPoint的指向速度是slowPoint速度的二倍?二倍如何体现?方slow的指向为1时,fast为2;当slow为2时,fast指针为4,每次的增加都是在前一次的基础上,而不是fast在slow的基础上添加的。
-
整体实现如下代码:
/** * @author 橙橙橙。 * Date:2019年3月31日 * 描述:一个长度未知链表,找出中间节点的值,注意时间复杂度 */ public class LinkedNode { int value; LinkedNode next; public LinkedNode(int value) { this.value = value; } public static void main(String[] args) { LinkedNode lick1 = new LinkedNode(3); LinkedNode node2 = new LinkedNode(5); LinkedNode node3 = new LinkedNode(6); LinkedNode node4 = new LinkedNode(8); LinkedNode node5 = new LinkedNode(10); LinkedNode node6 = new LinkedNode(19); LinkedNode node7 = new LinkedNode(20); LinkedNode node8 = new LinkedNode(30); //将LinkedNode类的对象连接成一个链表 lick1.next = node2; node2.next = node3; node3.next = node4; node4.next = node5; node5.next = node6; node6.next = node7; node7.next = node8; LinkedNode node = findMidPoint(lick1); System.out.println(node.value); } public static LinkedNode findMidPoint(LinkedNode head) { if(head == null || head.next == null) { return head; } LinkedNode fastPoint = head; LinkedNode slowPoint = head; while(fastPoint.next != null) { if(fastPoint.next.next != null) { slowPoint = slowPoint.next; fastPoint = fastPoint.next.next; } else { slowPoint = slowPoint.next; return slowPoint; } } return slowPoint; } }
结果如下:
10
加油加油!算法开始入门了~耶