客戶端從socket 讀取文件內(nèi)容,如何知道什么時(shí)候讀到文件的結(jié)尾? 以及接受到讀到的文件是否完整?
無(wú)法知道?;蛘哒f(shuō),只有“你”才知道。
你能知道的信息,是收到了多少字節(jié),收到的內(nèi)容是什么,至于是否“結(jié)尾”,是否“結(jié)束”,那是你邏輯上的事。
而傳輸協(xié)議如何設(shè)計(jì),可以簡(jiǎn)單去了解一下 HTTP 就明白了。
測(cè)試代碼發(fā)現(xiàn)有時(shí)候,接收到的文件是原文件的兩倍大小,怎么回事?
你代碼有問(wèn)題。
我運(yùn)行沒(méi)有問(wèn)題,你的代碼可以直接獲取到data64位的圖片,也能成功插入到#show里面,我覺(jué)得你可能遇到了跨域的問(wèn)題,toDataURL里面的圖片需要在相同域名下,如果你是本地運(yùn)行的話,建議把圖片地址也改成本地試試
因?yàn)橐坏﹕ingletonLazy被正確初始化以后,每次訪問(wèn)null == singletonLazy一定能夠得到false從而不會(huì)重新初始化。但是我們無(wú)需每次都通過(guò)上鎖來(lái)判斷null == singletonLazy。所以雙重鎖的目的是為了成功初始化singletonLazy之后不再觸發(fā)加鎖操作。
getEffectiveSessionTrackingModes 這個(gè)方法是在Servlet 3.0里面引入的,可以看一下你是否用的是Servlet3.0,然后看一下是否導(dǎo)入Servlet jar報(bào)了
可以試試 rap,阿里出的 mock 工具:
支持多人協(xié)作。項(xiàng)目開始前,讓后端定義好數(shù)據(jù)格式,開發(fā)起來(lái)還不是美滋滋
Cache-Control:max-age=86400 緩存一天
將這一段代碼,挪出在click函數(shù)外試試。
socket.on('chat',function(data){
var $it = addMsg(data);
$it.appendTo($message);
});
沒(méi)有代碼。只給思路。
補(bǔ)充
https://segmentfault.com/n/13... 這是我一篇筆記,可以參考參考,是個(gè)白話故事形式的講解,我覺(jué)得挺生動(dòng)的,希望幫到你
x = Rcos(a)cos(b)
y = Rcos(a)sin(b)
z = Rsin(a)
R為地球半徑
a= arcsin(z/R);
通過(guò)(sin(a))^2+(cos(a))^2=1得cos(a)
b = arcsin(y/Rcos(a))
這樣應(yīng)該可以吧-.-
TTFB(Time To First Byte)首字節(jié)時(shí)間,包含了發(fā)送請(qǐng)求到服務(wù)器,服務(wù)器處理請(qǐng)求并生成響應(yīng),服務(wù)器響應(yīng)內(nèi)容發(fā)送到瀏覽器的時(shí)間。只測(cè)試瀏覽器收到第一個(gè)字節(jié)的時(shí)間。
會(huì)對(duì)這個(gè)造成影響的分別有DNS查詢、服務(wù)器響應(yīng)、SSL認(rèn)證,重定向等。例如可能因?yàn)槟愕姆?wù)器在國(guó)外之類的原因造成TTFB過(guò)長(zhǎng)。
如果你的數(shù)據(jù)是后端計(jì)算完之后嵌到前端頁(yè)面上,也會(huì)有影響。解決方法不外乎是把某些運(yùn)算量較大的數(shù)據(jù)獲取改為用ajax之類的方式分步獲取。
HashSet源碼是基于HashMap實(shí)現(xiàn)的
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
Set<Class<?>> classes = new HashSet<>();
調(diào)用private static void doAddClass(Set<Class<?>> classes, String className)方法
兩個(gè)classes引用同時(shí)指向new HashSet<>()這個(gè)對(duì)象,在方法里面執(zhí)行 classes.add(cls);
也就是調(diào)用了map的put方法,修改了這個(gè)共同指向?qū)ο罄锩娴腍ashMap成員變量的內(nèi)容,返回的也是這個(gè)對(duì)象,所以getClassSet方法返回的set里能獲取到元素。
mongod 服務(wù)沒(méi)開啟
packageInfoList.forEach(package => {
var newPackage = ConfigData.getGoods(true, package.id);
package.packageTag.forEach(tag => {
var newTag = newPackage.packageTag.find(t => t.id === tag.id);
if(!newTag) return;
tag.goods.forEach(goods => {
var newGoods = newTag.goods.find(g => g.id === goods.id);
if(!newGoods) return;
var flag = updateGoodAttr(goods, newGoods);
});
});
});
updateGoodAttr = (goods, newGoods) => {
goods.attr.forEach(attr => {
var newAttr = newGoods.attr.find(a => a.id === attr.id)
attr.option.filter(taste => !!taste.select).foreach(taste => {
var newTasteOption = newAttr.option.find(t => t.id === taste.id);
if(newTasteOption) {
newTasteOption.select = taste.select;
}
});
});
}
已經(jīng)省去里很多迭代的下角標(biāo)處理里,但是代碼還是很啰嗦,頻繁重復(fù)對(duì)兩個(gè)數(shù)組進(jìn)行元素比較。干脆把這個(gè)邏輯提取出來(lái):
var match = (arr1, arr2, identifier, process) => arr1.forEach(item1 =>
arr2.forEach(item2 => identifier(item1) === identifier(item2) && process(item1, item2))
);
傳入兩個(gè)數(shù)組,對(duì)數(shù)組元素的每個(gè)元素使用 identifier 獲取 id,如果比較成功,則調(diào)用 process 函數(shù)處理這兩個(gè)元素。例子中 identifier 都一樣,即 item => item.id.
var ID = item => item.id;
var processPackage = (p1, p2) => match(p1.packageTag, p2.packageTag, ID, processTag);
var processTag = (tag1, tag2) => match(tag1.goods, tag2.goods, ID, processGoods);
var processGoods = (goods1, goods2) => match(goods1,attr, goods2.attr, ID, processAttr);
var processAttr = (attr1, attr2) => match(attr1.options.filter(taste => !!taste.select), attr2.options, ID, processTaste);
var processTaste = (taste1, taste2) => taste2.select = taste1.select
var packageInfoList = [...], configPackageList = [...];
match(packageInfoList, configPackageList, ID , processPackage);
目前代碼中還存在重復(fù)地調(diào)用 match 函數(shù),調(diào)用邏輯相似而重復(fù),如果能把這塊抽出來(lái)就好了。我們?cè)偬崛∫粋€(gè)函數(shù),用來(lái)構(gòu)造 processXXX。processAttr比較特殊,對(duì)兩邊取子屬性的邏輯不一樣,所以提取的這個(gè)函數(shù)需要考慮 processAttr 的需求。
var subProcess = ([s1, s2], id, process) => (i1, i2) => match(s1(i1), s2(i2), id, process)
var fixSelector = f => Array.isArray(f) ? f : [f, f]
var processTaste = (taste1, taste2) => taste2.select = taste1.select
var processAttr = subProcess(
fixSelector([item => item.options.filter(taste => !!taste.select), item => item.options]),
ID,
processTaste
)
var processGoods = subProcess(fixSelector(item => item.attr), ID, processAttr)
var processTag = subProcess(fixSelector(item => item.goods), ID, processGoods)
var processPackage = subProcess(fixSelector(item => item.tag), ID, processTag)
var ID = item => item.id
match(
packageInfoList,
configPackageList,
ID,
processPackage
);
最后一步調(diào)用其實(shí)等價(jià)于:
subProcess(fixSelector([() => packageInfoList, () => configPackageList], ID,
subProcess( fixSelector(package => package.tag), ID
subProcess( fixSelector(tag => tag.goods), ID,
subProcess( fixSelector(goods => goods.attr), ID
subProcess( fixSelector([attr => attr.options.filter(taste => !!taste.select), attr => attr.options]), ID
processTaste
)
)
)
)
)()
把掉套函數(shù)調(diào)用拉平試試?試想如下代碼:
f(a, f(b, f(c, f(d, e)))))
// 等價(jià)于
[a,b,c,d,e].reduceRight((prev, item) => f(item, prev))
于是有:
var match = (arr1, arr2, identifier, process) => arr1.forEach(item1 =>
arr2.forEach(item2 => identifier(item1) === identifier(item2) && process(item1, item2))
)
var subProcess = ([s1, s2], id, process) => (i1, i2) => match(s1(i1), s2(i2), id, process)
// 為了傳遞 selector 的時(shí)候可以單獨(dú)給一個(gè)函數(shù)
var fixSelector = f => Array.isArray(f) ? f : [f, f]
var reducer = (prev, [selector, identifier]) => subProcess(fixSelector(selector), identifier, prev)
var process = (...items) => items.reduceRight(reducer)()
// 調(diào)用
process(
[ [() => packageInfoList, () => configPackageList], ID], // 初始數(shù)據(jù)
[ package => package.tag, ID], // 根據(jù)上面一項(xiàng)的元素,返回需要繼續(xù)比對(duì)的下一層數(shù)據(jù)
[ tag => tag.goods, ID], // 把ID當(dāng)參數(shù)在每一層傳進(jìn)來(lái)是為了支持不同層取 ID 的方式不同
[ goods => goods.attr, ID], // 再深也不怕,無(wú)非多一個(gè)參數(shù)
// 支持兩邊不同的取值方法
[ [attr => attr.options.filter(taste => !!taste.select), attr => attr.options], ID],
// 最后一個(gè)函數(shù)就是你處理深處數(shù)據(jù)的地方啦
(taste1, taste2) => taste2.select = taste1.select
)
雖然調(diào)用的時(shí)候挺漂亮的,但是有點(diǎn)繞。。。
不適合。
不要為了消息隊(duì)列而消息隊(duì)列
redis 或數(shù)據(jù)庫(kù)里放個(gè)表,就存 token 和 uid 的映射。
主動(dòng)作廢就是直接將 uid 對(duì)應(yīng)的 token 置空。
每次先檢查 uid 是否存在對(duì)應(yīng)的 token,有就該怎么校驗(yàn)就怎么校驗(yàn),刷新就是生成新的 token 覆蓋。
你的后臺(tái)在去拉取一遍用戶的相關(guān)信息
主要看下本地終端執(zhí)行g(shù)it命令的用戶和jenkins啟動(dòng)用戶是不是相同。
jenkins的啟動(dòng)的默認(rèn)用戶是jenkins用戶,可以在jenkins的配置文件修改。
正則表達(dá)式:/^abcdx{0,1}/ 展開如下:
知道了展開式,你就知道文檔中字符串該如何替換了,也就是說(shuō),找到跟上面兩個(gè)字符串一樣的字符串,就會(huì)替換。
至于你說(shuō)的 abcdxx,是匹配 abcd 還是匹配 abcdx,那就涉及到正則表達(dá)式中的重復(fù)出現(xiàn)字符是貪婪的還是非貪婪的,默認(rèn)情況是貪婪的,也就是最大化的匹配。所以 abcdxx, 被替換成 abcdyyx。
其實(shí),你的正則表達(dá)式可以優(yōu)化一下,可以寫的更簡(jiǎn)潔,/^abcdx?/,其中 ? 表示0次或者1次。
有個(gè)itchat,可以獲取所有群成員資料,同時(shí)你可以捕獲@所有女性 的信息,然后轉(zhuǎn)換成@所有性性別為女的群成員
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。