一道Java这道题没有那道题简单题

问题:char[]与String相比,有什么优胜的地方?
针对安全保密高的信息,char[]比String做得更好。因为String是不可变得,即使你修改原先的变量,实际上也是在内存中新建一个对象,原数据还是保留在内存中,等待回收。而char[]中的元素是可以更改的。这就意味着,如密码等保密信息用完之后,你可以马上修改它而不能痕迹。从而相对于String有更好的安全性。可从下面例子中看出,char[]变更内容后,仍是那个对象。而String已经不是原来的String了。
这个对比,在知乎中这个贴有非常好的回答,我把它引用在下面:
作者:知乎用户
链接:https://www.zhihu.com/question//answer/
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
=====================
图里说的很清楚,虽然String加载密码之后可以把这个变量扔掉,但是字符串并不会马上被GC回收,一但进程在GC执行到这个字符串之前被dump,dump出的的转储中就会含有这个明文的字符串。
那如果我去"修改"这个字符串,比如把它赋一个新值,那么是不是就没有这个问题了?
答案是否定的,因为String本身是不可修改的,任何基于String的修改函数都是返回一个新的字符串,原有的还会在内存里。
对于char[]来说,你可以在抛弃它之前直接修改掉它里面的内容,密码就不会存在了。但是如果你什么也不做直接交给gc的话,也会存在上面一样的问题。
有的大神说这个是毫无根据的扯淡
这些所谓的大神应该没有什么安全方面的常识,这非常普遍。
======================
1. 这种做法意义有多大?
如果没有及时清空而由GC来清除的话,暴露窗口大约是秒这个数量级,如果能够在计算HASH后立即清除,暴露窗口大约是微秒数量级。如此简单的设计就可以降低如此多的被攻击概率,性价比是非常高的。
2. 如何使用反射来修改String? 和修改char[] 相比,有何区别和风险?
通过reflection机制可以查看String的内部的内存成员,从而可以直接修改其中的数据区。但是这样的做法会有问题,内部化的String为了提高HASH速度,节省空间,值相同的字符串通常只有一个实例。
你自己的char[],修改它是没有副作用的。但是String里的char[],很可能是多个String所共享的,你改掉它就会殃及别的String。举个例子,有一个密码是"Password",而你密码框提示密码输入的文字也是"Password",改掉第一个"Password"会把后面那个也改掉。
3. 如果一点明文也不想出现,应该怎么做?
为了保证"全部处理流程均无明文密码",需要底层API在给你密码之前就做了HASH,并且这个HASH算法就是你想要的那种。最好还加盐。不过这只是在用户程序方面无明文,底层获取中会不会有明文就保证不了了。
4. 有没有绝对安全策略?
安全往往是相对于攻击成本而言的,攻击收益越高,黑客就越能接受攻击成本高的方案。因此,你采取的安全策略应该与这个攻击收益相匹配。对于极其敏感和宝贵的数据来源,就需要在安全方面上下很大功夫。目前来看,没有绝对的安全,只有相对的安全。
阅读(...) 评论()一道JAVA面试题,难道我了。 - 『悬赏问答区』
- 吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn
后使用快捷导航没有帐号?
只需一步,快速开始
请完成以下验证码
请完成以下验证码
查看: 1377|回复: 10
一道JAVA面试题,难道我了。
阅读权限10
已知带有特殊标记的sql语句和前端传过来的参数集合,用参数替换sql的特殊标记,如果标记对应的参数存在,则直接替换,如果不存在,要把对应的一段条件去掉,最后得出一个能用于查询的sql语句。要求给出完整代码,代码加上必要的注释。(请不要用正则匹配做题)
例如:已知 1)带有特殊标记的sql语句 select * from T1 where 1=1 and a &= :aa&&and (b =:bb or b =:cc) and e like :ee
? ? ? ? ? 2)前端传过来的参数有 aa= &111& , bb= &222&, cc= &333&,dd = &444&
? ? ?得到 select * from T1 where 1=1 and a &= 111 and (b = 222 or b = 333)
? * 用参数替换sql的特殊标记,如果标记对应的参数存在,则直接替换,如果不存在,要把对应的一段条件去掉,最后得出一个能用于查询的sql语句,返回能用于查询的sql语句。
? * @param labelSql 带有标记的sql语句
? * @param param 参数集合
能用于查询的sql
?public static String getRunnableSql(String labelSql,Map&String,Object& param){
也可大胆想像,如果参数中没有bb = 222,应该怎么处理?
完成了,请用如下情况去测试
1) sql: select T1.a,T1.b from T1 where 2=2 and (((a = :AA or B like :BB or c in :CC) and d in :DD ) or e && :EE) and f like :FF
2)参数:GG = &1223& , aa = &first&
最终得到 select * from T1 where 1=1&&
也测一下:有些标记有参数,有些标记没有参数,看最终结果是否正确
我想了很久最终还是没做出来,我把我的代码贴下,实现了替换,但是改变sql还是没有想到好的办法:
[Java] 纯文本查看 复制代码public static String getRunnableSql(String labelSql,Map&String,Object& param){
labelSql+=& &;
StringBuffer sql = new StringBuffer(labelSql);
//--------------start---------------
//以下代码是填充44行代码map数据的
// String -& labelSql字符串中的特殊标识
//List&Integer& -& 有2个下标,第一个是特殊字符在sql语句中的首下标,第二是则是尾下标
Map&String,List&Integer&& map=new HashMap&String,List&Integer&&();
int off = 0;
int next = 0;
int daEnd=0;
int end=0;
while(((next=labelSql.indexOf(&:&, off))!=-1)&&(
((end=labelSql.indexOf(& &,next))!=-1)|
(daEnd=labelSql.indexOf(&)&,next))!=-1)) {
end=end&(daEnd==-1?end:daEnd)?daEnd:
String key=labelSql.substring(next, end);
ArrayList&Integer& list = new ArrayList&Integer&();
list.add(next);
list.add(end);
map.put(key, list);
off=next+1;
//-----------------end-----------------------
for (Entry&String, Object& entry:param.entrySet() ) {
for(Entry&String, List&Integer&& sqle:map.entrySet()) {
//如果labelSql变量中的标识和用户发来的标识匹配成功
if(sqle.getKey().equals(&:&+entry.getKey())) {
if(sqle.getValue().size()&1) {
throw new RuntimeException(&下标出错大&);
//不管用户发来什么数据,最后转为字符串
String value= String.valueOf( entry.getValue());
sql.replace(sqle.getValue().get(0), sqle.getValue().get(1), value);
return sql.toString();
1. 将where条件以后的语拆分为:
2. 从上往下,依次使用下列规则入栈:[mw_shl_code=sql,true]select T1.a,T1.b from T1 where2=2
and //如果栈顶不是and或or,则and、or、(压栈
//如果栈顶(,且遇到and、or时,则语法报错
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
本帖最后由 WillingIce 于
15:01 编辑
1. 将where条件以后的语拆分为:
[SQL] 纯文本查看 复制代码select T1.a,T1.b from T1 where
B like :BB
f like :FF
2. 从上往下,依次使用下列规则入栈:[SQL] 纯文本查看 复制代码select T1.a,T1.b from T1 where2=2
and //如果栈顶不是and或or,则and、or、(压栈
//如果栈顶(,且遇到and、or时,则语法报错
a = :AA //如果有输入,则替换后压栈
//如果栈顶不是and、or,则and、or、(压栈
B like :BB //如果有输入,则替换后压栈
//如果栈顶不是and或or,则and、or、(压栈
//如果有输入,则替换后压栈
) //如果栈顶是(、or、and,则不压栈,并弹出(、or、and,否则压栈
//如果栈顶不是and或or,则and、or、(压栈
//如果有输入,则替换后压栈
) //如果栈顶是(、or、and,则不压栈,并弹出(、or、and,否则压栈
//如果栈顶不是and或or,则and、or、(压栈
e && :EE //如果有输入,则替换后压栈
) //如果栈顶是(、or、and,则不压栈,并弹出(、or、and,否则压栈
//如果栈顶不是and或or,则and、or、(压栈
f like :FF //如果有输入,则替换后压栈
//如果栈顶是or、and,则弹出or、 如果栈顶是(,则语法报错
3. 把栈中剩余的内容合并为一个sql语句的条件表达式。
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限100
貌似主要是sql查询相关的东西,和java关系不大
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
貌似主要是sql查询相关的东西,和java关系不大
是在java中,改传入的sql语句,但是不能用正则
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限35
前排围观 我也没有思路&&楼主能给个正则的思路吗
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
前排围观 我也没有思路&&楼主能给个正则的思路吗
题目说明不准用正则哦
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
本帖最后由 v 于
16:26 编辑
1. 将where条件以后的语拆分为:
[mw_shl_code=sql,true]select T1.a,T1.b from T1 where
思路很不错,但是怎么切割呢?
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
这不是MySQL的预处理吗。。。
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
[Java] 纯文本查看 复制代码public String getRunnableSql(String labelSql,Map&String,Object& param) {
StringBuffer sql = new StringBuffer();
sql.append( &select * from T1 where 1=1 &);
if(checkStr(map.get(&:aa&))) {
sql.append(&and a &=& + map.get(&:aa&));
if(checkStr(map.get(&:bb&)) || checkStr(map.get(&:cc&))) {
sql.append(&and (&);
if(checkStr(map.get(&:bb&))) {
sql.append(&and b =& + map.get(&::bb&));
if(checkStr(map.get(&:cc&))) {
sql.append(&and c =& + map.get(&::cc&));
sql.append(&)&);
return sql.toString();
private boolean checkStr(String param) {
if(param==null||&&.equals(param)) {
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
都是大神啊 什么都看不懂的小白路过
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
免责声明:吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。
( 京ICP备号 | 京公网安备 87号 )
Powered by Discuz!
Comsenz Inc.19:43 提问
PAT的一道简单的题目,用JAVA做的,请大神指点一下!
提交会出编译错误
identifier expected
ssr2[i]=aaa.[0]+ " " +aaa.[1];&
按赞数排序
题目是输出 名称和学号,代码是输出 名称 学号 分数
数组的错误吧?java可以这样定义动态数组么?难道是我记错了?
题目是输出 名称和学号,代码是输出 名称 学号 分数
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐史上面试最简单也是最难的一道java题:看大神程序员是如何操作的史上面试最简单也是最难的一道java题:看大神程序员是如何操作的最牛java程序员百家号小编前几天偶然看到一个新闻:一位java面试者在面试的时候,竟然只有一道面试题,就是当场用java写出坦克大战。最终获得月薪20k,他到底是怎么做到写出代码能获得这么高的月薪呢?小编为大家解读一下。个人觉得手写代码是一个很重要面试过程。一段代码,就代表着这个人。代码能直接体现他的价值观。下面看一下大神是如何写代码的。从这段简短的代码中,能看出来一位好的程序员的编程习惯。在写的过程中,至少能看出这些问题取名字,传参数是不是很随意。随意的取名是维护的噩梦。接口,函数设计能力。是解决具体问题,还是能解决一类问题,别的同事如何使用你的代码。思路是否清晰,代码结构是否层次分明。提笔之前,想清楚自己要干什么。代码可读性,可维护性。边界问题,细节处理是否合理。直接关系到这个人的bug率。打算如何测试自己的代码。对代码的责任心。写代码过程中和面试官的沟通次数。这个人的沟通能力和沟通欲望。面试中大家都说工资全靠吹,但是我们在公司最终老板还是要看写出来的代码是否高效有用。我们需要一眼能看懂并理解,没有人想去改编和管理一堆垃圾一样的代码。所以你知道为什么别人能拿到20k的工资了吗?再看看自己的编码规范。本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。最牛java程序员百家号最近更新:简介:一枚会编程的小鲜肉,哈哈哈作者最新文章相关文章一道简单的Java笔试题,但…… - 简书
一道简单的Java笔试题,但……
面试别人,对我来说是一件新奇事,以前都是别人面试我。
我清楚地知道,我在的地域与公司,难以吸引到中国的一流软件人才。所以,我特地调低了期望,很少问什么深入的技术问题,只问一些广泛的、基础的。我只要最终给Leader一句“这个人技术还行/很好/非常好”,就行了。至于其它能力、综合水平,由别人把关。为此,在挑选唯一的一道笔试题时,我特别地上心。
首先,我不敢用网上那些广为流传的,比如Leetcode、《程序员面试宝典》里的题——这些都太难了!正儿八经做,其实很少有人能在1小时内完美做出来,除非之前遇到过。我本人也并非什么思维敏捷的牛人,不然也不会混得这么惨。正所谓己所不欲,勿施于人,我也不希望以后别人考我特别麻烦的算法题,所以自创了一道特别简单的。
其次,对(Android平台的)Java程序员来说,大多数情况下不需要写什么复杂的算法。相反,Java层主要做的是界面控制、业务逻辑、数据流之类的,更提倡代码的简单和可读,尽量用既有的公共类库,不惜损失一些运行效率。拿一道复杂的算法题,考一个Java程序员,多少有点刁难人。
最后,还是那个薪资待遇和人才梯度问题。没有Google的工资,就别考Google的题;没有Google的向心力,就别期待有Google级别的人才来面试。
以下有一个static method,类外会调用它,一个个地插入一些元素进入一个List。可以改变这个List内容的,只有这一个method,要求任何时候这个List都是有序的。
比如,依次插入3、2、1、2,我希望List的顺序是1、2、2、3。
class Solution {
private static List&Integer& sSorted = new LinkedList&&();
public static void addElement(int e) {
// TODO: Insert e to sSorted and make sure sSorted is always sorted.
我会给出15分钟的时间,而其实往往会再多给10分钟。
(有兴趣,你可以停在这试试。相信在看文章这种轻松的环境下,理清这道题的思路也就10~30秒。)
(为什么下限是10秒呢?唉……一不小心暴露了我智商的峰值。我实际问过一些同事,他们通常在理解的同时,就立刻给出了正确的思路,过程不足5秒,其中甚至包括一个硬件工程师,和一个只负责沟通和文档的妹子。)
在过程中,我会逐步给出一些提示,从接口到思路,都会主动提供,其它也基本有问必答。
如果单纯考算法,C语言才是最合适的,因为它没有什么高级的工具类,什么复杂点的都得自己写。而Java,则有一些“基础”类库是难以记忆的。比如前面出现的java.util.List,就没有多少人能在纸上写出它的常用接口。
我并不想考察什么死记硬背,在这个时代,断网后本来就没几个程序员能正常编程。所以我会主动提供一份List的不完全接口列表。
public interface List&E& extends Collection&E& {
public void add(int location, E object);
public void add(E object);
public void clear();
public boolean contains(Object object);
public boolean equals(Object object);
public E get(int location);
public int indexOf(Object object);
public boolean isEmpty();
public E remove(int location);
public E set(int location, E object);
public int size();
我没有给出完全的接口,因为给多了无疑是误导人。真正能用上的接口其实也就3个,但我也总不能只给3个,提示得太明显,也限制了对方的思路。所以,给出了可能用得上的这几个。我也没给出注释,因为有声明就已经够了。而且如果对方问起,我也会给出解释。
一开始我想,考一个排序算了。但是转念一想,这也太不负责任了。对面要是背一道冒泡排序的解法上来,达不到考察技术水平的目的,Boss也不会认可。本着“放水不能太明显”的原则,我想考插入排序,并且把题目弄得没多少人见过。
排序是一类基本算法,合格的程序员至少会一种。大多数人都只会入门级的冒泡排序,而我更喜欢插入排序,原因……你会明白的。
插入排序,其实就是把数组或列表在逻辑上分成两部分,一部分是待排序的,一部分是有序的。一开始,有序的部分只有一个元素(或者一个都没有),然后从待排序的部分里一个个抽出来,插入到有序的部分。等元素都插入到了有序的部分,排序过程也就完成了。
你看,也就抽插N次的事。而我这道题,就是只考插入排序算法的一半,会插就行。
在面试过程中,我甚至常常亲自解释插入排序是怎么回事——放水到这个份上,我都不忍心再退步了。
真正的考察点
这是一份Android平台的开发工作,Boss要求的是能干活、干好活。我给出的建议要求是:
熟悉Java。
有良好的沟通、表达能力。
学习能力强,喜欢不断拓展计算机领域的知识。
有良好的编码习惯,愿意为代码的简洁、优雅而反复修改。
我建议Boss放弃学历和工作年限的要求,技术岗位就应该只考察技术(和其它基本能力),不应该考察技术的间接证明。
Java是Android的基本功(我们不玩Kotlin、Scala、React Native等新花样),这门语言如果不扎实,那至少得带半年。
我没有在Android岗明确地要求考察Android,是因为Android的那些东西相对来说容易学习。即便是毫无经验的新手,要搞清楚什么“四大组件”“五大布局”,也就一两天的事。而如果Java不够扎实,各种肉眼可见的大小bug就会层出不穷,知识盲点一两年都补不完。
沟通是职场基本功。如果话都说不清,那么会显著降低团队的沟通效率。而且,我个人认为,话说不清的人,代码一定写不好。语言条理清晰,逻辑层次分明,体现到代码上,就是简洁、明朗。
学习能力、求知欲,是作为一个程序员的基本素养。因为,大部分人的工作,类似于在一堆按钮中,找到合适的那个按下去;而程序员的工作,往往是闭着眼睛这么干。开发工程师通常是在一堆未知(没读过的代码、不知道的接口)中,把一小部分变成已知(读懂了的代码或接口),进行一些增删改,最后达成外界(产品经理、设计师、测试工程师)赋予的业务目标。
一些职业卖口水,一些职业卖口才。一些职业卖青春,一些职业卖肉体(咳咳,我说的是空姐和搬砖,想歪的去面壁)。一些职业卖知识,一些职业卖能力。
程序员,或者说软件开发工程师,卖的是学习能力(其实也包括青春和肉体),快速学会各种知识,找到那些藏在屏幕外的按钮,并且正确的按下去。
比如,像Bash这类Command line工具,就是自己敲命令出来执行,而不是去界面上找功能对应的按钮;而程序设计、实现,就是去发现、或者创造一种解决问题的办法,然后用代码表达出来——你看,都是在干一些反UI、UX设计的事。唯有不断地学习,才能提高效率,把自己从加班中解脱出来,把项目从bug中拯救出来。
所以,厌学的人当不了好程序员,也干不长。
编码习惯,相对次之。部分观点认为,这东西伴随一生,如果一开始没有好习惯,这辈子都没办法改了。Boss就是这么认为的,我倒是不这么认为。我相信编码习惯的可塑性是很高的——你不按规范写,我不给你merge,改不改?
但是,编码习惯作为程序员的软技能,还是可以一定程度上看出其技术素养、代码质量的。至于优雅什么的,我其实没有真的敢这么期待。
所以,我这道题其实是考察这四点。
能写出来,并且无明显问题,代表Java基本功扎实。
理解我对题目的描述,和我确认清楚题目的细节,这是看沟通能力。
List接口不知道,我给你啊;插入排序不会,我教你啊;其它还有什么不会,你问啊——这是在考察学习能力。
代码的字里行间,可以明显看出编码习惯。
总体来说,我很伤心。
第一位就让我很伤心,当我看了他前两行代码,就不忍心接着往下看:
private static List&Integer& sSorted = new LinkedList&&();
public static void addElement(int e) {
if (null == sorted) {
sorted.add(e);
// I couldn't read more!
第一行就编译不过。如果他对Java的一些命名规范有一定的了解,就绝不会把sSorted写成sorted。(当然,sSorted也许并不是合适的命名方式,因为s和m这类前缀有些冗余。我通常遵守Android源码的通用规范,它是有这类前缀的。)
第二行必然抛出NullPointerException,而不知道是该庆幸还是悲伤的是,它永远执行不到。根据我已经给出的一个接口addElement,和可以猜到或者问出来的读取接口,都是不会把sSorted变成null的。这体现了沟通、理解能力的一点问题。
此外,即使sSorted因为什么bug而变成null,这里也不应该做处理,而是任其抛出NullPointerException,或者转义一下,主动抛出IllegalStateException。否则,此处将变成一个不会crash的隐藏bug。不能用正常处理,代替异常处理;当然,也不能用异常处理,代替流程控制。
另外,更令我失望的是,有一位是这么写的:
for (int i = 0; i & sSorted.size(); i++) {
if (e == sSorted.get(i)) {
sSorted.add(i, e);
我问他,如果这个元素不在这个List里存在怎么办?如果这个List是空的怎么办?他顿时一囧,我也一起囧,心想自己是不是太坏了。
还有一位,仿佛听见了我这几个问题,他竟然一一作答:
if (sSorted.size == 0) {
sSorted.add(e);
if (e &= sSorted.get(sSorted.size - 1)) {
sSorted.add(e);
if (e &= sSorted.get(0)) {
sSorted.add(0, e);
if (sSorted.contains(e)) {
sSorted.add(sSorted.indexOf(e), e);
// more...
他想干什么呢?也许是优化性能吧,只能这么帮腔了。另外,他对size的理解,和数组的length相同。
这位算是经验比较丰富(30岁),对Java的理解比较深入的了。他说排序不需要手写,Java里有现成的接口。我说,是这样没错,但接口我没给出,如果你记得,那就写出来吧。
于是他在刚才那一大段“优化”的后面,这么写了:
sSorted.add(e);
sSorted.sort(new Comp...able() {
public boolean ?(left, right) {
return right &=
思路上,插入后再排序,我先不吐槽。我明明说了“记得”再写,这Comparable及其接口int compareTo(T another)如果记不清,我就当看lambda表达式了。可是,他这个?分明是Comparator的int compare(T lhs, T rhs)接口呀!
不过,其实这些我都可以捏着鼻子认了,因为我也手写不出来。但List是没有sort方法的呀!
Arrays和Collections才有各自的sort方法,它俩算是银弹型工具类,而Array和Collection是没有的。这个细节,谁用谁知道,知道了就绝不会记错,尽管就差一个s。
还有一位,他先插入、再冒泡排序,是这么写的:
sSorted.add(e);
for (int i = 0, sSorted.size(i) & sSorted.get(e), i++) {
temp = sSorted.get(e);
sSorted.get(e) = sSorted.size(i);
sSorted.size(i) =
你没看错,for()里面是,分隔的。
你没看错,temp是从石头缝里蹦出来的。
你没看错,List.get(e)是可以对其赋值的。
你没看错,List.size(i)是可以传参数进去的。
还有两位,直接交白卷放弃了。
其中一位还比较认真,思考了一会儿,说“我不想浪费时间”。
我没乱用词,他确实“比较认真”。另一位在我递过去后,直接看两眼就递回来,“排序我不会”,然后看手机去了。
o(╯□╰)o
我自己在纸上写的时候,花了大概5分钟去思考细节,再花5分钟写出来。(唉……一不小心,又暴露了自己奇慢无比的思维,以及奇慢无比的写字速度。)这比我此前预计的时间多了好几倍!
不过,以我给的15~25分钟,应该不算太难为人……吧?
class Solution {
private static List&Integer& sSorted = new LinkedList&&();
public static void addElement(int e) {
for (i = 0; i & sSorted.size(); ++i) {
if (e &= sSorted.get(i)) {
sSorted.add(i, e);
这是我自己在纸上写的答案。
(如果有兴趣,可以停在此处,考虑下这是否是最优算法。)
public E get(int location) {
if (location &= 0 && location & size) {
Link&E& link = voidL
if (location & (size / 2)) {
for (int i = 0; i &= i++) {
link = link.
for (int i = i & i--) {
link = link.
return link.
throw new IndexOutOfBoundsException();
这是java.util.LinkedList在Android(API 23)上的实现,而反编译Oracle JDK 1.8的实现也大同小异。
也就是说,我写的答案虽然看似简洁,但其最坏时间复杂度与先插入再排序也没太大区别,都是O(n2)。
终日打燕,反而被燕啄了眼!(暴露了真实水平。)
我后来又写了一个参考答案,算是勉强在脸上摸了些防晒霜。
(大家有兴趣可以想想为什么这是一个改进。当然,一定还有更好的方案。)
class Solution {
private static List&Integer& sSorted = new LinkedList&&();
public static void addElement(int e) {
int i = 0;
for (int j : sSorted) {
if (e &= j) {
sSorted.add(i, e);
(我没有在提示列表中给出迭代器,结果自己也被晃过去了。)
隐藏的杀手锏
面试官在出题考察应聘者时,应聘者也在通过这道题考察这家公司。
为了避免让人觉得这家公司考题太简单、工作内容太无趣、里面的员工(我)水平太低,我还准备了一些后续问题,由浅入深,作为杀手锏。
为什么LinkedList可以赋值给List?
考察多态(polymorphism)。
为什么List&Integer&要写&&内的内容,而LinkedList&&()可以不写?
考察泛型(generic)。
为什么List里面是Integer,但放进去和拿出来的都是int?
(此处有坑,其实拿出来的还是Integer。)
考察基本数据类型的自动装箱、拆箱(auto boxing/unboxing)。
如何在外面有多线程调用时,保证这个唯一的List的正确性?
考察synchronized和volatile。
如何在多线程状态下的每一个线程,各保持一个独立的List?
考察ThreadLocal。
(当然,还有一些和Android相关的问题。)
我真心是没想考算法,所以连算法复杂度的评估都没打算问。
实际情况是,我往往没有机会问这些问题,因为没几个人写出来。
吐槽与建议
首先,喷一下大学扩招……算了,不扯这么远了。
那两位放弃做题的,一个是计算机学院的,一个是软件工程学院的。排序写不出来,竟然也是能毕业的!
有两位是某App的开发者。我把他们的App下载下来,发现了一堆bug后,本来想忍忍、就当没看见、码农何苦为难码农,然后手机发热、卡顿、灭屏后几乎点亮不了(内存泄露吃光了RAM,导致系统进程没有内存可用)。过了一阵最终好了,我查看耗电排行,运行10分钟就高居榜首,耗了17%的电——我吓得立刻卸载了。一个第三方App能把系统给卡成这样,一般人还真做不到。
还有两位是“相关专业”的,非计算机、软件工程专业,反而表现最佳,虽然还是没写出来。
他们无一例外,都是在大学以外,又参加过某些Java、Android培训的。这些培训班的水平,可见一斑。问题倒不一定是培训班的教学质量,而是这种大规模提供人才转型服务的形式本身——这个世界上,本来就不是谁,都能当一个好码农,哪怕工作要求只是复制粘贴。
现在,很多码农都戏称自己是在“搬砖”、复制粘贴,但实际上程序员的工作不可能仅止于此。使用别人写好的基本算法,参考别人的实现代码,只是为了集中精力去解决抽象层次更高的业务问题。
“我们不写代码,我们只做代码的搬运工。”——万万不可把这句话当做信条。
还有很多人,在没有Demo的情况下,无论给多么详细的API或其它资料,仍然无法写代码。他们只能在既有的基础上,修修补补,无法凭空创作。
我推荐三本Java的基础书:
《Java编程思想》(Think in Java)
这本是最合适的Java语言入门书。其它很多语法书都是从C/C++的角度来讲Java的变化,或者从C++的思路来讨论Java怎么用,而这本书的英文名则直接告诉你,请用Java来思考、解决问题。
《Effective Java》
Java中有很多坑,Java中也有很多糖。如果没有看过这本书,那么不知不觉就会犯很多大忌。
《代码整洁之道》(Clean Code)
我是在独立写一个小项目的时候开始看的。看到一半时项目也写到一半,顿时连代码都不会写了!每天都在写自己看不下去的代码,而不知道怎么写能看得过眼的。加速看完后,重新开始会写代码。最终,项目后半部分的代码,和前半部分完全不同,不像一个人写的,我后来又重构了一遍。
(为什么我不多推荐点书呢?一来,是我本人也没看过多少,囧;二来,三本是极限,根据我的经验,推荐三本可以让人看一本,推荐三本以上,受众一本也不会看。)
我有一个朋友,也是一个前同事,好学如好色。他周末都在找一个大学教室看书,甚至有时请年假去教室看书。一本《Java编程思想》,逐行精读三遍以上。工作经验不足两年,跳槽三次,现在在一家百亿级上市公司,年薪三十万,统率十人。
究其原因,无非基础知识扎实,口水喷死面试官尔。
我作为一个面试别人的初哥,一心只想着自己喜欢的抽插……呃不,插入排序算法,给别人造成了不必要的麻烦,只能说抱歉了。
和我一起面试的,还有一个负责文档和规范的妹子(前面提到过的那个)。她也是有一票否决权的,而且用得比我更频繁!
我最多只给交白卷的,和那个耗电超恐怖的App,这几个人直接否决。而这个妹子,考察对方的其它综合能力。
在实际工作中,她是需求的接口人,我们需要和她沟通,实现各方对我们团队的需求。所以,只要她说一句“我和这个人难以沟通”,那么Boss基本上就直接拒绝了。
下次我还是换一道更简单的吧,码农何苦为难码农。
底层码农一枚。
我在简书的所有首发原创文章,默认遵守以下协议:
1. 简书用户协议
http://www.jianshu.com/p/c44d171298ce
2. 署名-相同方式共享 4.0 国际
https://creativecommons.org/licenses/by-sa/4.0/
非首发于简书的转载文章,则谢绝再次转载。
可以通过文首或文末的原文链接,遵循原文的协议转载。
Java 基础思维导图,让 Java 不再难懂 - 工具资源 - 掘金思维导图的好处 最近看了一些文章的思维导图,发现思维导图真是个强大的工具。了解了思维导图的作用之后,觉得把它运用到java上应该是个不错的想法,这样回顾知识点的时候一目了然,快速知道自己的短板。 思维导图...
1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io的语法,虚拟机方面的语法。 1、一个&.java&源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个publ...
百战程序员_ Java1573题 QQ群:034603 掌握80%年薪20万掌握50%年薪10万 全程项目穿插, 从易到难,含17个项目视频和资料持续更新,请关注www.itbaizhan.com 国内最牛七星级团队马士兵、高淇等11位十年开发经验专...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金 相信有很多...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
B男与B女在越南旅游时认识,一夜情之后发现彼此在同一个城市工作与生活,一夜情变成了长久的性伴侣。 B男已婚有孩,B女有同居男友,准备结婚。B男带B女去自己牌友的局,介绍B女为表妹。 B女称两个人的关系是缘份,B男对牌友说:因为便宜,几百块的衣服就能收买了。 这就是男女之间的...
或许大多数人看到这个题目,脑海中自然而然就会想到:为了成功,为了证明自己,为了更好的物质生活,为了实现梦想!除了这些在仔细想想,拼搏的意义到底在哪里?还是这些肤浅的答案吗?
偶然间看到了一档综艺节目,里面讲述的是爸爸带孩子的故事,当然除了妈妈之外。古往今来好像咱们中国的...
谈了一场轰轰烈烈,让微博系统都瘫痪的恋爱,鹿晗和关晓彤,除了让媒体从业者提早一天上班,还让微博的网络工程技术人员提前结束长假。 今天的朋友圈,不知道被刷了多少起源于鹿晗的“大家好……”格式。各种能轻松调侃的都是抠鼻吃瓜的路人甲,众多被切了心头肉“老公粉”更多是震惊、愤怒和黯...
周六,空气清度污染,温度有些低,风偏大,知道今天不是一个适合在户外玩耍日子。虽然蓝天白云有些久违,果断选择和姑娘在室内活动。 跳舞结束后,去了一趟医院后,医生说,姑娘可以不用顾及太多这样那样不能吃的东西,西医没有这套理论。于是乎,大开绿灯,吃了薯片,虾片和各种饼干,有了医生...
移床终拟醉, 解带懒归耕。 江湖一重弦, 心空入竹声。

我要回帖

更多关于 这道题没有那道题简单 的文章

 

随机推荐