分类目录归档:程序开发

关于前端面试

摘自:https://mdluo.github.io/blog/about-front-end-interview/

继上一篇 关于程序员求职简历 之后如果顺利的话就应该是面试了,在此也整理一下最近在网上收集的前端面试相关资料,包括预备知识、书籍、面试考点、面经等。前端方面资料其实太多太多,就光从知乎、前端乱炖、w3cplus 等网站就能找到很多,所以针对细节不发散,仅挑一些内容丰富的合集,更多的资料可以从其中找到。

1. 前端团队

参考我整理的列表(部分维护了网站、技术型前端团队): 国内知名前端团队

2. 知识技能

前端技能汇总 Frontend Knowledge Structure (源码)(朴灵,阿里巴巴)

大前端的瑞士军刀,只记录有用的源码)(聂微东,百度)

前端收集(罗磊,腾讯阅文)

知乎上前端开发领域有哪些值得推荐的问答?——知乎

2015-2016前端知识体系图谱(w3ctech)

前端收藏夹源码)(w3ctrian)

QQ联盟群交流(492107297)群规(有大量的教程、资料、面试题)(豪情)

3. 学习路线、书籍

前端开发者手册(Pomy,美团)

有哪些关于前端开发技术(HTML、CSS 和 JavaScript 等)的值得推荐的书籍?(李路,Knewone)

前端路上的旅行(大漠,淘宝)

Developer进阶书单(phodal,ThoughtWorks)

年后跳槽如何准备?(豪情)

学习前端的这一年(Helkyle @ w3ctrian)

零基础的前端开发初学者应如何系统地学习?——知乎

4. 面试考点、面经

写给前端面试者(大漠,淘宝)

谈谈面试与面试题谈谈面试与面试题 II (winter,淘宝)

互联网公司技术岗实习/求职经验(实习内推+简历+面试+offer篇)(张秋怡,阿里巴巴)

史上最全 前端开发面试问题及答案整理(trigkit4,口袋购物)

最全前端开发面试问题及答案整理(AutumnsWind)

前端开发面试题(马云云,ZTE)

收集的前端面试题和答案(邱德清,阿里妈妈)

web前端面试相关的知识点(王文杰,乐视云)

2016十家公司前端面试小记(沧海)

一道常被人轻视的前端JS面试题(沧海)

Web前端开发测试题(大漠,淘宝)

常见前端面试题及答案(默语,腾讯)

前端工作面试问题(一)(Ruipeng Zhang,哈工大)

面试经验分享之数据结构、算法题(Song Chengru,清华)

名企笔试(伯乐在线)

如何面试一名前端开发工程师?(芋头,大搜车)

国内大型互联网公司(如BAT)对于web前端开发方向校招都考些什么?——知乎

如何面试前端工程师?——知乎

初级前端面试需要带什么作品?——知乎

5. 网站、专栏、周刊

前端开发 —— 知乎

前端 —— 稀土掘金

前端乱炖

w3cplus

w3ctech

前端开发博客

前端观察

前端De早读课

前端大全 —— 伯乐在线

前端 —— 开发早读课

imweb前端社区

奇舞周刊

精华 —— CNode社区

web前端开发 —— segmentfault

发现:前端 —— 开发者头条

6. 前端新技术

谈谈前端『新』技术(尤雨溪,Meteor)

为什么整个互联网行业都缺前端工程师?(100offer)

近几年前端技术盘点以及 2016 年技术发展方向(小胡子哥,淘宝)

如何跟上前端开发的最新前沿(GitHub)

HTML的BUTTON标签

调试一个JavaScript的程序,相当郁闷(花了不少时间),虽然问题不经意间解决(哥的运气还好~),但还不知道所以然。

简单叙述下该场景:

JS代码(Ajax):

<script>

function search(item) {
items = item.forms.elements;
Ajax.call(…..);
}

</script>

HTML代码:

<form actioin=”javascript:;” method=”post”>
<button onclick=”search(this)”>搜索</button>
</form>

以上是简化的模拟场景。一直跟踪到XMLHttpRequest的onreadystatechange方法,检查到status为0,Firefox给出的提示是:Firefox不知道如何打开此地址,因为协议(Javascript)未知任何程序关联。

用了好多test确保程序无误,但在以上情况下就通不过。当快要绝望的时候,我把button这个HTML标签,加个type=”button”。噢嘢!运行成功。坑爹的!

PS:<button> 控件 与 <input type=”button”> 相比,提供了更为强大的功能和更丰富的内容,所以一开始用了button,没想到这里被“调戏”了下~

.NET 中的哈希碰撞漏洞

哈希冲突攻击的方法是试图将大量数据填充到哈希表内,导致其键值可能存在重复的问题。这些键值的碰撞,大大减缓对哈希表的操作,并且足够多的元素也导致服务器处理它们需要花很多的时间,几分钟(甚至几小时)。这可以阻止Web服务器处理来自其他用户的请求,并导致拒绝服务(这意味着该网站变得反应迟钝或缓慢)。

微软如何处理这个问题呢?

微软在2011年12月29日发布一个更新补丁,该补丁可限制每个 HTTP POST 请求最多包含 1000 个表单域。一旦你更新了这个补丁,那么你的表单不能过超过1000个表单字段,如果超过将会抛出如下异常:

System.Web.HttpException:
The URL-encoded form data is not valid. ---> System.InvalidOperationException: Operation is not valid due to the

current state of the object.
   at System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded()
   at System.Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding encoding)
   at System.Web.HttpRequest.FillInFormCollection()
   --- End of inner exception stack trace ---
   at System.Web.HttpRequest.FillInFormCollection()
   at System.Web.HttpRequest.get_Form()

关键内容是 ThrowIfMaxHttpCollectionKeysExceeded. 如果你发现有这个字符串表示表单域超出了限制,你可通过修改 web.config 来修改这个限制值:

<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="some number here"/>
</appSettings>

英文原文,OSCHINA原创翻译

PHP客户端使用.NET发布的WEB服务

Web服务相关知识在此不叙述,还有保证PHP SOAP扩展已开启。

.NET发布Web服务相当容易。步骤简单叙述如下:

1)在Visual Studio环境(2010为例)的资源管理器,右键点击网站项目,然后选“添加web引用”,弹出如下图框:

2)因为本地测试,选择“此解决方案中的Web服务”,然后选择已经建立好的.asmx文件(在此以Service.asmx为例)。

3)到此便建立好Web Service服务。例:http://localhost:3395/WebSite2/Service.asmx

App_Code/Service.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

///
///MyWebService 的摘要说明
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
//若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
public class Service : System.Web.Services.WebService {
    public Service () {
        //如果使用设计的组件,请取消注释以下行
        //InitializeComponent();
    }

    [WebMethod(Description = "This is a test"]
    public string getName(string name) {
        return "This is " + name;
    }
}

 

现在由PHP SOAP扩展使用该Web服务:

$wsdl = "http://localhost:3395/WebSite2/Service.asmx?wsdl";
$client = new SoapClient($wsdl, array('trace' => true));

// 传递函数
$params = array('name' => 'php');
$ret = $client->__soapCall('getName', array('parameters' => $params));

echo $ret->getNameResult  // 最后打印: This is PHP

因为不同的程序通信,这里必须用soapCall()方法调用一个SOAP操作。调用后可以在WSDL(http://localhost:3395/WebSite2/Service.asmx?wsdl)查找其自动产生的属性或方法。

PHP 5.4.0 正式版发布

PHP开发团队很荣幸的宣布PHP 5.4.0的发布。这个版本在5.x系列基础上有很大的飞跃,此版本包括很多的新的功能,同时也修复了许多的bug.

一些主要的功能包括:traits缩短数组语法特性(a shortened array syntax)用于测试的内置web服务器(a built-in webserver for testing purposes)。PHP5.4.0显著的提高了性能和内存,修复了超过100个的bug.

PHP解析大型XML文档

PHP中有两种主要的XML解析器

1)基于树的解析器。它是把整个文档存储为树的数据结构中,即需要把整个文档都加载到内存中才能工作。所以,当处理大型XML文档时候,性能剧减。SimpleXML和DOM扩展属于此类型解析器。

2)基于流的解析器。它不会一次把整个文档加载到内存中,而是每次分别读取其中的一个节点并允许实时与之交互(当移向下一个节点时,上一个节点是被丢弃,但也设置为保留)。很明显,其效率要高且占内存少,不便之处代码量大点。

所以,PHP中处理大型XML文档可以用XMLReader扩展方案(基于流的解析器)。它在PHP 5.1中默认是启用的。

举例:

// 创建对象
$reader = new XMLReader();

// 从一个文档或URL中加载XML数据
$reader->open('filename.xml');
// 或从变量加载
$reader->XML($document);

// 遍历
while($reader->read()) {
  // statement
}

XMLReader节点类型值:

节点类型说明
XMLReader::NONE非节点类型
XMLReader::ELEMENT开始元素
XMLReader::ATTRIBUTE属性节点
XMLReader::TEXT文本节点
XMLReader::CDATACDATA节点
XMLReader::ENTITY_REF实体引用节点
XMLReader::ENTITY实体声明节点
XMLReader::PI处理指令节点
XMLReader::COMMENT注释节点
XMLReader::DOC文档节点
XMLReader::DOC_TYPE文档类型节点
XMLReader::DOC_FRAGMENT文档片段节点
XMLReader::NOTATION符号节点
XMLReader::WHITESPACE空白节点
XMLReader::SIGNFICANT_WHITESPACE显著空白节点
XMLReader::END_ELEMENT结束元素
XMLReader::END_ENTITY结束实体
XMLReader::XML_DECLARATIONXML声明节点

XMLReader节点的类型值:

名称类型说明
attributeCountint节点的属性
baseURIstring节点的Base URI
depthint节点的树结构深度
hasAttributesbool节点是否包含属性
havValuebool节点是否包含文本值
isDefaultbool属性值是否来自默认的DTD
isEmptyElementbool节点是否是一个空的元素标签
localNamestring节点的本地(local)名
namestring节点的资格(Qualified)名
nameSpaceURIstring与节点相关的名称空间的URI
nodeTypestring节点的节点类型
prefixstring与节点相关的名称空间前缀

Java工程师可能不知道的那些FE潜规则

写了一个多月JavaScript,感觉如今可不比几年前只有IE6的年代,而且过去只是用JS写个Ajax或者是简单的表单验证,可如今写一个稍微复杂点的小应用,要兼容所有浏览器,才发现真是太难了,难怪FE是一个独立的工种,有别于我们这些Java工程师了。

1 首先是最简单的select标签,就有诸多不兼容:

A、 cloneNode方法,对于非IE浏览器没有问题,对于IE浏览器,我遇到的问题包括:
1)option selected的会clone不过去,然后会将第一个option作为selected值
2)事件clone也会有问题

B、Readonly:对于IE6,可以通过以下方法将select设为readonly:
obj.onbeforeactive=function(){return false}
obj.onfocus=function(){obj.blur();
obj.onmouseover=function(){obj.setCapture();}
obj.onmouseout=function(){obj.releaseCapture();}
对于其他浏览器,我采用的是元素替代法,动态创建一个input标签,把值赋给它,然后将select隐藏。

C、select的z-index对于IE6无效,网上有很多关于这个讨论,JQuery采用一个iframe搞定

D、动态添加option的方法不同,这个网上一搜一大堆

E、对于onclick和onchange的响应不同,在FF下可以在onclick select时动态读取option值然后构建option,然后选中一个值后执行onchange事件,但是IE下不能这样做。

2 css对offsetWidth之类的理解不同 – http://newleague.iteye.com/blog/765535

3 对于vertical-align baseline的理解不同 – http://w3help.org/zh-cn/causes/RD1016

4 设置背景色
element.style.backgroundColor
在firefox下想改变颜色,必须先设为null,再设为其他颜色才行,即先取消原来的颜色。
在IE下,想取消颜色,必须设为”才行,而换其他颜色,无需先去掉之前的颜色。

5 不同浏览器去padding的理解不同

6 不同浏览器对强制换行和强制不换行的理解不同 – http://www.cftea.com/c/2009/01/QPDZU40MNW8FYYG3.asp
最恶心的是对于IE6,如果是<td><span>我是蚊子</span></td>,那么在td上写了word-break:keep-all依然无效,必须在span上也写。

7 获得head节点的方式不同
在Firefox下可以用window.head,而所有浏览器都兼容的方式是document.getElementsByTagName(‘head’)[0]

8 往head上添加css code的方法不同,也就是动态添加<style>标签。
IE下可以用var style=document.createStyleSheet();style.cssText=cssCode;而有文章说,在Windows上的IE,用createStyleSheet返回的是styleElement的styleSheet,而在Mac上返回的是styleElement自己。在其他浏览器下需要document.createElement(‘style’); 然后还有区分是否具有styleSheet属性。

9 对于onchange事件,firefox浏览器可以注册在table,div等组件上,然后通过冒泡,拦截input,select等发出的事件,而IE不行,必须绑定到相应的组件上

10 将input设为readonly=true,其依然会响应keypress,keyup,keydown,onblur事件

11 IE和非IE对于停止冒泡和取消默认行为的方法不同

12 大家都知道IE和非IE在动态添加事件时使用的方法不同,IE是attachEvent,其他是addListener,然后参数也不同。更重要的是如果一个控件绑定了多个function,他们绑定和执行的顺序是不同的,IE是跟绑定顺序相反,其他是跟绑定顺序相同

13 获得当前事件不同,一个是window.event一个是直接接受event

14 FF下执行offset系列非常慢,但是IE下比较快,而IE的改变CSS的执行非常慢。
Firefox6比Firefox3.6速度快的多,相差好几百倍(针对一个400行*50列的表格的JS处理)

15 如果大量动态改变css,那么使用document.createDocumentFragment,然后将需要修改样式的Dom获取出来appendChild到这个临时的fragment上,修改完css后再append回去即可,这样性能能差好几百倍。

16 浏览器加载网页时,顺序读取html,遇到外部js链接会读进来,然后按顺序执行,边解释边执行,而对于外部css,图片等则是启动另外的线程连接服务器去获取。
IE对于CSS引入有限制,我没试过,但有篇文章讨论:http://blog.csdn.net/ydshang/article/details/4158211

17 表格定位某一行,可以通过改变scrollTop来实现,当然如果出现了滚动条的话

18 IE的Dom用完要记得释放,可以在unload方法中,否则会出现内存泄露

19 unload方法在各个浏览器里各不相同,我之前的文章里有介绍。http://sslaowan.iteye.com/blog/1128209

20 我知道了为什么FE最喜欢的浏览器是FF,最讨厌的是IE6,恨不得IE6去死,其他IE也不怎么样。但是Chrome,Opera也各有各的bug

21 Ajax当使用同步模式时,如果访问的链接是错误的,那么FF会在控制台报错,而IE会直接弹出个对话框,然后就崩溃了。

22 FF支持document.getElementsByClass等方法,IE不支持,可以自己写一个。

23 trim方法在IE和FF下不同,需要自己写一个,可以用正则表达式

24 动态设置元素的css class在IE和非IE浏览器下也不同

25 有时本地字体库会影响你的字体,大小等显示,但是有时甚至会影响你的布局

26 字符串也可以使用><等符号比较大小,但是是字符串比较,不要被骗了

27 JS中this问题非常让人困惑

28 判断浏览器可以有很多方法,主流是两大类,agent判断法和特性法,后者好像更推荐

29 JS是面向对象语言,对象.属性=值 只影响当前对象,而对象.prototype.属性则影响整个类。非IE浏览器可以覆盖DOM对象的类方法,但是IE不行。

30 getComputedStyle,获得外部添加的css,FF支持,IE不支持,具体看这篇文章 http://www.jb51.net/article/16128.htm

31 IE和Chrome支持outerHTML方法,其他浏览器没有。相关讨论:http://walsh.iteye.com/blog/261966http://stackoverflow.com/questions/1700870/how-do-i-do-outerhtml-in-firefox

32 还有一个特悲剧的,IE下会把document.[formname.]控件Id当成那个控件,如果把一个控件比如input的id设为了submit,那么form.submit()就会报错。

33 如果利用全角空格进行布局时,Firefox支持,而IE会去除只剩一个,但是是在某些情况下的,具体看这篇文章:http://w3help.org/zh-cn/causes/BT1025

34 透明度:
filter:alpha(opacity=0); /* IE */
-moz-opacity:0.3; /* Moz + FF */
opacity: 0.3;

至于用不用var的区别,undefined和null的区别,Ajax构建的不同方式,这些一般的Java程序员都了解了。

很多Java程序员也会使用JS框架,比如JQuery,Extjs和Dojo,她们都帮我们屏蔽了很多兼容性问题。Dojo提供了Java一样的面向对象机制。

抛砖引玉,你还遇到过什么陷阱,那些FE都知道,而我们Java工程师不知道?

原文:http://sslaowan.iteye.com/blog/1156214

Ecshop的MySQL类autoReplace()方法重写

如题:

    // autoReplace
    public function autoReplace($table, $field_values, $update_values, $where = '')
    {
        $field_descs = $this->getAll('DESC ' . $table);

        // primary key | fields
        $primary_keys = $field_names = array();
        foreach ($field_descs as $value) {
            $field_names[] = $value['Field'];
            
            if ($value['Key'] == 'PRI')  {
                $primary_keys[] = $value['Field'];
            }
        }

        // action fields
        $fields = $values = array();
        foreach ($field_names as $value) {
            if (array_key_exists($value, $field_values) ) {
                $fields[] = $value;
                $values[] = "'" . $field_values[$value] . "'";
            }
        }

        // sets
        $sets = array();
        foreach ($update_values as $key => $value) {
            if (array_key_exists($key, $field_values) ) {
                if (is_int($value) || is_float($value)) {
                    $sets[] = $key . ' = ' . $key . ' + ' . $value;
                } else {
                    $sets[] = $key . " = '" . $value . "'";
                }
            }
        }
        
        // not exists primary key
        if (empty($primary_keys) && !empty($fields)) {
        	$sql = 'INSERT INTO ' . $table . '(' . implode(', ', $fields) . ') VALUES(' . implode(', ', $values) . ')';
        } else {
        	if ($this->version() >= 40102) {
        		$sql = 'INSERT INTO '. $table .'('. implode(',', $fields) .') VALUES('. implode(',', $values) .')';
        		
        		if (!empty($sets)) {
        			$sql .= ' ON DUPLICATE KEY UPDATE  '. implode(',', $sets);	
        		}
        	} else {
        		// where
        		if (empty($where)) {
        			$where = array();
        			
        			foreach ($primary_keys as $key) {
        				$where[] = $key = "'". $field_values[$key] ."'" ;
        			}
        			
        			$where = implode(' AND ', $where);
        		}
        		
        		if (!empty($where) && (!empty($sets) || !empty($fields))) {
        			if (intval($GLOBALS['db']->getOne("SELECT COUNT(*) FROM $table WHERE $where")) > 0) {
        				if (!empty($sets)) {
        					$sql = 'UPDATE '. $table .' SET '. implode(',', $sets) .' WHERE '. $where;
        				}
        			} else {
        				if (!empty($fields)) {
        					$sql = 'REPLACE INTO '. $table .'('. implode(',', $fields) .') VALUES('. implode(',', $values) .')';
        				}
        			} // else
        		}
        	} // else
        } // end if
        
        return empty($sql) ? false : $this->query($sql);
    }

已经重写过MySQL类(使用MySQLi方法),需要者Email:ljlwill@gmail.com。

php基本安全

复习下PHP安全的基础知识:

1)关闭注册全局变量功能

即是在php.ini中register_globals=off(也是默认)。它决定是否将 EGPCS(Environment,GET,POST,Cookie,Server)变量注册为全局变量。 如果register_globals=on, 客户端提交的数据中含有GLOBALS变量名, 就会覆盖服务器上的$GLOBALS变量。

2)在使用变量之前,进行初始化。

3)过滤全部输入数据。

其方式主要取决于数据的类型。

4)防止SQL的注入。

应该使用特定语言的数据库转义函数。如mysql_real_escape_data()。

5)谨慎使用执行命令的函数。

如eval(), exec(), system(), passsthru(), popen(), 反撇号(`)。如果在命令中含有变量,无比进行安全检查。还应该再使用escapeshellarg()和escapeshellcom()进行预处理。

6)谨慎使用变量引用包含文件。

7)session会话安全。可改变其默认目录或利用数据库存储其数据。

8)重命名通过HTTP(浏览器)上传的文件。

9)隐藏站点错误消息,把错误报告级别设置为最高。

10)在显示提交的数据时,过滤其HTML和Javascript(如可用strip_tags()函数)

等等