標籤: 如何寫文案

  • 最致命的七月! 日本上月逾300人死於氣候災難

    摘錄自2018年8月1日東森新聞台北報導

    日本西部本月初暴雨成災,引發多處爆發土石流,造成斯多人死傷。禍不單行的是,暴雨過後又有熱浪來襲,數以萬計的人因中暑入院,不少人因此死亡。

    更慘的是,最後還來了一個怪颱「雲雀」在日本拐來拐去,到處肆虐。 統計顯示,日本光是今年7月就有逾300人死於跟天氣相關的災難中,是該國近年最致命的一個月。

    日本迎來極高溫天氣,東京史上首度熱破40°C,多處地方打破歷來的高溫紀錄,至少已有116人死於這一波熱浪。 當局周二(31日)公布的數字顯示:7月第二周因中暑入院的人數比前一周飆升兩倍至將近萬人,第三周再飆升至2.2萬人,上周則稍為降低到1.37萬人。

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

    FB行銷專家,教你從零開始的技巧

  • 研究:伊波拉疫情將隨二氧化碳濃度升高而擴大

    研究:伊波拉疫情將隨二氧化碳濃度升高而擴大

    環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:Carbon Brief

    根據發表在《自然通訊(Nature Communication)》的,當大氣中溫室氣體濃度升高,非洲伊波拉疫情爆發的威脅也將隨之增加。

    隨著氣溫上升,蝙蝠和其他會將病毒傳播給人類的動物可能遷移到新的區域,進而帶來疾病。

    新的模型顯示,如果人口繼續快速增加但發展緩慢且沒有相應的氣候行動,那麼到2070年,伊波拉疫情平均每10年就會爆發一次,今日的平均值是每17年一次。目前還不是疫區的西非和中非也可能受影響。

    該研究的結論是,在當前的經濟增長速度和高碳排放水準下,高風險區域的總面積可能擴大五分之一。在更高的碳排放水準下,甚至可能擴大1/3。

    作者們說,他們於2018年建立統計模型,成功預測了剛果民主共和國當前的疫情,目前伊波拉在當地已經奪走了兩千多條生命。

    因此,他們認為,這份研究當為非洲(包括過去認為未受影響的地區)針對性的伊波拉疫苗計畫和醫療基礎設施的部署奠定基礎。

    獅子山共和國境內努力對抗伊波拉病毒蔓延的村民。 (CC BY-NC-ND 2.0)

    伊波拉病毒於1976年首次被發現,2014年爆發疫情,造成西非成千上萬人喪生,在世界各地成為頭條新聞。

    一般認為這種傳染病是透過所謂的「溢出物感染」從蝙蝠和其他動物宿主傳播給人類的,是一種人畜共通傳染病。所有人類會感染的傳染病中,有2/3是人畜共通傳染病。

    伊波拉病毒一旦感染人類,就可經由直接接觸在人與人之間傳播。人類的症狀包括發燒、嘔吐,有時還包括內部和外部出血。平均死亡率約為50%。

    由於伊波拉疫情可能造成重大傷亡,科學家們必須了解下一次伊波拉疫情可能在何時何地爆發,以便分配醫療資源。

    但是,由於伊波拉自發現以來,確認的疫情暴發僅有23次,很難用傳統預測常見傳染病(如流感)的方法預測。

    伊波拉防疫措施。來源: 。(CC BY 2.0)

    倫敦大學學院的雷丁(David Redding)博士、瓊斯(Kate Jones)博士及其團隊沒有用以前的爆發資料進行研究,而是「由下而上」建立伊波拉爆發的風險模型。

    他們使用的資料包含許多因子,包括寄主分布、人口數、陸上交通、空中交通、以及土地利用類型。

    該分析的一個關鍵要素是氣候變遷,它既能影響當地社會經濟發展,也可以影響疾病傳播,而且正如雷丁所說,「在我們的模型中,大部分氣候的影響來自於為攜帶疾病的物種提供更好的條件,從而擴大了其地理分布範圍。」

    儘管究竟哪些動物能將伊波拉病毒傳給人類仍存在一些不確定性,最主要的嫌犯是大型狐蝠,而這種狐蝠常常被人類獵來吃。這些動物喜歡溫暖和潮濕的棲息地,隨著氣候變遷,高風險地區的棲息地還可能擴張。

    分析中還納入了其他可能是傳染途徑的動物,如猿類和麂羚。

    研究人員指出,從他們觀察到的結果看來,氣候的作用不如貧窮(後者與醫療保健的反應密切相關)和人口數。

    但他們也發現,溢出物感染隨著溫室氣體濃度的增加而增加。雷丁說,「在我們的模型中,負面影響隨著排放增加越來越明顯。」

    研究人員開發出一個可模擬西非流行的薩伊伊波拉病毒(Zaire Ebola virus, EBOV)人傳人和動物傳人的模型。

    科學家用圖示說明在不同排放情境下的伊波拉病毒擴散風險。來源:

    為了評估複雜的社會、經濟和氣候因素對非洲未來伊波拉病毒傳播的影響,研究團隊將氣候變遷情境中的代表濃度途徑(representative concentration pathways, RCPs)和共享社會經濟途徑(shared socio-economic pathways, SSPs)納入其模型。

    RCPs代表不同程度的氣候行動導致溫室氣體濃度不斷升高的情境。SSP代表各種社會經濟發展情境,涉及全球社會、人口統計和經濟學的不同狀況。

    接著,研究人員使用這些模型來預測到2070年非洲不同地區的伊波拉疫情風險變化。在大多數情境中,模擬結果顯示伊波拉發病率隨時間持續增加。

    但是,在永續發展和氣候變遷大規模緩解的情境,伊波拉疫情風險普遍下降。

    在現況條件下,模型預測,由溢出物感染引發的流行病大約每17年發生一次。流行病爆發在此定義為規模在1,500名患者以上的感染狀況。

    團隊使用現況條件進行了約1,500次年度模擬,發現其中約有5.8%發生了疫情爆發。接著使用不同的條件組合重複此過程。

    最大的增長發生在高排放、高人口增長和經濟發展緩慢的情況下(RCP6.0和SSP3),疫情幾乎每10年爆發一次。(論文的原始摘要寫道,在此情況下,疫情爆發的可能性比今日高出四倍,但是正確應是1.6倍。Carbon Brief與作者聯繫後確認了這一點。)

    在最樂觀的情境下(假定排放量適中且發展迅速,即RCP4.5和SSP1),頻率下降到大約每30年一次。

    模型也顯示,影響超過200萬人的「災難性疫情爆發」模式也很類似。目前這種事件預估每43年發生一次,但根據模擬,在高排放情境下,它們的發生頻率也將增加。

    模型還預測有爆發風險的區域會擴大。例如,在最樂觀的社會經濟和氣候情況下,有爆發風險的總面積與今天相比減少了近一半(分別是40萬平方公里和80萬平方公里)。

    相比之下,在低度氣候變遷緩解和中度發展(RCP6.0和SSP2)情境下,該面積增加了20.5%;在更極端的情況(RCP8.5和SSP3)下,該面積進一步增加了34%。

    值得注意的是,許多傳染病是透過環境傳播(例如水或土壤傳播),但伊波拉病毒是透過宿主之間的直接接觸傳播。這表示儘管蝙蝠和人類直接受到氣候變遷的影響,但病毒本身卻不太容易受氣候變遷影響。

    該論文的結論是,因應氣候變遷的全球性承諾也許有助降低伊波拉病例。但是對於這種推測不應太樂觀,因為「證據顯示不太可能發生全面性的改變」。

    「在中部和西部非洲減少貧困以及增加醫療資源,似乎是降低全球未來伊波拉疫情風險最現實的方法。」

    除了準確地找出已知有伊波拉疫情的地區外,該模型還確定了尼日、迦納和肯亞等國家都很可能受小規模溢出物感染和伊波拉疫情影響,儘管這些國家從來沒傳出伊波拉疫情過。

    Ebola epidemics will ‘increase with greenhouse gas concentrations’, study finds by Josh Gabbatiss

    The threat of Ebola outbreaks across Africa will increase as levels of greenhouse gases in the atmosphere rise, according to new research.

    With warming temperatures, bats and other animals that are thought to transmit the virus to humans are expected to move into new areas, bringing the disease with them. 

    The new modelling suggests that by 2070 epidemics could break out, on average, once every 10 years, if rapid population growth and slow development are accompanied by inaction on climate change. Under today’s conditions, the average is once every 17 years.

    According to the analysis, published in , changing conditions may also affect regions of West and Central Africa that are not currently considered at risk.

    The paper concludes that with current rates of economic growth and high emissions, the total epidemic-prone area could expand by a fifth. At even higher levels of emissions, it could expand by a third.

    The scientists behind the work say their modelling, which was undertaken in 2018, has already successfully predicted the currently underway in the Democratic Republic of Congo that has claimed more than 2,000 lives.

    With this in mind, they say the analysis should lay the groundwork for targeted Ebola vaccine programmes and healthcare infrastructure in Africa, including regions previously thought to be unaffected.

    Modelling everything

    First identified in 1976, Ebola around the world in 2014 when of epidemic proportions killed thousands of people in West Africa.

    The viral disease is thought to pass to humans from bats and other animal hosts in so-called “spillover events”. It is one of the many “zoonotic”, or animal-borne, diseases that make up of all human infectious diseases. 

    Once spread to humans, Ebola can be transmitted from person to person through direct contact. in humans include fever, vomiting and sometimes both internal and external bleeding. The average fatality rate is around 50%.

    Given its potential to inflict significant harm, it is vital that scientists understand when and where the next outbreak of Ebola is likely to strike so that medical resources can be directed accordingly.

    However, as there have only been around 23 confirmed outbreaks since the disease was discovered, traditional methods used to predict common infections, such as flu, are difficult.

    Instead of working from previous outbreak data, of , along with his colleague and their team, developed an outbreak risk model “from the bottom-up”. 

    They used data on a range of factors including host distribution, human population size, people’s movements by roads and air, and land use.

    , who leads the group at the and was not involved in the study, tells Carbon Brief that combining all these factors into a model is “extremely complex”. “Therefore, I am impressed by this work,” he says.

    One vital component of the analysis was climate change, which can influence disease spread both by affecting both local socioeconomic development and, as Redding tells Carbon Brief, the host species themselves:

    “In our model most of the climate effects are through better conditions for the disease-carrying species, thus increasing their native geographical range.”

    While there is still about precisely which animals pass Ebola on to humans, the prime suspects are large fruit bats that are often hunted . These creatures are known to prefer warm and wet habitats, which are expected to expand in the target regions as the climate changes.

    Other animals thought to provide alternative routes for infection, such as apes and duiker antelopes, were also considered in the analysis.

    The researchers note that climate played a less important role in their observed outcomes than poverty – which is closely tied with healthcare response – and human population size. 

    However, they also note that spillover events “increased with greenhouse gas concentrations”. Redding explains:

    “There is a positive association in our model results with increasingly more negative impact with higher emission scenarios.”

    Epidemic expansion

    The researchers developed a model that simulated animal-to-human and human-to-human transmission of Zaire Ebola virus (EBOV), the strain responsible for the West African epidemic.

    In order to gauge the impact of complex social, economic and climate factors on future Ebola transmission in Africa, the team then incorporated representative concentration pathways () and shared socio-economic pathways () into their modelling.

    RCPs broadly represent scenarios with ever-higher levels of greenhouse gases resulting from different levels of climate action. SSPs are for various socioeconomic development scenarios, involving different outcomes for global society, demographics and economics.

    (For more, see Carbon Brief’s recent on RCP8.5 and Carbon Brief’s SSP .)

    The researchers then used these models to project changes in Ebola risk across different African regions by the year 2070.

    Writing in their paper, they say their simulations suggest a “general, ongoing increase in Ebola incidence over time” for most scenarios.

    However, for scenarios involving sustainable development and extensive climate mitigation, there was a general decrease in Ebola risk (the chart below gives an idea of changing risk in different scenario combinations).

    Change in future risks of Ebola virus disease under different RCP and SSP scenarios. Each map represents mean change in “per grid cell probability” of an Ebola case from zero (yellow) to −0.06 (dark blue) and 0.06 (red), aggregated at a country level with data from the group’s model for 2070. Source: Redding et al. (2019)

    Under current conditions, the models predict an epidemic resulting from a spillover event will occur roughly once every 17 years. An epidemic was defined as an outbreak involving more than 1,500 patients.

    To arrive at this conclusion, the team ran around 1,500 yearly simulations using present day conditions and found that epidemics occurred in approximately 5.8% of them. This process was then repeated using different sets of conditions.

    The greatest increase occurs in a scenario with high emissions, high population growth and slow economic development (RCP6.0 and SSP3), with epidemics expected to occur nearly once every 10 years.

    (The likelihood of epidemics occurring under these conditions compared to present day was incorrectly described as four times more likely, instead of 1.6 times more likely, in the paper’s original abstract. The authors confirmed this after Carbon Brief contacted them about the discrepancy.)

    Under the most optimistic of the scenarios they used – which assumes moderate emissions and high development (RCP4.5 and SSP1) – the occurrence drops to roughly once every 30 years.

    A similar pattern is expected to play out for “catastrophic epidemics” affecting more than two million people. These events are currently predicted to take place once every 43 years, but the modelling suggests they will increase in frequency under high-emissions scenarios.

    The models also predict an expansion in the area at risk from outbreaks. For example, under the most optimistic socioeconomic and climate scenario, the total area where epidemics could start decreased by nearly half compared to present day (0.4m square kilometres, km2, compared to 0.8m km2).

    In comparison, in a scenario involving low climate mitigation and “middle of the road” development (RCP6.0 and SSP2), this area increased by 20.5%, Under a more extreme scenario (RCP8.5 and SSP3) this increased further, by 34%.

    Disease and climate

    While the links between climate and Ebola, Redding and his co-authors think this is the first attempt to model future transmission of the disease that takes climate change into account.

    Baylis says there has been extensive work exploring direct links between changing climate and the spread of disease – for example, in the Kenyan highlands and malaria risk. 

    However, while work from his own group has suggested of infectious diseases are susceptible to climate, he says identifying these links can be challenging:

    “Attribution is difficult, because we are really saying that climate change increases the probability of an event, but extreme events are expected even without climate change.”

    It is worth noting that while many infectious diseases are transmitted via the environment (by way of water or soil, for example), Ebola moves via direct contact between hosts. This means while bats and humans are affected directly by the changing climate, the virus itself is less susceptible to a changing climate.

    The paper concludes that global commitments to tackle climate change may drive down Ebola cases. However, it is not optimistic about this outcome, noting “evidence suggests a wholesale change is unlikely”:

    “Efforts to decrease poverty in Central and Western Africa with a concomitant increase in healthcare resources, therefore, would appear to be the most realistic approach to reducing future Ebola virus disease risk globally.”

    Future response

    Besides accurately identifying the known endemic area for Ebola, the modelling also identifies countries such as Nigeria, Ghana and Kenya as vulnerable to both small spillovers and epidemics of Ebola, despite never having been the source of such outbreaks before.

    The team says their approach “somewhat contradict[s] analyses based on current case data”.

    According to Baylis, the team’s validation of past outbreaks using the new approach increases confidence in future predictions, but notes the models are still “likely constrained by the quality of our knowledge of Ebola hosts, which is not high”.

    Besides identifying a “much larger” area within Africa that is vulnerable to spillover events, the team also incorporated information about airline routes and concluded that China, Russia, India, the US and many European countries were at risk of importing the disease.

    According to Redding, their work “acts as a call” for both a better understanding of where Ebola outbreaks could hit, plus the need for cooperation between wealthier and poorer countries to improve healthcare resources in preparation. He concludes:

    “Such an approach is a no-lose situation as better containment facilities and barrier nursing, for example, could protect nations and their neighbours against many different future disease outbreaks, not just Ebola.”

    ※ 全文及圖片詳見:()

    ※ 論文資料:Redding, D. et al. (2019) Impacts of environmental and socio-economic factors on emergence and epidemic potential of Ebola in Africa, Nature Communications,

    作者

    如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

    於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※超省錢租車方案

    ※教你寫出一流的銷售文案?

    網頁設計最專業,超強功能平台可客製化

  • 用剛果童工挖鈷致死或殘 5科技巨頭挨告

    摘錄自2019年12月17日聯合報報導

    特斯拉、蘋果、微軟、戴爾、Google母公司字母(Alphabet)以共謀罪名被告上法庭。這是科技業首次因其鈷來源,共同面臨法律訴訟。

    代表剛果民主共和國14個家庭擔任原告的美國人權組織「國際權利倡議」(International Rights Advocates)15日提告五家全球大型科技公司,指強迫勞動的體系導致這些家庭的小孩死亡或重傷,而五家科技業者是這個體系的一部分。

    這起訴訟說,案件裡的兒童,最小的才6歲,因為出身赤貧家庭,不得不休學到嘉能可的礦坑挖鈷。他們每周要工作六天,有些人領的日薪低到只有1.5美元(約台幣45元)。

    鈷是製造科技產品內部可重複使用鋰電池的必要材料。全球一半以上的鈷產自剛果民主共和國。根據歐盟執委會2018年的一份研究,未來10年全球鈷需求料將每年增加7%到13%。原告主張,挨告的科技業者全都有能力徹底整頓旗下鈷供應鏈,以確保更安全的工作條件。

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※教你寫出一流的銷售文案?

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※回頭車貨運收費標準

    ※別再煩惱如何寫文案,掌握八大原則!

    ※超省錢租車方案

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 跟殺蟑盒一樣的殺蜂盒 日網友:不分蜂類都傷害到怎麼辦呢?

    文:宋瑞文

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※超省錢租車方案

    ※別再煩惱如何寫文案,掌握八大原則!

    ※回頭車貨運收費標準

    ※教你寫出一流的銷售文案?

    FB行銷專家,教你從零開始的技巧

  • 龍芯團隊完成CoreCLR MIPS64移植,已在github開源

    龍芯團隊完成CoreCLR MIPS64移植,已在github開源

    國產龍芯的軟件生態之中.NET不會缺席,畢竟 C# 與 .NetCore/Mono 也是全球幾大主流的編程語言和運行平台之一,最近一段時間聽到太多的鼓吹政務領域不支持.NET, 大家都明白這是某些人為了自己的利益打壓使用.NET技術的公司,我今天寫這篇文章就是想通過龍芯團隊的行動告訴更多人一起來推動.NET技術在中國的發展。希望龍芯廠商、支持龍芯的國產操作系統廠商能高度重視這個問題,主動加入 .Net Core 社區,加入.NET基金會,积極貢獻代碼,儘快做好適配工作。

    龍芯團隊一直在做net core的mips64移植工作,2020年6月18日完成了里程碑性的工作,在.NET Core 3.1分支上完成了MIPS64 的移植工作,目前已經在github上開源,開源地址:https://github.com/gsvm/coreclr 。具體說明可以參見 https://github.com/dotnet/runtime/issues/38069。 龍芯團隊正在做移植后的測試工作,已經完成了 9500 多項測試,ASP.NET Core示例程序 FlightFinder 已經可以在MIPS64 上正常運行,具體可以參看 https://github.com/dotnet/runtime/issues/4234。

    龍芯團隊還在github上面為龍芯.NET 建立了一個倉庫 https://github.com/gsvm/loongson-dotnet,用於關於龍芯的.NET信息,工作和下載,開源協議採用和.NET Core一樣的MIT協議。 根據這個倉庫的信息,龍芯團隊將在不久的將來發布.NET Core 3.1版本,然後升級到https://github.com/dotnet/runtime ,也就是.NET 5了。目前這項工作正在緊鑼密鼓的進行,非常歡迎大家的積极參与貢獻,包括issue或者PR,如果您有任何問題或需要任何支持,請隨時提交問題或通過电子郵件:aoqi@loongson.cn 與龍芯團隊聯繫。

    在文章的最後,我向你分享一個龍芯團隊成員 xiangzhai 在這個 https://github.com/xiangzhai/mono/issues/2 提到了指令集相關的編程的一些相關知識:

    OpenJDK、CorelCLR、mono都太大了,比較小的虛擬機例子可以看看PSP模擬器: https://github.com/xiangzhai/ppsspp-jit-mips64/commits/mips64-port-dev

    CoreCLR官方的文檔不錯:下降、寄存器分配、代碼生成 https://github.com/dotnet/runtime/blob/master/docs/design/coreclr/jit/ryujit-overview.md

    CoreCLR代碼生成常用調試方法: dotnet/runtime#606

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計最專業,超強功能平台可客製化

  • Thunk函數的使用

    Thunk函數的使用

    編譯器的求值策略通常分為傳值調用以及傳名調用,Thunk函數是應用於編譯器的傳名調用實現,往往是將參數放到一個臨時函數之中,再將這個臨時函數傳入函數體,這個臨時函數就叫做Thunk 函數。

    求值策略

    編譯器的求值策略通常分為傳值調用以及傳名調用,在下面的例子中,將一個表達式作為參數進行傳遞,傳值調用以及傳名調用中實現的方式有所不同。

    var x = 1;
    
    function s(y){
        console.log(y + 1); // 3
    }
    
    s(x + 1);
    

    在上述的例子中,無論是使用傳值調用還是使用傳名調用,執行的結果都是一樣的,但是其調用過程不同:

    • 傳值調用:首先計算x + 1,然後將計算結果2傳遞到s函數,即相當於調用s(2)
    • 傳名調用:直接將x + 1表達式傳遞給y,使用時再計算x + 1,即相當於計算(x + 1) + 1

    傳值調用與傳名調用各有利弊,傳值調用比較簡單,但是對參數求值的時候,實際上還沒用到這個參數,有可能造成沒有必要的計算。傳名調用可以解決這個問題,但是實現相對來說比較複雜。

    var x = 1;
    
    function s(y){
        console.log(y + 1); // 3
    }
    
    s(x + 1, x + 2);
    

    在上面這個例子中,函數s並沒有用到x + 2這個表達式求得的值,使用傳名調用的話只將表達式傳入而並未計算,只要在函數中沒有用到x + 2這個表達式就不會計算,使用傳值調用的話就會首先將x + 2的值計算然後傳入,如果沒有用到這個值,那麼就多了一次沒有必要的計算。Thunk函數就是作為傳名調用的實現而構建的,往往是將參數放到一個臨時函數之中,再將這個臨時函數傳入函數體,這個臨時函數就叫做Thunk 函數。

    var x = 1;
    
    function s(y){
        console.log(y + 1); // 3
    }
    
    s(x + 1);
    
    // 等同於
    
    var x = 1;
    
    function s(thunk){
        console.log(thunk() + 1); // 3
    }
    
    var thunk = function(){
        return x + 1;
    }
    
    s(thunk);
    

    Js中的Thunk函數

    Js中的求值策略是是傳值調用,在Js中使用Thunk函數需要手動進行實現且含義有所不同,在Js中,Thunk函數替換的不是表達式,而是多參數函數,將其替換成單參數的版本,且只接受回調函數作為參數。

    // 假設一個延時函數需要傳遞一些參數
    // 通常使用的版本如下
    var delayAsync = function(time, callback, ...args){
        setTimeout(() => callback(...args), time);
    }
    
    var callback = function(x, y, z){
        console.log(x, y, z);
    }
    
    delayAsync(1000, callback, 1, 2, 3);
    
    // 使用Thunk函數
    
    var thunk = function(time, ...args){
        return function(callback){
            setTimeout(() => callback(...args), time);
        }
    }
    
    var callback = function(x, y, z){
        console.log(x, y, z);
    }
    
    var delayAsyncThunk = thunk(1000, 1, 2, 3);
    delayAsyncThunk(callback);
    

    實現一個簡單的Thunk函數轉換器,對於任何函數,只要參數有回調函數,就能寫成Thunk函數的形式。

    var convertToThunk = function(funct){
      return function (...args){
        return function (callback){
          return funct.apply(this, args);
        }
      };
    };
    
    var callback = function(x, y, z){
        console.log(x, y, z);
    }
    
    var delayAsyncThunk = convertToThunk(function(time, ...args){
        setTimeout(() => callback(...args), time);
    });
    
    thunkFunct = delayAsyncThunk(1000, 1, 2, 3);
    thunkFunct(callback);
    

    Thunk函數在ES6之前可能應用比較少,但是在ES6之後,出現了Generator函數,通過使用Thunk函數就可以可以用於Generator函數的自動流程管理。首先是關於Generator函數的基本使用,調用一個生成器函數並不會馬上執行它裏面的語句,而是返回一個這個生成器的迭代器iterator 對象,他是一個指向內部狀態對象的指針。當這個迭代器的next()方法被首次(後續)調用時,其內的語句會執行到第一個(後續)出現yield的位置為止,yield后緊跟迭代器要返回的值,也就是指針就會從函數頭部或者上一次停下來的地方開始執行到下一個yield。或者如果用的是yield*,則表示將執行權移交給另一個生成器函數(當前生成器暫停執行)。

    function* f(x) {
        yield x + 10;
        yield x + 20;
        return x + 30;
    }
    var g = f(1);
    console.log(g); // f {<suspended>}
    console.log(g.next()); // {value: 11, done: false}
    console.log(g.next()); // {value: 21, done: false}
    console.log(g.next()); // {value: 31, done: true}
    console.log(g.next()); // {value: undefined, done: true} // 可以無限next(),但是value總為undefined,done總為true
    

    由於Generator函數能夠將函數的執行暫時掛起,那麼他就完全可以操作一個異步任務,當上一個任務完成之後再繼續下一個任務,下面這個例子就是將一個異步任務同步化表達,當上一個延時定時器完成之後才會進行下一個定時器任務,可以通過這種方式解決一個異步嵌套的問題,例如利用回調的方式需要在一個網絡請求之後加入一次回調進行下一次請求,很容易造成回調地獄,而通過Generator函數就可以解決這個問題,事實上async/await就是利用的Generator函數以及Promise實現的異步解決方案。

    var it = null;
    
    function f(){
        var rand = Math.random() * 2;
        setTimeout(function(){
            if(it) it.next(rand);
        },1000)
    }
    
    function* g(){ 
        var r1 = yield f();
        console.log(r1);
        var r2 = yield f();
        console.log(r2);
        var r3 = yield f();
        console.log(r3);
    }
    
    it = g();
    it.next();
    

    雖然上邊的例子能夠自動執行,但是不夠方便,現在實現一個Thunk函數的自動流程管理,其自動幫我們進行回調函數的處理,只需要在Thunk函數中傳遞一些函數執行所需要的參數比如例子中的index,然後就可以編寫Generator函數的函數體,通過左邊的變量接收Thunk函數中funct執行的參數,在使用Thunk函數進行自動流程管理時,必須保證yield后是一個Thunk函數。
    關於自動流程管理run函數,首先需要知道在調用next()方法時,如果傳入了參數,那麼這個參數會傳給上一條執行的yield語句左邊的變量,在這個函數中,第一次執行next時並未傳遞參數,而且在第一個yield上邊也並不存在接收變量的語句,無需傳遞參數,接下來就是判斷是否執行完這個生成器函數,在這裏並沒有執行完,那麼將自定義的next函數傳入res.value中,這裏需要注意res.value是一個函數,可以在下邊的例子中將註釋的那一行執行,然後就可以看到這個值是f(funct){...},此時我們將自定義的next函數傳遞后,就將next的執行權限交予了f這個函數,在這個函數執行完異步任務后,會執行回調函數,在這個回調函數中會觸發生成器的下一個next方法,並且這個next方法是傳遞了參數的,上文提到傳入參數後會將其傳遞給上一條執行的yield語句左邊的變量,那麼在這一次執行中會將這個參數值傳遞給r1,然後在繼續執行next,不斷往複,直到生成器函數結束運行,這樣就實現了流程的自動管理。

    function thunkFunct(index){
        return function f(funct){
            var rand = Math.random() * 2;
            setTimeout(() => funct({rand:rand, index: index}), 1000)
        }
    }
    
    function* g(){ 
        var r1 = yield thunkFunct(1);
        console.log(r1.index, r1.rand);
        var r2 = yield thunkFunct(2);
        console.log(r2.index, r2.rand);
        var r3 = yield thunkFunct(3);
        console.log(r3.index, r3.rand);
    }
    
    function run(generator){
        var g = generator();
    
        var next = function(data){
            var res = g.next(data);
            if(res.done) return ;
            // console.log(res.value);
            res.value(next);
        }
    
        next();
    }
    
    run(g);
    

    每日一題

    https://github.com/WindrunnerMax/EveryDay
    

    參考

    https://www.jianshu.com/p/9302a1d01113
    https://segmentfault.com/a/1190000017211798
    http://www.ruanyifeng.com/blog/2015/05/thunk.html
    

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計最專業,超強功能平台可客製化

  • Spring中基於xml的AOP

    Spring中基於xml的AOP

    1、Aop 全程是Aspect Oriented Programming 即面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的同一維護的一種技術。Aop是oop的延續,是軟件開發中的 一個熱點,也是Spring框架中一個重要的內容。是函數式編程的一個衍生範例,利用Aop可以對業務邏輯各個部分進行分割,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用行,提高了開發效率。簡單的說就是把我們程序中的重複代碼抽取出來,在需要執行的時候,使用動態代理的技術,在不修改源碼的基礎上已有的方法進行增強,(使用動態代理的方式實現)

    相關術語

    JoinPoint:鏈接點 那些被攔截到的點,在spring中,這些點指的是方法,因為spring只支持方法類型的連接點

    Pointcut:切入點   是指我們要對哪些JoinPont進行攔截的定義

    Advice:通知/增強  攔截到Joinpoint之後所要做的事情就是通知

    通知類型:前置通知、後置通知、異常通知、最終通知、環繞通知

    Introduction:引介   是一種特殊的通知,在不修改類代碼的前提下,Introduction可以在運行期為類動態的添加一些方法或field

    Target:目標對象,代理的目標對象

    Weaving 織入   是指把增強應用到目標對象來創建新的代理對象的過程,spring採用動態代理織入,而AspectJ採用編譯期織入和類裝載期織入

    Proxy:代理,一類類被Aop織入增強后,就產生一個結果代理類

    Aspect:切面   是切入點和通知(引介)的結合

    在 spring 中,框架會根據目標類是否實現了接口來決定採用哪種動態代理的方式。

    基於XMl的AOP步驟

    1、創建Maven項目引入spring坐標

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mingqi</groupId>
        <artifactId>SpringIOC</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.7</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </project>

    2、創建業務層接口:

    package com.mingqi.services;
    public interface IAccountService {
        /**
         * 模擬登陸賬戶
         */
        void saveAccount();
    
        /**
         * 模擬更新賬戶
         * @param id
         */
        void updateAccount(int id);
    
        /**
         * 模擬刪除賬戶
         * @return
         */
        int deleteAccount();
    
    }

    3.創建業務層實現類

    package com.mingqi.services.impl;
    import com.mingqi.services.IAccountService;
    public class AccountServicesImpl implements IAccountService {
        public void saveAccount() {
            System.out.println("執行了保存");
        }
    
        public void updateAccount(int id) {
            System.out.println("執行了更新"+id);
        }
    
        public int deleteAccount() {
            System.out.println("執行了刪除");
            return 0;
        }
    }

    4、創建工具類

    package com.mingqi.utils;
    import org.aspectj.lang.ProceedingJoinPoint;
    /**
     * 用戶記錄日誌的工具類,裏面提供公共的代碼
     */
    public class Logger {
        /**
         * 用於打印日誌:計劃讓其在切入點方法執行前執行(切入點方法就是業務層方法)
         */
        public  void beforePrintLog(){
            System.out.println("Logger類中的pringLog方法開始記錄日誌了。。。");
        }
        public  void afterReturningPrintLog()
        {
            System.out.println("後置通知Logger類中的beforePrintLog方法開始記錄日誌了。。。");
        }
        /**
         * 異常通知
         */
        public void afterThrowingPrintLog()
        {
            System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日誌了。。。");
    
        }
        /**
         * 最終通知
         */
        public void afterPrintLog()
        {
            System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日誌了。。。");
        }
    
        /**
         * 環繞通知
         * 問題  當我們配置了環繞通知以後,切入點方法沒有執行,而通知方法執行了
         * 分析: 通過對比動態代理中的環繞通知代碼,發現動態代理中的環繞通知有明確的切入點方法調用,而我們的代碼中沒有
         * 解決: Spring 框架為我們提供了一個接口:ProceedingJoinPoint。該接口有一個方法proceed(),此方法就相當於明確調用切入點的方法
         *        該接口可以作為環繞通知的參數方法,在程序執行時,spring框架會為我們提供該接口的實現類供我們使用
         * spring中的環繞通知
         *      他是spring框架為我們提供的一種可以在代碼中手動控制增強方法何時會執行的方式
         * @param pjp
         * @return
         */
        public Object aroundPringLog(ProceedingJoinPoint pjp){
            Object rtValue = null;
            try{
                Object[] args = pjp.getArgs();//得到方法執行所需的參數
    
                System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。前置");
    
                rtValue = pjp.proceed(args);//明確調用業務層方法(切入點方法)
    
                System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。後置");
    
                return rtValue;
            }catch (Throwable t){
                System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。異常");
                throw new RuntimeException(t);
            }finally {
                System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。最終");
            }
        }
    }

    4、創建bean配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
           <!-- 配置spring的IOC,把service對象配置進來-->
           <bean id="accountSevice" class="com.mingqi.services.impl.AccountServicesImpl"></bean>
           <!-- spring 中基於xml的Aop配置步驟
             1、把通知Bean也交給spring來管理
             2、使用aop:config標籤表名開始aop的配置
             3、使用aop:aspect標籤表明配置切面
                 id屬性:是給切面提供一個唯一標識
                 ref屬性:是指定通知類的id
             4、在aop:aspect標籤的內部使用對應的標籤來配置通知的類型
                 我們現在的示例是讓printlog方法在切入點方法執行之前執行,所以是前置通知
                 aop:before:標識前置通知
                    method屬性: 用於指定Logger類中的方法哪個是前置通知
                    pointcut屬性: 用於指定切入點表達式,該表達式的含義指的是對業務層中的哪些方法增強
                    切入點表達式的寫法:
                       關鍵字:execution(表達式)
                       表達式:  訪問修飾符 返回值 包名.包名.包名....類名.方法名(參數列表)
                       標準的寫法: public void com.mingqi.service.impl.AccountServiceImpl.saveAccount()
                       訪問修飾符可以省略:void com.mingqi.service.impl.AccountServiceImpl.saveAccount()
                       返回值可以使用通配符,標識任意返回值:* com.mingqi.service.impl.AccountServiceImpl.saveAccount()
                       包名可以使用通配符,表示任意包,但是有幾級包就需要寫幾個*  *.*.*.*.*.AccountServiceImpl.saveAccount()
                       包名可以使用..代表當前包及其子包:* *.AccountServiceImpl.saveAccount()
                       類名和方法名都可以使用*來實現統配 * *..*.*();
                       參數列表: 可以直接寫數據類型:
                                     基本類型直接寫名稱:int
                                     引用類型寫包名.類名的方式: java.lang.String
                                    可以使用通配符來標識任意類型,單必須有參數
                                    可以使用..標識有無參數均可,有參數可以是任意類型
    
                          全通配寫法:
                        * *..*.*(..)
                       實際開發中 切入點表達式的通常寫法:
                              切到業務層實現類的所有方法,* com.mingqi.service.impl.*.*(..);
             -->
           <!-- 配置Logger類-->
           <bean id="logger" class="com.mingqi.utils.Logger"></bean>
           <!--使用aop:config標籤表名開始aop的配置-->
           <aop:config>
                  <aop:pointcut id="pt1" expression="execution(* com.mingqi.services.impl.*.*(..))"></aop:pointcut>
                  <!--使用aop:aspect標籤表明配置切面-->
                  <aop:aspect id="LogAdvice" ref="logger">
                         <!-- 配置前置通知:在切入點方法執行之前執行
                         <aop:before method="beforePrintLog" pointcut-ref="pt1"></aop:before>-->
    
                         <!-- 配置後置通知:在切入點方法正常執行之後值。它和異常通知永遠只能執行一個
                              <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after-returning>-->
                         <!-- 配置異常通知:在切入點方法執行產生異常之後執行。它和後置通知永遠只能執行一個
                             <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>-->
                         <!-- 配置最終通知:無論切入點方法是否正常執行它都會在其後面執行
                            <aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>-->
                         <!-- 配置環繞通知 詳細的註釋請看Logger類中-->
                            <aop:around method="aroundPringLog" pointcut-ref="pt1"></aop:around>
                        </aop:aspect>
                 </aop:config>
           </beans>

    6、創建測試類

    package com.mingqi.test;
    import com.mingqi.services.IAccountService;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class SpringIoc {
        @Test
        public void TestAccount()
        {
            ApplicationContext ac= new ClassPathXmlApplicationContext("beam.xml");
            IAccountService accountService=(IAccountService) ac.getBean("accountSevice");
            accountService.saveAccount();
            accountService.updateAccount(22);
            accountService.deleteAccount();
        }
    }

     

     

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計最專業,超強功能平台可客製化

  • 【服務器】VMware Workstation Pro虛擬機搭建本地服務器CentOs7和寶塔面板(保姆式教程)

    【服務器】VMware Workstation Pro虛擬機搭建本地服務器CentOs7和寶塔面板(保姆式教程)

    內容繁多,請耐心跟着流程走,在過程中遇到問題請在下面留言(我只是小白,請專業人士噴輕點)。

    前言

    這幾天一直在複習thinkphp5.1,學習環境是phpStudy8.1,但是遇到了文件有緩存的問題(thinkphp5.1.39,修改文件后刷新沒有效果那種,需要隔幾分鐘才正常),百度也沒有解決方法,搞了幾天,一直沒解決,就氣着去折騰本地虛擬機服務器,使用阿里雲的CentOs7鏡像(本站的服務器也是阿里雲的CentOs7,運維環境也是寶塔哦),運維環境是寶塔面板

    說到寶塔就有一些故事了,買服務器的時候是想用windows server2008的,配置了IIS一段時間,搞不定,然後往nginx方向走,又搞不定,後來用windows寶塔面板,還是搞不定,不管怎麼折騰都沒辦法搞定,網站一直打不開,然後就轉CentOs7了,安裝寶塔,配置域名,訪問域名,網站就可以显示了,回想當初,不知道自己腦子抽了哪條經。

    工具

    • VMware Workstation Pro 15.5.5(虛擬機,自己去下載安裝哦,安裝步驟:下一步,我同意,修改安裝路徑,下一步,完成)

    • CentOs7(iso鏡像,推薦使用IDM或者迅雷下載,鏡像大小4.6GB上下)
      阿里雲鏡像:http://mirrors.aliyun.com/centos/7.8.2003/isos/x86_64/

    • Xshell(用於連接虛擬機,方便使用Linux命令,是一個遠程工具,右鍵就可以複製粘貼哦,還可以拉滾動條。)

    查看並保持vmnet8 ip

    本地vmnet8 ip

    查看本地的vmnet8 ip(安裝好虛擬機后才會自動生成的),打開cmd輸入ipconfig
    按win鍵+R,輸入cmd,回車就能打開cmd

    或者按win鍵+S,搜索“cmd”,也能打開“命令提示符”

    還有左下角的“田”形右鍵,然後選擇“Windows Powershell”;
    還有Git的Git Bash等等。。。。。。。。。。。。。。。。

    輸入ipconfig后,就显示下面界面

    這裏主要的內容是以太網適配器VIware Network Adapter VInet8,把細框里的IPv4地址子網掩碼默認網關(我這裏沒有,我也不知道為什麼)用文本記下來,或者不關這個窗口,後面要用到的。

    虛擬機vmnet8 ip

    虛擬機裏面的虛擬網絡需要設置一下虛擬機裏面的虛擬網絡需要處理一下虛擬機裏面的虛擬網絡需要編輯一下

    下圖標記2的地方,勾勾要去掉,去掉之後點擊NAT設置,查看虛擬機的vmnet8 ip,把紅框里的子網IP子網掩碼默認網關用文本記下來,然後點擊確定。

    現在整理一下要用文本記下來的東西

    創建虛擬機

    點擊創建新的虛擬機

    點擊自定義,下一步。

    選擇虛擬機版本,我這裡是15.5.5,下一步

    點擊稍後安裝操作系統,下一步。

    選擇Linux操作系統,現在安裝的是entOs7,所以版本選擇CentOs7 64位,下一步。

    虛擬機名稱隨意,可以中文,這裏我寫的是服務器ip名(可以重命名的),為了方便定位,不用我說都懂的啦,從左邊欄就可以看出100、101、102沒有102,哎?我跳過102了?我是把流程走一遍再碼字的,碼字的時候,服務器已經ok了,不過問題不大,下一步。。。。

    默認(本站的核心是2個,但是我100、101都是1個核心,這裏默認1個核心夠用了),本地服務器,也就自己一個人訪問,而且這裏配置是跟本機電腦配置有關的,服務器一核心足矣(只要電腦帶得動,給八核我也沒意見),下一步。

    默認(本站的內存是1GB,但是我100、101都是2GB,這裏默認1GB夠用了),同上(如果在阿里雲買服務器,我建議是1核心2GB內存哦),下一步。

    點擊使用網絡地址轉換(NAT),下一步。

    默認,下一步。

    默認,下一步。

    默認,下一步。

    默認(磁盤大小自己改,20GB實際上夠了,下面選項默認),下一步。

    默認,下一步。

    點擊自定義硬件

    點擊打印機,然後點擊移除

    跟着数字的步驟走(步驟3:選擇下載好的CentOs7鏡像,我個人是推薦放在服務器根目錄下,看我圖中的路徑,這裏不明白要留言哦)。

    點擊完成

    安裝CentOs7系統

    點擊開啟此虛擬機

    這裏說一下,默認選中的是Test this this media & install CentOS 7(白色字體是選中狀態),按方向鍵↑然後回車(如果按鍵沒效果,需要把鼠標點一下虛擬機显示屏)。

    中文在最下面,滾下去或者拉到下面才看到(下面的搜索chinese),點擊繼續

    這裏看一下自己的日期和時間是不是亞洲/上海 時區,不是的話自己進去調一下(百度)。

    點擊軟件選擇

    把紅框里的兩個勾勾點上,完成。

    點擊安裝位置

    點擊我要配置分區,完成。

    點擊點這裏自動創建他們,完成。

    默認,/boot(啟動文件),swap(交換分區,類似windows虛擬內存。看內存總大小,如果內存足夠大,這個空間就要設置很大,如果內存小於2G,那麼這個空間設置成內存的2倍大小。),/(根分區),完成。

    點擊接受更改

    點擊網絡和主機名

    打開以太網,修改主機名(也闊以使用默認的啦),然後點擊應用(點完應用后看看以太網是不是關閉了,如果關閉了再點開),完成。

    點擊開始安裝

    點擊ROOT密碼

    設置密碼,我這裏設置123456(本機的,起個好記的就好),完成(點兩次)。

    等待安裝(根據自己的需求去創建用戶吧,但是創建后可能某些操作需要root權限,不折騰就不要創了,昨晚搞CentOs8服務器差點崩潰,CentOs8是規定要創建用戶的,CentOs7和CentOs8就跟windows7和windows10一樣)。

    安裝完畢,點擊重啟。

    選擇第一個。

    我的用戶名是root,密碼123456
    輸入用戶名root,回車。

    輸入密碼123456(不可見的,輸入就行了),回車。

    噔噔噔噔,革命成功

    配置服務器靜態ip(需要配置服務器動態ip的自己百度一下)

    到了這一步,你已經回不了頭了,還學會一丟丟Linux命令,建議多去看看Linux命令

    打開目錄:cd /etc/sysconfig/network-scripts/(複製粘貼就好,這個複製粘貼有點麻煩,找不到的就手敲,正是這樣才要用Xshell工具來遠程,得先配置ip,忍一忍吧),回車。

    我這裏显示的是ifcfg-ens33,這裏要說一下,我百度過,有些是32,也有1667777,先用cd /etc/sysconfig/network-scripts/進入目錄,然後ll显示列表(ls也可以显示列表,只显示列表名)。

    編輯ifcfg-ens33:vi ifcfg-ens33(vi:進入編輯模式,文件名別敲錯。),回車。

    i 字母鍵進入編輯模式(如果不显示下圖的,肯定是vi ifcfg-ens33輸入錯了,自己檢查一下,退出vi方法:按Esc(注意左下角),輸入:q!(不保存退出))。

    看圖IPADDR=192.168.157.103NETMASK=255.255.255.0GATEWAY=192.168.157.2,這裏不建議複製粘貼了,好好敲,我擔心會亂(如果一定要複製粘貼的話,先把裏面的複製出來,加上IPADDR、NETMASK、GATEWAY再粘貼回去,不知道能不能明白我的意思,咱們還是敲吧!!!)。

    保存並退出:按Esc鍵,然後輸入:wq(必須小寫),回車。

    重啟網絡:systemctl restart network,回車。
    查看ip:ip addr, 回車。
    出現下圖就可以了,萬歲。

    配置本地的網絡(只需要配置一次)

    這是本地訪問虛擬機要配置的,文本中記下來的本機ip用這裏(因為我這沒有默認網關,所以不填)。

    使用Xshell連接虛擬機服務器(右鍵就可以複製粘貼哦)

    新建會話,這裏隧道要取消轉發X11連接到:(可能會有人奇怪,為什麼這張步驟和下面步驟在正常思路來說調換了,我其實是忘了,後面才補回來的)。

    新建會話,輸入名稱192.168.157.103(輸入名稱后,下面的主機也是同步的。),然後點擊連接。

    出現這個彈窗就說明99.99%成功了,如果沒有就說明配置出錯,大概率在上一個步驟[配置本地的網絡(點擊跳轉)][60]

    輸入用戶名root

    輸入用戶名123456

    okay。

    安裝寶塔面板

    寶塔官網:https://www.bt.cn/
    寶塔Linux面板命令大全:https://www.bt.cn/btcode.html(一定要多看)

    這裏標註幾個常用的命令(本文章用到的):cd(不用說了吧)、clear(清屏,也可以用Ctrl+L)、ll(當前列表,詳細的展示列表),ls(當前列表,簡潔的展示列表)、vi 文件名(編輯文件,按Esc::wq保存並退出、:q(退出)、:q!強制不保存並退出)。

    安裝

    安裝腳本:yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
    PS:此腳本從官方複製過來的時間為2020年6月19日,僅限CentOs系統,如果距離已久,請到官網複製

    右鍵隨意複製粘貼,Xshell工具的好處(佛主:https://www.kancloud.cn/jiangguowu/kfjsdkfjskd/1076752)。

    DO you want to install Bt Panel tothe /www directory now?(y/n):(現在是否要將Bt面板安裝到/www目錄?(是/否):)。
    按y,回車。

    寶塔面板訪問地址:http://192.168.157.103:8888/7a81976f119.137.3.117換成192.168.157.103自己設置的服務器ip(別傻了,只有本地才能訪問)。

    username: yq0g4uxd
    password: c937d4a9

    是闊一。

    點擊一鍵安裝(也可以不選擇,然後自己去左邊的軟件商店自己選擇安裝)。

    建議設置一下安全入口面板用戶面板密碼(只能設置8位數,為了方便,我強行使用命令行將密碼設置為123456,命令:cd /www/server/panel && python tools.py panel 123456,更多的寶塔命令請到寶塔Linux面板命令大全查看:https://www.bt.cn/btcode.html)

    報錯、錯誤、問題大雜燴(此目錄處理教程中遇到的問題,請在下面留言)

    安裝寶塔 -> 14: curl#6 – “Could not resolve host: mirrorlist.centos.org; 未知的錯誤

    打開:vi /etc/resolv.conf
    加入:nameserver 8.8.8.8nameserver 8.8.4.4

    完美結束!!!

    圖片太多,碼字的時候都卡了,大概68張圖片,感覺還是錄製視頻好啊

    如果有錯誤的地方,歡迎糾正。

    我已經想好下一篇的文章了,出一個寶塔面板使用教程。

    原文鏈接:https://blog.langting.top/archives/117.html

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※想知道最厲害的網頁設計公司"嚨底家"!

    ※別再煩惱如何寫文案,掌握八大原則!

    ※產品缺大量曝光嗎?你需要的是一流包裝設計!

  • 09.DRF-ModelSerializer

    四、模型類序列化器ModelSerializer

    如果我們想要使用序列化器對應的是Django的模型類,DRF為我們提供了ModelSerializer模型類序列化器來幫助我們快速創建一個Serializer類。

    ModelSerializer與常規的Serializer相同,但提供了:

    • 基於模型類自動生成一系列字段
    • 基於模型類自動為Serializer生成validators,比如unique_together
    • 包含默認的create()和update()的實現

    4.1 定義

    比如我們創建一個BookInfoSerializer

    class BookInfoSerializer(serializers.ModelSerializer):
        """圖書數據序列化器"""
        class Meta:
            model = BookInfo
            fields = '__all__'
    
    • model 指明參照哪個模型類
    • fields 指明為模型類的哪些字段生成

    我們可以在python manage.py shell中查看自動生成的BookInfoSerializer的具體實現

    >>> from booktest.serializers import BookInfoSerializer
    >>> serializer = BookInfoSerializer()
    >>> serializer
    BookInfoSerializer():
        id = IntegerField(label='ID', read_only=True)
        btitle = CharField(label='名稱', max_length=20)
        bpub_date = DateField(allow_null=True, label='發布日期', required=False)
        bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=-2147483648, required=False)
        bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=-2147483648, required=False)
        image = ImageField(allow_null=True, label='圖片', max_length=100, required=False)
    

    4.2 指定字段

    4.2.1) 使用fields來明確字段,__all__表名包含所有字段,也可以寫明具體哪些字段,如

    class BookInfoSerializer(serializers.ModelSerializer):
        """圖書數據序列化器"""
        class Meta:
            model = BookInfo
            fields = ('id', 'btitle', 'bpub_date')
    

    4.2.2) 使用exclude可以明確排除掉哪些字段

    class BookInfoSerializer(serializers.ModelSerializer):
        """圖書數據序列化器"""
        class Meta:
            model = BookInfo
            exclude = ('image',)
    

    4.2.3) 默認ModelSerializer使用主鍵作為關聯字段,但是我們可以使用depth來簡單的生成嵌套表示,depth應該是整數,表明嵌套的層級數量。如:

    class HeroInfoSerializer2(serializers.ModelSerializer):
        class Meta:
            model = HeroInfo
            fields = '__all__'
            depth = 1
    

    形成的序列化器如下:

    HeroInfoSerializer():
        id = IntegerField(label='ID', read_only=True)
        hname = CharField(label='名稱', max_length=20)
        hgender = ChoiceField(choices=((0, 'male'), (1, 'female')), label='性別', required=False, validators=[<django.core.valators.MinValueValidator object>, <django.core.validators.MaxValueValidator object>])
        hcomment = CharField(allow_null=True, label='描述信息', max_length=200, required=False)
        hbook = NestedSerializer(read_only=True):
            id = IntegerField(label='ID', read_only=True)
            btitle = CharField(label='名稱', max_length=20)
            bpub_date = DateField(allow_null=True, label='發布日期', required=False)
            bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=-2147483648, required=False)
            bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=-2147483648, required=False)
            image = ImageField(allow_null=True, label='圖片', max_length=100, required=False)
    

    4.2.4) 显示指明字段,如:

    class HeroInfoSerializer(serializers.ModelSerializer):
        hbook = BookInfoSerializer()
    
        class Meta:
            model = HeroInfo
            fields = ('id', 'hname', 'hgender', 'hcomment', 'hbook')
    

    4.2.5) 指明只讀字段

    可以通過read_only_fields指明只讀字段,即僅用於序列化輸出的字段

    class BookInfoSerializer(serializers.ModelSerializer):
        """圖書數據序列化器"""
        class Meta:
            model = BookInfo
            fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
            read_only_fields = ('id', 'bread', 'bcomment')
    

    4.3 添加額外參數

    我們可以使用extra_kwargs參數為ModelSerializer添加或修改原有的選項參數

    class BookInfoSerializer(serializers.ModelSerializer):
        """圖書數據序列化器"""
        class Meta:
            model = BookInfo
            fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
            extra_kwargs = {
                'bread': {'min_value': 0, 'required': True},
                'bcomment': {'min_value': 0, 'required': True},
            }
    
    # BookInfoSerializer():
    #    id = IntegerField(label='ID', read_only=True)
    #    btitle = CharField(label='名稱', max_length=20)
    #    bpub_date = DateField(allow_null=True, label='發布日期', required=False)
    #    bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=0, required=True)
    #    bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=0, required=True)
    

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

    ※別再煩惱如何寫文案,掌握八大原則!

    ※教你寫出一流的銷售文案?

    ※超省錢租車方案

    FB行銷專家,教你從零開始的技巧

  • 一起玩轉微服務(6)——通信協議如何統一

    一起玩轉微服務(6)——通信協議如何統一

    一、接口調用

    接口調用如果是遠程調用,那麼就構成了簡單的分佈式。最簡單的遠程接口實現方式是web service或rest。當然一個合理的分佈式應用不僅僅是遠程接口調用這麼簡單。還需要有負載均衡、緩存等功能。最簡單實現分佈式的技術是Rest接口,因為Rest接口可以使用現存的各種服務器,比如負載均衡服務器和緩存服務器來實現負載均衡和緩存功能。

    二、統一通信協議

    關於通信協議,不同的公司有不同的選擇,但是建議同一公司內部使用統一的通信協議,比較典型的有grpc和brpc。

    1. gRPC簡介

    gRPC是Google發布的基於HTTP 2.0傳輸層協議承載的高性能開源軟件框架,提供了支持多種編程語言的、對網絡設備進行配置和納管的方法。由於是開源框架,通信的雙方可以進行二次開發,所以客戶端和服務器端之間的通信會更加專註於業務層面的內容,減少了對由gRPC框架實現的底層通信的關注。如下圖,DATA部分即業務層面內容,下面所有的信息都由gRPC進行封裝。

     

     

    grpc是一個高性能、開源和通用的 RPC 框架,面向移動和 HTTP/2 設計。目前提供 C、Java 和 Go 語言版本,分別是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.
    grpc基於 HTTP/2 標準設計,帶來諸如雙向流、流控、頭部壓縮、單 TCP 連接上的多復用請求等特。這些特性使得其在移動設備上表現更好,更省電和節省空間佔用。
    關於具體gRPC報文的結構,可以參考下圖:

     

     

    下面展示一下gRPC的交互過程

     

     

    1. 交換機在開啟gRPC功能后充當gRPC客戶端的角色,採集服務器充當gRPC服務器角色;
    2. 交換機會根據訂閱的事件構建對應數據的格式(GPB/JSON),通過Protocol Buffers進行編寫proto文件,交換機與服務器建立gRPC通道,通過gRPC協議向服務器發送請求消息;
    3. 服務器收到請求消息后,服務器會通過Protocol Buffers解譯proto文件,還原出最先定義好格式的數據結構,進行業務處理;
    4. 數據梳理完后,服務器需要使用Protocol Buffers重編譯應答數據,通過gRPC協議向交換機發送應答消息;
    5. 交換機收到應答消息后,結束本次的gRPC交互。

    上圖展示的是gRPC交互過程的具體流程,這也是Telemetry觸發方式其中之一,稱為Dial-out模式。簡單地說,gRPC就是在客戶端和服務器端開啟gRPC功能后建立連接,將設備上配置的訂閱數據推送給服務器端。

    2. brpc

    與grpc類似,brpc源自百度,目前支撐百度內部大約 75 萬個同時在線的實例。
    其實基於以上的幾種選擇都能夠完成高效的開發,團隊內部使用統一的標準,這樣更有利於模塊化和統一標準。
    服務間的通信是通過輕量級的web服務,使用同步的REST API進行通信。在實際的項目應用中,一般推薦在查詢的時候使用同步機制,在增刪改使用異步的方式,結合消息隊列來實現數據的操作,以保證最終的數據一致性。
    具體可以使用BRPC做如下

    1. 搭建能在一個端口支持多協議的服務, 或訪問各種服務
    2. Server能同步或異步處理請求
    3. Client支持同步、異步、半同步,或使用組合channels簡化複雜的分庫或併發訪問
    4. 通過http界面調試服務, 使用cpu, heap, contention profilers
    5. 獲得更好的延時和吞吐
    6. 把你組織中使用的協議快速地加入brpc,或定製各類組件, 包括命名服務 (dns, zk, etcd), 負載均衡 (rr, random, consistent hashing)

    三、rest API

     

     

    REST API 應為創建、檢索、更新和刪除操作使用標準 HTTP 動詞,而且應特別注意操作是否冪等。
    POST 操作可用於創建資源。POST 操作的明顯特徵是它不是冪等的。舉例而言,如果使用 POST 請求創建資源,而且啟動該請求多次,那麼每次調用后都會創建一個新的唯一資源。
    GET 操作必須是冪等的且不會產生意外結果。具體來講,帶有查詢參數的 GET 請求不應用於更改或更新信息(而應使用 POST、PUT 或 PATCH)。
    PUT 操作可用於更新資源。PUT 操作通常包含要更新的資源的完整副本,使該操作具有冪等性。
    PATCH 操作允許對資源執行部分更新。它們不一定是冪等的,具體取決於如何指定增量並應用到資源上。例如,如果一個 PATCH 操作表明一個值應從 A 改為 B,那麼它就是冪等的。如果它已啟動多次而且值已是 B,則沒有任何效果。對 PATCH 操作的支持仍不一致。例如,Java EE7 中的 JAX-RS 中沒有 @PATCH 註釋。
    DELETE 操作用於刪除資源。刪除操作是冪等的,因為資源只能刪除一次。但是,返回代碼不同,因為第一次操作將成功 (200),而後續調用不會找到資源 (204)。

     

    四、你們怎麼解決

    不同項目組之間使用的語言有可能不同,框架有可能不同,同樣的,通信協議有可能不同,你們怎麼解決的呢?

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※別再煩惱如何寫文案,掌握八大原則!

    網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

    ※超省錢租車方案

    ※教你寫出一流的銷售文案?

    網頁設計最專業,超強功能平台可客製化