1、参考书目

入门:《JavaScript DOM编程艺术》第二版

进阶:《JavaScript高级程序设计》第二版、《JavaScript编程精粹》

《JavaScript权威指南》

2、引言

Node.js是CommonJS的一个部分实现

本书代码下载:

http://github.com/tdd/pragmatic-javascript

https://github.com/tdd/pragmatic-javascript/archive/master.zip

http://media.pragprog.com/titles/pg_js/code/pg_js-code.tgz

介绍的框架包括:Prototype、jQuery、MooTools、YUI、Dojo、ExtJS

3、利用事件委托

  • 优先使用事件委托
  • 元素共享同一个行为,最好在DOM高层次监听事件,这样可以节省内存和CPU时间

dom/delegation.html

<ul id="items">
<!-- We will insert togglers in each LI using JS -->
<li><div><p>Data 1</p><p>Data 2</p></div></li>
<li><div><p>Data 1</p><p>Data 2</p></div></li>
<li><div><p>Data 1</p><p>Data 2</p></div></li>
<!-- Potentially lots more elements here… -->
</ul>

dom/delegation.js(Prototype)

document.observe('dom:loaded', function() {
$('items').observe('click', function(e) {
var trigger = e.findElement('a.toggler');
if (!trigger) return;
e.stop();
var content = trigger.up('p').next('div');
if (!content) return;
content.toggle();
trigger.update(content.visible() ? 'Close' : 'Open');
trigger.blur();
}); $('items').select('li').each(function(item) {
item.insert({ top: '<p><a class="toggler" href="#">Open</a></p>' });
item.down('div').hide();
});
});

4、模拟后台处理

  • 利用HTML5的Web Workers实现多线程
  • 分解成多个小任务,利用setTimerout和clearTimeout模拟后台处理
var handle = windows.setTimeout(callback, intervalInMs)
window.clearTimeout(hanle);

参考https://github.com/madrobby/emile 50行小程序实现精确定时器

(function(emile, container){
var parseEl = document.createElement('div'),
props = ('backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth '+
'borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize '+
'fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight '+
'maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft '+
'paddingRight paddingTop right textIndent top width wordSpacing zIndex').split(' '); function interpolate(source,target,pos){ return (source+(target-source)*pos).toFixed(3); }
function s(str, p, c){ return str.substr(p,c||1); }
function color(source,target,pos){
var i = 2, j, c, tmp, v = [], r = [];
while(j=3,c=arguments[i-1],i--)
if(s(c,0)=='r') { c = c.match(/\d+/g); while(j--) v.push(~~c[j]); } else {
if(c.length==4) c='#'+s(c,1)+s(c,1)+s(c,2)+s(c,2)+s(c,3)+s(c,3);
while(j--) v.push(parseInt(s(c,1+j*2,2), 16)); }
while(j--) { tmp = ~~(v[j+3]+(v[j]-v[j+3])*pos); r.push(tmp<0?0:tmp>255?255:tmp); }
return 'rgb('+r.join(',')+')';
} function parse(prop){
var p = parseFloat(prop), q = prop.replace(/^[\-\d\.]+/,'');
return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q };
} function normalize(style){
var css, rules = {}, i = props.length, v;
parseEl.innerHTML = '<div style="'+style+'"></div>';
css = parseEl.childNodes[0].style;
while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
return rules;
} container[emile] = function(el, style, opts, after){
el = typeof el == 'string' ? document.getElementById(el) : el;
opts = opts || {};
var target = normalize(style), comp = el.currentStyle ? el.currentStyle : getComputedStyle(el, null),
prop, current = {}, start = +new Date, dur = opts.duration||200, finish = start+dur, interval,
easing = opts.easing || function(pos){ return (-Math.cos(pos*Math.PI)/2) + 0.5; };
for(prop in target) current[prop] = parse(comp[prop]);
interval = setInterval(function(){
var time = +new Date, pos = time>finish ? 1 : (time-start)/dur;
for(prop in target)
el.style[prop] = target[prop].f(current[prop].v,target[prop].v,easing(pos)) + target[prop].u;
if(time>finish) { clearInterval(interval); opts.after && opts.after(); after && setTimeout(after,1); }
},10);
}
})('emile', this);

dom/background.js

var CHUNK_INTERVAL = 25; // ms.
var running = false, progress = 0, processTimer; function runChunk() {
window.clearTimeout(processTimer);
processTimer = null;
if (!running) return;
// Some work chunk. Let's simulate it:
for (var i = 0; i < 10000; i += (Math.random() * 5).round())
;
++progress;
updateUI(); // See source archive -- just updates a progressbar
if (progress < 100) {
processTimer = window.setTimeout(runChunk, CHUNK_INTERVAL);
} else {
progress = 0, running = false;
}
} function toggleProcessing() {
running = !running;
if (running) {
processTimer = window.setTimeout(runChunk, CHUNK_INTERVAL);
}
}

5、打造漂亮的tooltip

用CSS属性设置tooltip元素为默认隐藏,并在其内容标签上加:hover选择器来恢复显示。

但这种方式在IE6不起作用,因为IE6只允许<a>元素上有:hover。只能手动编写脚本,响应mouseover和mouseout。

作者推荐Prototype的Prototip2库http://www.nickstakenburg.com/projects/prototip2/

ui/tooltips/index.html

<li tabindex="1">
<span class="name">Capacity: 1.5 TB</span>
<div class="tooltip" >
<p><strong>1.5 Terabyte = 1,536 Gigabytes</strong></p>
<p>Enough for 50,000 songs, 1,000 DivX movies, 100,000
high-definition photos, hundreds of iDVD projects and
plenty of backup space left.</p>
</div>
</li>

ui/tooltips/tooltips.css

#files li { position: relative; }
#files li .tooltip {
position: absolute; top: 8px; left: 120px; width: 24em;
z-index:; display: none;
/* IE6 doesn't know li:hover, so we need to toggle via JS,
therefore avoiding in-rule display: none */
_display: block;
border: 1px solid gray;
background: #fffdc3 url(bg_tooltip.png) top left repeat-x;
}
#files li:hover .tooltip,
#files li:focus .tooltip { display: block; }

ui/tooltips/tooltips.js

function toggle(reveal, e) {
var trigger = e.findElement('li'),
tooltip = trigger && trigger.down('.tooltip');
if (!tooltip) return;
tooltip[reveal ? 'show' : 'hide']();
} document.observe('dom:loaded', function() {
var isIE6 = Prototype.Browser.IE &&
undefined === document.body.style.maxHeight;
if (!isIE6) return;
var files = $('files'), tooltips = files && files.select('.tooltip');
if (!files || 0 == tooltips.length) return;
tooltips.invoke('hide');
files.observe('mouseover', toggle.curry(true)).
observe('mouseout', toggle.curry(false));
});

6、友好的弹窗

用<a>链接到要弹出的内容(href=,target=”_blank”),然后在链接上挂上JavaScript代码。这样可以解决禁止弹窗、屏幕阅读器(视觉障碍者使用)、搜索引擎的访问问题。

ui/popups/index.html

<p>
The great thing about <a class="popup" target="_blank"
href="http://pragprog.com/titles/pg_js">Pocket Guide to JavaScript</a>
is that it focuses on a bunch of specific, useful tasks.</p>

ui/popus/popus.js

var POPUP_FEATURES = 'status=yes,resizable=yes,scrollbars=yes,' +
'width=800,height=500,left=100,top=100'; function hookPopupLink(e) {
var trigger = e.findElement('a.popup');
if (!trigger) return;
e.stop(); trigger.blur();
var wndName = trigger.readAttribute('target') ||
('wnd' + trigger.identify());
window.open(trigger.href, wndName, POPUP_FEATURES).focus();
} document.observe('click', hookPopupLink);

7、光箱特效

利用FancyBox jQuery插件

ui/lightbox/lightbox.js

$('#thumbnails a').fancybox({
zoomSpeedIn: 300, zoomOpacity: true, overlayColor: '#000',
overlayOpacity: 0.6
});

8、无限翻页

ui/infinite/infinite.js

function lowEnough() {
var pageHeight = Math.max(document.body.scrollHeight,
document.body.offsetHeight);
var viewportHeight = window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight || 0;
var scrollHeight = window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop || 0;
// Trigger for scrolls within 20 pixels from page bottom
return pageHeight - viewportHeight - scrollHeight < 20;
} function checkScroll() {
if (!lowEnough()) return pollScroll();
$('spinner').show();
new Ajax.Updater('posts', 'more.php', {
method: 'get', insertion: 'bottom',
onComplete: function() { $('spinner').hide(); },
onSuccess: pollScroll
});
} function pollScroll() { setTimeout(checkScroll, 100); } pollScroll();

9、载入内容时保持显示区域的位置不变

ui/viewport/index.html

<h2>Comments</h2>

<div id="extraComments">
<a id="loadKnownComments" href="?with_known_comments">See previous
comments you already know about</a>
</div> <h3>Comment 5</h3>

ui/viewport/viewport.js

function loadKnownComments(e) {
e.stop();
var zone = $('extraComments'), ref = zone.next('h3');
var upd = new Ajax.Request('known_comments.html', {
method: 'get',
onSuccess: function(res) {
var orig = ref.cumulativeOffset().top -
document.viewport.getScrollOffsets().top;
zone.insert({ before: res.responseText });
window.scrollTo(0, ref.cumulativeOffset().top - orig);
}
});
} document.observe('dom:loaded', function() {
var loader = $('loadKnownComments');
loader && loader.observe('click', loadKnownComments);
});

10、提供输入长度的反馈

  • 对keyup和keypress监听,以及对非字符键(删除、剪切、粘贴)做出响应。没必要监听keydown
  • 为避免每次按键都重复计算最大长度,我们在初始化时把它缓存起来。为了把最大长度和输入区域关联起来,我们用了JS关联数组,这比用属性轻便点

form/feedback/index.html

<p>
<label for="edtDescription">Description</label>
<textarea id="edtDescription" name="description" cols="40"
rows="5" class="maxLength200"></textarea>
</p>

form/feedback/feedback.js

var maxLengths = {};

  function bindMaxLengthFeedbacks() {
var mlClass, maxLength, feedback;
$$('*[class^=maxLength]').each(function(field) {
field.up('p').addClassName('lengthFeedback');
mlClass = field.className.match(/\bmaxLength(\d+)\b/)[0];
maxLength = parseInt(mlClass.replace(/\D+/g, ''), 10); feedback = new Element('span', { 'class': 'feedback' });
maxLengths[field.identify()] = [maxLength, feedback];
updateFeedback(field);
field.observe('keyup', updateFeedback).
observe('keypress', updateFeedback); feedback.clonePosition(field, { setHeight: false,
offsetTop: field.offsetHeight + 2 });
field.insert({ after: feedback });
});
} function updateFeedback(e) {
var field = e.tagName ? e : e.element();
var current = field.getValue().length,
data = maxLengths[field.id], max = data[0],
delta = current < max ? max - current : 0;
data[1].update('Remaining: ' + delta);
if (current > max) {
field.setValue(field.getValue().substring(0, max));
}
} document.observe('dom:loaded', bindMaxLengthFeedbacks);

11、同时选择或反选多个checkbox

form/checklist/index_for_book.html

<table id="mailbox">
<thead>
<tr>
<th><input type="checkbox" id="toggler" /></th>
<th>Subject</th>
<th>Date</th>
<!-- From, Size, Attachments… -->
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="mail_ids[]" value="1" /></td>
<td>Happy new year!</td>
<td>Jan 1, 2010 00:03am</td>
<!-- … -->
</tr>
<!-- More rows… -->
</tbody>
</table>

form/checklist/checklist.js

function toggleAllCheckboxes() {
var scope = this.up('table').down('tbody'), boxes = scope &&
scope.select('tr input[type="checkbox"]:first-of-type');
var refChecked = this.checked;
(boxes || []).each(function(box) { box.checked = refChecked; });
} document.observe('dom:loaded', function() {
$('toggler').observe('click', toggleAllCheckboxes);
});

12、表单验证

检验未填的必填项

form/validation101/validation101.js

function checkForm(e) {
var firstOffender, value;
this.select('.required').each(function(field) {
value = field.getValue();
if (value && !value.blank()) {
field.up('p').removeClassName('missing');
} else {
firstOffender = firstOffender || field;
field.up('p').addClassName('missing');
}
});
if (firstOffender) { e.stop(); firstOffender.focus(); }
} document.observe('dom:loaded', function() {
$('registration').observe('submit', checkForm);
});

检查特定格式的输入域

form/validation102/validation102.js

var FIELD_PATTERNS = {
integer: /^\d+$/,
number: /^\d+(?:\.\d+)?$/,
email: /^[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$/i
}; function checkField(field) {
var value = $F(field).toString().strip();
for (var pattern in FIELD_PATTERNS) {
if (!field.hasClassName(pattern)) continue;
if (!FIELD_PATTERNS[pattern].test(value)) return false;
}
return true;
}

和服务器端通信,监测登录名域

form/validation_ajax/validation_ajax.js

document.observe('dom:loaded', function checkLogin() {
var feedback = $('user_login').next('.feedback'),
spinner = $('user_login').next('.spinner');
new Field.Observer('user_login', 0.8, function(_, value) {
if (value.length < 2) return;
feedback.hide(); spinner.show();
new Ajax.Request('check_login.php', {
method: 'get', parameters: { login: value },
onComplete: function(res) {
if (Ajax.activeRequestCount > 1) return;
if (res.request.success() && res.status) {
feedback.update('Login available!').removeClassName('ko');
} else {
feedback.update('Login taken!').addClassName('ko');
}
spinner.hide(); feedback.show();
},
});
});

form/validation_ajax/check_login.php

sleep(rand(5, 10) / 10.0); // Simulate intarwebs delay…
$RESERVED = array('bob', 'doudou', 'tdd', 'meshak', 'ook');
$login = isset($_GET['login']) ? $_GET['login'] : '';
$response = in_array($login, $RESERVED) ? '422 Conflict' : '202 Accepted';
header('HTTP/1.1 ' . $response);

13、在表单中提供动态的帮助tooltip

form/tooltips/index.html

<p>
<label for="user_login">
Login*
<span class="tooltip" style="display: none;">
Logins must be unique, at least 3 characters long,
and may only use letters, numbers, white space,
hyphens, underscores and periods.
</span>
</label>
<input type="text" id="user_login" name="user[login]"
class="required text" />
</p>

form/tooltips/tooltips.css

#registration { font-family: sans-serif; }
#registration p { margin: 0 0 0.5em;}
/* START:main */
#registration label { float: left; width: 6em; position: relative; zoom:; }
#registration input.text { width: 14em; }
#registration .tooltip {
display: block; position: absolute; left: 24em; top:;
padding: 0.35em 0.5em 0.35em 2em; width: 15em;
border: 1px solid silver;
color: gray; font-size: 80%;
background: #ffc url(lightbulb.png) 0.5em 0.3em no-repeat;
}

form/tooltips/tooltips.js

document.observe('dom:loaded', function() {
var attr = Prototype.Browser.IE ? 'htmlFor' : 'for';
function showTooltip() {
var tooltip = $$('label['+attr+'="'+this.id+'"] .tooltip').first();
tooltip && tooltip.show();
}
function hideTooltip() {
var tooltip = $$('label['+attr+'="'+this.id+'"] .tooltip').first();
tooltip && tooltip.hide();
} $('registration').getInputs().invoke('observe', 'focus', showTooltip).
invoke('observe', 'blur', hideTooltip);
});

14、自动完成输入

Prototype的Sctipt.aculo.us控件

form/autocompletion/index.html

<div class="p" id="local">
<label for="edtCachedSearch">Local search:</label>
<input type="text" id="edtCachedSearch" name="search" type="text" />
<div class="completions"></div>
</div>
<div class="p">
<label for="edtAjaxSearch">Ajax search:</label>
<input type="text" id="edtAjaxSearch" name="search" type="text" />
(capitals of the world)
<div class="completions"></div>
</div>

form/autocompletion/autocompletion.css

.completions {
border: 1px solid silver; background: white; font-size: 80%; z-index:;
}
.completions ul { margin:; padding:; list-style-type: none; }
.completions li { line-height: 1.5em; white-space: nowrap;
overflow: hidden; }
.completions li.selected { background: #ffa; }
.completions strong { color: green; }

form/autocompletion/autocompletion.js

var FREQUENT_SEARCHES = [
'JavaScript', 'JavaScript frameworks', 'Prototype', 'jQuery', 'Dojo',
'MooTools', 'Ext', 'Ext JS', 'script.aculo.us', 'Scripty2', 'Ajax',
'XHR', '42'
]; function initLocalCompletions() {
var field = $('edtCachedSearch'), zone = field.next('.completions');
new Autocompleter.Local(field, zone, FREQUENT_SEARCHES,
{ fullSearch: true });
} function initAjaxCompletions() {
var field = $('edtAjaxSearch'), zone = field.next('.completions');
new Ajax.Autocompleter(field, zone, 'autocomplete.php', {
method: 'get', paramName: 'search' });
}

15、多文件自动上传

HTML5之前使用Base64编码,每个上传文件膨胀33%

form/uploads/index.html

<form method="post" action="server.php" enctype="multipart/form-data">
<ul id="uploads"></ul>
<p><input type="file" name="files[]" id="filSelector" /></p>
<p><input type="submit" value="Send these files" /></p>
</form>

form/uploads/uploads.js

var ICONS = $H({ word: $w('doc docx'), image: $w('jpg jpeg gif png') });

  function getFileClass(fileName) {
var ext = (fileName.match(/\.(.+?)$/) || [])[1].toString().toLowerCase();
var icon = ICONS.detect(function(pair) { return pair[1].include(ext); });
return (icon || [])[0];
} function handleQueueRemoval(e) {
var trigger = e.findElement('button');
trigger && trigger.up('li').remove();
} function queueFile() {
var fileName = $F(this), clone = this.cloneNode(true);
var item = new Element('li', { 'class': getFileClass(fileName) });
$(clone).observe('change', queueFile).setValue('');
this.parentNode.appendChild(clone);
item.appendChild(this);
item.appendChild(document.createTextNode(fileName));
item.insert('<button><img src="remove.png" alt="Remove" /></button>');
$('uploads').appendChild(item);
} document.observe('dom:loaded', function() {
$('filSelector').observe('change', queueFile);
$('uploads').observe('click', handleQueueRemoval);
});

16、使用JSON-P

JSON-P的传输主要依赖于动态生成的<script>标签,所以传输数据可以不限于同一来源。

jsonp和ajax完全是两个概念,可以说jsonp出现的理由就是弥补ajax无法跨域访问的缺陷而出现的。jsonp返回的数据并不是json,而是javascrip。

参考文章:说说JSON和JSONP   初识jsonp

server/jsonp/jsonp.js

function injectData(data) {
var ref = $('sysInfo').down('tbody tr:last-child'), row = new Element('tr'), key;
ref.select('td').each(function(cell) {
row.appendChild($(cell.cloneNode(true)).update(data[cell.className]));
});
ref.insert({ after: row });
}
window.injectData = injectData; function loadJSONPBasic(e) {
e.stop(); this.blur();
document.documentElement.firstChild.appendChild(
new Element('script', { type: 'text/javascript',
src: this.href + '&r=' + Math.random() }));
} function loadJSONP(e) {
e.stop(); this.blur();
var script = new Element('script', { type: 'text/javascript',
src: this.href });
script.src += ('&r=' + script.identify());
script.observe('load', Element.remove.curry(script));
document.documentElement.firstChild.appendChild(script);
} document.observe('dom:loaded', function() {
$('triggerJSONP').observe('click', loadJSONP);
});

随机参数是为了避免浏览器缓存而添加的,为了保证代码质量,最好先检查下一URI,以决定用&还是?(这个参数是否是第一个参数)

在浏览器载入之后将其删除,以免DOM变得过大

17、跨域“Ajax”1

跨域的方法:

  • 通过服务器端代理来载入数据
  • 跨来源资源共享(Cross-Origin Resource Sharing,CORS)。XHR2就是用的CORS,这也是W3C指定的跨域数据请求的方式
  • 使用JSON-P,或者同时使用动态/隐藏表单和<iframe>

server/crossdomain1/crossdomain1.js

// 同时使用动态生成的表单和<iframe>
function loadUsingDF1(e) {
e.stop(); this.blur();
var warp = new Element('iframe', { name: '__blackhole' });
warp.setStyle('width: 0; height: 0; border: 0');
document.body.appendChild(warp);
warp.observe('load', function() {
$('responses').insert('<p>OK, posted.</p>');
});
var form = new Element('form', { method: 'post', action: this.href,
target: '__blackhole' });
form.submit();
} // 使用得到204响应的动态生成的表单
function loadUsingDF2(e) {
e.stop(); this.blur();
var form = new Element('form', { method: 'post', action: this.href });
form.submit();
Element.insert.defer('responses', '<p>OK, posted.</p>');
} // 使用服务器端协议
function loadUsingSSP(e) {
e.stop(); this.blur();
new Ajax.Updater({ success: 'responses' }, 'ssp.php', {
method: 'get', parameters: { uri: this.href }, insertion: 'bottom'
});
} // 使用CORS兼容的XMLHttpRequest
function loadUsingXHR(e) {
e.stop(); this.blur();
new Ajax.Updater({ success: 'responses' }, this.href, {
method: 'get', insertion: 'bottom'
});
}

18、跨域“Ajax”2

YQL并不是云数据库的一部分,它是一个严格的查询处理托管服务。另外,这也意味着YQL不受单独的数据资源限制,甚至不限制应用于雅虎的自身产品。YQL可以操作任何第三方数据源,只要对方是一种常见的格式,如RSS, ATOM, JSON, XML,等等。

// 使用之前那种普通的JSON-P
function loadUsingJSONP(e) {
e.stop(); this.blur();
window.jsonpCallback = function jsonpCallback(data) {
$('responses').update(data.payload.escapeHTML());
};
document.documentElement.firstChild.appendChild(
new Element('script', { type: 'text/javascript',
src: this.href + '?r=' + Math.random() + '&callback=jsonpCallback' }));
} // 使用JSON-P-X形式的YQL html表(XML格式的JSON-P)
function loadUsingYQLget(e) {
e.stop(); this.blur();
window.yqlCallback = function yqlCallback(data) {
$('responses').update('<ul>' + data.results.map(function(td) {
return '<li>' + td.replace(/<\/?(?:td|p)[^>]*>/g, '').
replace(/href="/g, 'href="http://github.com') + '</li>';
}).join("\n") + '</ul>');
};
var url = this.href, xpath = "//*[@class='title']",
yql = 'select * from html where url="' + url + '" and xpath="' + xpath + '"',
data = { q: yql, format: 'xml', callback: 'yqlCallback' };
document.documentElement.firstChild.appendChild(
new Element('script', { type: 'text/javascript',
src: 'http://query.yahooapis.com/v1/public/yql?' + Object.toQueryString(data) +
'&r=' + Math.random()
}));
} // 使用JSON-P形式的YQL htmlpost表
function loadUsingYQLpost(e) {
e.stop(); this.blur();
window.yqlCallback = function yqlCallback(data) {
$('responses').update(data.query.results.postresult.p.join("<br/>"));
};
var post = Object.toQueryString({ foo: 'foo', bar: 'bar' }),
url = this.href, xpath = "//p", env = 'store://datatables.org/alltableswithkeys',
yql = 'select * from htmlpost where url="' + url + '" and postdata="' + post + '"' +
' and xpath="' + xpath + '"',
data = { q: yql, format: 'json', env: env, callback: 'yqlCallback' };
document.documentElement.firstChild.appendChild(
new Element('script', { type: 'text/javascript',
src: 'http://query.yahooapis.com/v1/public/yql?' + Object.toQueryString(data) +
'&r=' + Math.random()
}));
} // 使用CSSHttpRequest
function loadUsingCHR(e) {
e.stop(); this.blur();
CSSHttpRequest.get(this.href, function(res) {
$('responses').insert('<p>' + res.escapeHTML() + '</p>');
});
}

《JavaScript修炼之道》读书笔记的更多相关文章

  1. csapp读书笔记-并发编程

    这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...

  2. CSAPP 读书笔记 - 2.31练习题

    根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1)  属于第一种情况 sum = x ...

  3. CSAPP读书笔记--第八章 异常控制流

    第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...

  4. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  5. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  10. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

随机推荐

  1. 介绍两种风格的URL

    两种风格的“动态资源”——统一资源定位符(Uniform Resource Lactor,URL) 当前互联网上主要有两种主要风格的URL: 第一种直接在URL中知名文件(比如xxx.php,xxx. ...

  2. [迷宫中的算法实践]迷宫生成算法——递归分割算法

    Recursive division method        Mazes can be created with recursive division, an algorithm which wo ...

  3. Python入门笔记(19):Python函数(2):函数/方法装饰器

    一.装饰器(decorators) 装饰器的语法以@开头,接着是装饰器函数的名字.可选参数. 紧跟装饰器声明的是被装饰的函数和被装饰的函数的可选参数,如下: @decorator(dec_opt_ar ...

  4. vim编辑器,管道,输入输出重定向

    1.vim的认识及其一些常用指令 a, 认识vim的命令行模式和插入模式: 当vim运行后默认进入该模式,他可以控制屏幕光标的移动,字符.字或行的删除,移动复制某区段及进入Insert mode下,或 ...

  5. js实现向上滚动效果

    源码: <style type="text/css"> #up_zzjs{border:1px solid #ccc;width:170px;height:182px; ...

  6. pbfunc外部函数扩展应用-直接在Datawindow中生成QR二维码,非图片方式

    利用pbfunc外部函数在Datawindow中直接生成QR二维码,非图片方式.需要注意以下面几点: Datawindow的DataObject的单位必须为像素(Pixels). Datawindow ...

  7. MAC 隐藏文件的显示

    显示 defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏 defaults write com.apple.finder A ...

  8. Java生成公私钥对

    public static synchronized KeyPair generateRSAKeyPair(int keysize, BigInteger publicExponent) { try ...

  9. WPF下递归生成树形数据绑定到TreeView上

    最终效果图:(用于学习类的效果 图片丑了点,看官莫怪) 新建窗体 然后在前端适当位置插入如下代码: <TreeView x:Name="> <TreeView.ItemTe ...

  10. AloneJs.confirmbox() —— 确认框

    一.引用 <link href="https://cdn.suziyun.com/alonejs.min.css" rel="stylesheet" /& ...