Friend C https://www.ihewro.com/ zh-CN Our life is very short, we will lose it eventually, so we might as well be bold. Tue, 28 Dec 2021 22:16:00 +0800 Tue, 28 Dec 2021 22:16:00 +0800 Handsome -- a typecho theme https://www.ihewro.com/archives/489/ https://www.ihewro.com/archives/489/ Mon, 05 Dec 2016 19:32:00 +0800 Friend C

[scode type="green"]

This website is the only way to buy handhome themes, and any other channels are illegal reselling themes.

Handsome theme has been obtained National Certified Software Copyright Certificate

[/scode]

Topic Introduction [tag] 9.2.0 [/tag]

[score type="lblue"] Please read the purchase instructions before purchasing, You can consult before purchasing
All function effects in this blog are provided by the theme [/scode]

Writing and reading, recording and reviewing, simple and powerful.

[button color="success" icon="glyphicon glyphicon-send" url=" https://handsome.ihewro.com/user.html "] handhome user community [/button]

Function introduction

[tabs]
[tab name="Multiple Styles" active="true"]

The carefully matched and designed pure white tone is suitable for various devices and resolutions. Fourteen colors and multiple layouts can be switched at will.

[album type="photos"]
 Responsive design: not just computer side design
 Top navigation
 Collapse Navigation
[/album]

Through background settings, the theme can switch between one column, two columns and three columns.

In addition, a transparent mode that is more friendly to the picture background is designed.

 New transparent mode: misty rain, hazy fog, with your favorite beautiful background

Has a preference for dark porn.

 Dark mode: darker, more focused

Simple and practical reading mode.

 Reading mode: focus on your content

[/tab]

[tab name="Time Machine"]

Handsome time machine support Web terminal, mobile terminal, WeChat official account, browser, chrome, Firefox, edge browser extension , allowing you to record at any time.

[album type="photos"]

 Time machine: recall those feelings that have not been set

 Jietu20210216-170937@2x.jpg
 Time machine label, classify what you think

[/album]

The WeChat official account also supports publishing articles to the designated category (it can be set as an encrypted category, so you can write a diary directly on the WeChat official account)

function introduce
That year today The page will display the content released on the same day in the past 24 months, recalling the past and present mood
Rss subscription On the time machine page, you can also subscribe to any other website that supports rss, and view all your following content on one page

[/tab]

[tab name="Content Encryption"]

Handsome theme provides a variety of encryption methods for expression.

The whole station is encrypted, and only space is private.

 All site encryption: the black domain in the Internet

Encrypt a category separately.

 Classified encryption: encrypt a certain category separately to hide your own moods

An article is encrypted.

 Article encryption: single article is more free

function introduce
All station encryption After setting the password, it is required to enter the password to access all pages in the front desk of the whole station
Classified encryption After the password is set, all articles of the current category can be accessed only after the password is entered. It also supports encryption of the specified date range of the category
Article encryption Support encryption of single article
Part of the article is visible in login Some private content can be read only after logging in
Some comments of the article are visible Don't want to be paid for nothing. Leave a comment before you leave
Comment Privacy Comment Visible to reviewers and logged in users, applicable to some information comments involving reviewer privacy

[/tab]

[tab name="Writing and typesetting"]

For the first time, the handhome theme transplanted the vditor modern markdown editor into the typecho blog, perfectly supporting the corresponding functions of attachment upload and theme, making image upload and text writing more comfortable.

 Vditor editor: modern article editor

function introduce
Support article format copying If you want to reprint a good article, you can copy it directly to keep the format consistent with the original article
Automatic uploading of pictures included in the clipboard Reprint an article from someone else, but also want to upload the image to your own server. Now everything is automatic
Copy image upload Ctrl+c ctrl+v complete

The article provides up to 20 kinds of short codes to improve the text typesetting experience, which can be visually edited in the editor.

[hplayer media="netease" id="483983380" type="song" size="large" /]

Insert a player in the article to support cloud resolution of songs (Netease Cloud, Xiami, Kugou, Baidu Music)

[vplayer url=" https://ihewro.github.io/sample_640x360.mp4 " /]

Insert local video resources (such as. mp4) into the article

[vplayer]
[Video url=" https://www.bilibili.com/video/BV1Bi4y1d7if "Title=" Sorry Louis C.K.: Sorry (2021) "/]
[Video url=" https://www.bilibili.com/video/BV1RL4y1J7wJ "Title=" A chord "/]
[/vplayer]

Insert a third-party resolution video (or collection, you can customize the resolution address) in the article

[post cid="152" /]

Insert references from other articles in the article (supports large and small styles)

[collapse status="true" title="shrink box"]

These words can not be displayed by default. Click the title to expand

[/collapse]

[timeline title="2020 memorabilia" type="small" start="where dreams begin" end="the new year begins"]
[item date="2020-1-20"] Wuhan was closed, and the epidemic situation made people panic [/item]
[item date="2020-3-20"] Start telecommuting and slowly get organized [/item]
[item color="light"] Life is getting better [/item]
[item date="2020-10-1"] Travel to Harbin on National Day to meet old classmates [/item]
[/timeline]

Timeline

[goal title="Small target of 2021"]
[item check="true"] Go to bed early every day [/item]
[item check="false"] Get up early every day [/item]
[item progress="50%"] Read 10 books [/item]
[item start="2021-01-02" end="2022-10-1"] Exercise for 30 minutes every day [/item]
[/goal]

schedule

[link]
[item name="Baidu Some" link=“ http://baidu.com "Desc=" Baidu will tell you "/]
[item name="Site Name" link=“ http://example.com "Desc=" Some link descriptions "/]
[/link]

Link Card

[column]
[block] [score type="share" size="small"] Front end/client/background development [/score]

  • Web site
  • IOS/Android development/WeChat applet
  • Background management system/crawler
    [/block]

[block] [score type="blue" size="small"] Language [/score]

  • Python/php/JavaScript
  • Java/Scala
  • c++/c
    [/block]
    [/column]

Column display

[score type="share"] Edit the label content here [/score]

[score type="yellow" size="simple"] Edit the label content here, but do not display the icon [/score]

[score type="red" size="small"] Edit the label content here. No icon is displayed and the margin is smaller, suitable for text background [/score]

Highlight reference (with 5 different icons and their colors)

[/tab]

[tab name="Customization and beautification"]

Like to change, not stick to the existing settings. Handhome background settings make everything easier.

 Background settings: powerful background settings, no need to know the code details, arbitrary manipulation of your own blog

The rich tutorials provided by handsome users are in the user community:

[button color="success" icon="glyphicon glyphicon-send" url=" https://handsome.ihewro.com/user.html "] handhome user community [/button]

Detailed installation and use documents:

[button color="success" icon="glyphicon glyphicon-file" url=" https://handsome.ihewro.com "] Handsome Theme Installation and Use Instruction Document [/button]

[/tab]

[tab name="Featured Functions"]

Ajax search, highlighting search terms

 Instant search: more timely and more useful

Audio and video player

function introduce
Integrated music player The theme has a built-in top global player (switching pages will not be interrupted) and a player inserted into the article to add more colors to the article. The player supports cloud resolution of Netease Cloud, QQ Music, Xiami Music and Baidu Music.
Built in video player Many bloggers are life bloggers, hoping to show some life videos on the broadcast. The theme has a built-in video player, but only supports playback .mp4. .avi .mkv And other video file suffixes.

Album category

 Photo album: share your happy moments with everyone

Chart statistics

You can clearly view the blog dynamics in the past 10 months and the number of blog posts, categories, and tags through the chart.

 Chart statistics: make everything visual

[/tab]

[tab name="Other Functions"]

Most of the functions and themes have been built in, and switches are provided to reduce the trouble of finding plug-in adaptations. Let you focus on creating without being disturbed by other trivia.

Handsome has submitted more than 800 records since its release, and user feedback enables Handsome to do better.

function introduce
Article Tree Make the article structure clearer and support the screen size of computers and mobile phones
Code highlighting Applicable to users who need to display code
Mathjax formula support For users related to mathematical formulas
Picture light box Pop up window of pictures, more convenient for zooming in and downloading pictures
Picture delay loading Delay loading pictures in posts and blogs
Sticky Posts Display some of your articles on the top
Support CDN and image space acceleration Support image space to automatically replace pictures and static resource addresses in articles as your static space address
Support cdn image thumbnail automatic processing size If your cdn supports image processing, you can use the theme switch to automatically zoom the image size of the article and home page, so as to save more user traffic and improve speed and smoothness
Text layout enhancement Buttons can be inserted into articles, and other articles can be referenced to display in the form of article blocks. Articles can be inserted into expansion boxes, tab boxes, videos, music, highlighted references, labels, and photo albums
Article screenshot One button automatically generates the article sharing card, which is simple and good-looking.
Smooth Scrolling Make your mouse scroll more smoothly
Album module Simple creation method, supporting external link and internal link pictures
Bean Paste List Time machine Article archiving Message Board Friendly Links Github project Enrich the website module
Header rich customization The article can be illustrated or not It's up to you to simply send a life diary or officially publish a beautifully typeset article
Automatic identification of outer chain Small icons are automatically added to the external chain, and a new window is opened, while the link of this site is not refreshed and opened
Resources that do not need homepage rendering will be dynamically loaded Both code highlighting and mathjax dynamically load js only on the article page, and images of the emoticon and reward modules will only be loaded when the user clicks, so as to minimize the number of requests and speed up access
Local cache function Based on service work technology, visitor browser level caching will be realized. After opening the blog for the first time, the blog's js and css will be automatically cached. Subsequent visits will only pull a small amount of resources away, making the access speed reach the peak
Powerful usage documentation From installation to use, FAQs to function descriptions, 99% of the topics can be answered here
More powerful background settings For the first time, complete the appearance settings and basic settings to start using If you want more free configuration, try the enhanced functions in the advanced settings. Developers can also use them; You can configure your own blog without understanding and modifying the code. Use the mouse to select and cancel
User community Customized beautification tutorials are provided by handsome users. Your blog can be more different
Work order system A problem solving platform similar to email, but also supports QQ online
And more It supports filling in the filing number, statistical code, adding custom css, html, js, pjax animation settings, and more details

[/tab]

[/tabs]

Theme purchase

programme price
personal use 88 yuan/person

[tabs]

[tab name="Purchase Method" active="true"]

[score type="lblue"] No bargaining, please indicate "Buy Handsome Theme" [/score]

[collapse title="Please click here to view the purchase instructions before purchasing" active="true" color="red" font weight="bold" status="false"]

Handsome is my amateur project, Purchase means that you understand the following rules, otherwise please do not disturb , thank you for your support and understanding:

  • Before purchase:

    • Refund not supported : Because the theme is virtual goods, no refund for any reason is supported after the source code is purchased. Please read the function description of the theme introduction page before considering whether to purchase. You can consult before purchasing
    • Master the theme : The configuration of the theme does not need to modify the code, However, it requires certain document reading ability , if you do not want to see the document, please do not buy
    • Scope of use

      • The typecho theme supports versions 1.0, 1.1, and 1.2 of typecho. Not available for WordPress , supports MySQL, sqlite, Pgsql databases, Apache, nginx servers, and PHP5.6~php8.0 versions.
      • The theme has a domain name authorization mechanism. By default, it can authorize a domain name by itself. If it is your own site, Self service modification is available (No need for me to operate). If you need to authorize other sites (for your own use), you can contact me to manually add them (without any secondary payment). It supports the authorization of external and internal network (LAN) IP and domain names
      • The theme can be modified freely for self use, Do not migrate/migrate to other systems/platforms based on handsome , otherwise, please do not buy
  • After purchase:

    • After sales content : Theme After sales is responsible for questions related to theme setting, not any after-sales questions related to server configuration and typecho installation
    • After sales response : Because it is neither a robot nor a full-time after-sales service, Therefore, you may not be able to reply immediately. I will reply to you in my spare time. You can view the usage documents first to save each other's time. 99% of the questions have been written If it is not found in the document, you can describe the problem details and screenshots as much as possible and send them to me. When you see them, you will reply, usually in In hours Internal reply. If there is no reply, please remind me again
    • Provide free upgrade and update services : Handsome is still in the update cycle. The update cycle is not fixed. If there is time, more updates will be made. For details, please refer to the update log at the end of the article
    • Personalized customization service is not supported : You can put forward any of your suggestions and ideas, but you will consider various factors comprehensively. It is not guaranteed that you will adopt them. Please understand.
  • summary : After purchase, you will get: 88 yuan= Handsome theme+supporting plug-ins+free follow-up updates+basic after-sales service (theme related)

thank!

[post cid="1189" cover="" size="small" /]

[/collapse]
[scode type="green" size="simple"] Purchase process:

  1. Scan directly first The QR code in the purchase method or payment by transfer (pre-sales consultation is available if there is any problem). Please note the contact information QQ when making payment
  2. Then contact me through the following contact information (Please note "Purchase Handsome Theme"). After seeing it, you will immediately respond to the application and process, and send the related documents of your theme through QQ

    • [button size="xs" color="info" icon="fontello fontello gradient" url="hd_ui.message ({title: 'QQ application', message: 'QQ number 3323935172 has been copied to the clipboard, you can search and add', type: 'info', time: '100000',}); if (navigator. clipboard) {navigator. clipboard. writeText ('3323935172 ');}"] QQ (3323935172) Consultation and purchase (Recommended) [/button]
    • [button size="xs" color="success" icon="glyphicon glyphicon-send" url="mailto: me@ihewro.co m"]me#ihewro.com[/button]
  3. Enjoy theme after-sales service (including issues related to theme setting)

[/scode]

[scode type="green" size="simple"] Purchase method:

 Scan QR code for payment, click to enlarge the clear version: size=60%

[/scode]

[/tab]

[/tabs]

Working with Documents

[tabs]

[tab name="Using Documents" color="red" font weight="bold" active="true"]
[button color="success" icon="glyphicon glyphicon-file" url=" https://handsome.ihewro.com "] Handsome Theme Installation and Use Instruction Document [/button]

The content mentioned in the help document will not be replied.

Please discuss non topic related issues and customized function modification issues in the exchange group

[/tab]
[tab name="Update Log"]

Due to space, only the latest log is displayed. Please refer to Handsome Theme Update Log

[collapse title="Update Log" status="false"]

[score type="green"] Update 2023-08-06 to 9.2.0 [/score]

newly added
  • The layout of the home page has been newly adjusted. The size of the head map strictly follows the 8:3 scale. Before that, there might be no resolution error, but now it is more tidy. At the same time, in different resolutions, multiple articles will be automatically selected and displayed side by side according to the width
  • Some minor adjustments have been made to the UI style layout, and more uniform UI style optimization has been carried out at many places and the bottom of the right sidebar as a whole
  • The mobile phone terminal adds a button to call up big search
  • The bottom menu supports customization. You can remove built-in buttons or add custom links! Customize bottom menu
optimization
  • Update the vditor version, optimize the automatic uploading function of the external link images, and add more error prompts
repair
  • Fix article preview white screen problem
  • Fix the image problem of the watercress list
  • Fix the problem of using the time machine browser plug-in
  • Fix separate page encryption

[/collapse]
[/tab]
[/tabs]

]]>
one thousand eight hundred and fifty-five https://www.ihewro.com/archives/489/#comments https://www.ihewro.com/feed/
CentOS sendmail module configuration https://www.ihewro.com/archives/1218/ https://www.ihewro.com/archives/1218/ Tue, 28 Dec 2021 22:16:00 +0800 Friend C install yum -y install sendmail

start-up systemctl start sendmail.service

View Status systemctl status sendmail.service

[scode type="red" size="simple"] An error is found, indicating that the domain name corresponding to the hostname cannot be recognized, because our domain name is not in a domain name format. [/scode]

 Dec 28 21:46:48 VM-0-14-centos systemd[1]: Starting Sendmail Mail Transport Agent... Dec 28 21:46:48 VM-0-14-centos sendmail[9384]: My unqualified host name (VM-0-14-centos) unknown;  slee... etry Dec 28 21:47:48 VM-0-14-centos sendmail[9384]: unable to qualify my own domain name (VM-0-14-centos) -... name Dec 28 21:47:48 VM-0-14-centos sendmail[9593]: starting daemon (8.14.7): SMTP+ queueing@01 :00:00 Dec 28 21:47:48 VM-0-14-centos systemd[1]: Started Sendmail Mail Transport Agent. Hint: Some lines were ellipsized, use -l to show in full.

Edit host file nano /etc/hosts Modify the mapping of localhost to a domain name format

 Please enter a picture description: size=50%

Restart sendmail : systemctl restart sendmail.service

Open 25 ports https://cloud.tencent.com/document/product/213/40436

stay /etc/mail.rc Configure stmp in the file

 set from= ihewro@163.com set smtp=smtp.163.com set smtp-auth-user= ihewro@163.com Set smtp auth password=******* (change to your own client authorization code here) set smtp-auth=login

Note that the password here is the authorization code, not the login password of the account

 image.png  :size=60%

Test sending echo "hello ihewro" | mail -v -s "" ihewro@163.com

[score type="green" size="simple"] So far everything has been settled. For detailed sendmail configurations, such as encrypted links or more complex sendmail configurations, refer to the following two articles:

[/scode]

]]>
zero https://www.ihewro.com/archives/1218/#comments https://www.ihewro.com/feed/
My personal experience of college enrollment in 2021 https://www.ihewro.com/archives/1217/ https://www.ihewro.com/archives/1217/ Sun, 26 Dec 2021 21:15:00 +0800 Friend C Series: [post cid="925" cover="" size="small"/]

[scode type="blue" size="simple"]

[post cid="1177" cover="" size="small"/] This article has written some experiences in job hunting. This article will record some experiences and lessons in the past year for reference only. (In fact, I wrote the manuscript in advance at the experience sharing meeting of our third research institute, and sorted it out a little.)

[/scode]

I got the internship offers from Baidu, Tencent and Byte, and finally chose Byte for internship. Due to the late preparation, QiuZhao started preparing QiuZhao after the bytes became regular, got an offer from Baidu, and finally left the bytes.

Some concepts

What is the difference between daily practice and formal (summer) practice

  • Daily internship If a group is short of people, it is likely to recruit interns all the year round, and there will be opportunities for daily internship Any student can go to the interview. However, the starting time of formal internship is relatively fixed, for example, from March to June every year, that is, summer internship.
  • Daily practice is relatively easy to enter, but some daily practice does not have the quota to become a full member. This needs to be confirmed first.
  • Byte's daily internship and formal internship are no different in becoming a regular employee. They all apply for becoming a regular employee together.

When can I go to the internship after getting the offer

After getting the offer for summer internship Can practice immediately (It usually takes about one week to follow a process), You can also choose to practice later You can control the time by yourself. Some companies can choose the time of internship on the system, and some can communicate with hr directly.

Difference between advance approval and formal approval

Take looking for internships as an example:

  • First approve in advance, and then formally approve. Generally, the group directly hires people in advance Do not enter the system No written examination The process is relatively fast When one side passes, it will be two sides soon.
  • Formal batch interviews will have face-to-face reviews. If the last failed interview review will affect the next interview, it is better to be cautious

Difference between internship offer and formal offer

In short, the internship offer is just a chance to give you an internship. If you do well during the internship, you can become a full member and get a formal offer.

Signing the formal offer does not mean going to work immediately, because we are enrolled by the university. After we get the formal offer, we can continue to practice (the salary will be the percentage of the formal salary), or we can take a leave for a period of time to work formally when we really graduate.

Time node

It is better to get your resume as soon as possible, because you are still familiar with the laboratory project, and it is not difficult to write it now. It will be more painful to write your resume in a few months.

Take last year as an example:

  • In the middle of February, Alibaba's early approval began (basically only at this time), and on March 8, Alibaba's early approval ended. Tencent's early approval started in March and ended on April 15
  • Get the internship offer from March to May, and it is better to get the internship offer in April.
  • Internship from April to August, the autumn recruitment in early July is approved in advance, and the autumn recruitment is officially approved at the end of July or early August. At the end of September, there are many fewer autumn recruitment, but relatively speaking, there are still opportunities,
  • At the end of October, the autumn moves are basically over, and there will be additional autumn moves later

  • How to find internship opportunities Personally, I think it is better to find people I know to push in. In addition to helping to see the progress, the benefits of pushing in can generally be pushed directly to the group, which can eliminate some groups with holes. Know what this group is doing in advance.
  • Internship is very important. It's better to find a company you want to go to when you are interning. It will be much easier to recruit in autumn , because there is basically no problem in becoming a regular intern. Secondly, the offer of becoming a regular intern is generally better than that of QiuZhao (of course, if QiuZhao performs well, it can also get a good offer). Many of the official offers around him are becoming a regular intern.
  • Control the time of internship , because it's very tiring to prepare for autumn moves while practicing. Generally, when practicing, the work pressure is very high, and there is no time to brush the questions.

Interview preparation

Project experience

I think there is no problem with our laboratory project. The important thing is to talk about it well.

  • Project Introduction

First of all, let me introduce what this project is, and Why do you want to do this project

  • Results of the project

Then you may ask about the final results of some data of the project, such as how many people can use the conference system at the same time, or the quantitative experience, such as fluency, or some other advantages.

  • Difficulties in the project

Finally, they will ask if there are any difficulties, challenges and how to solve them. In this process, we mainly investigate what the technical points of this project are.

What does difficulty mean? Personally, I think that problems that take several days to solve are difficulties.

Take two examples:

The first example is troubleshooting For example, if it took a week to find out the problem of a memory leak, it would be a difficulty, and the process of solving the problem would be How to locate the problem process For example, we first search for relevant information based on errors. It is certainly not so easy to find the reason directly, but we will find some of these information key word , such as some tools, so our use of this tool is a process of solving problems.

The second example is the design of requirement scheme For example, when a requirement is completed, we may have multiple feasible design schemes to implement the requirement. The process of solving this difficulty is We think about the reasons for choosing this method and the advantages and disadvantages of other design schemes

During the interview, I was asked: What is the most difficult problem you have encountered at work_ Find and solve problems- CSDN blog _ how to solve the difficulties encountered in the job interview

Some people say that my solution is to search through Baidu, but in fact, the details are also to search for an error or problem first, but it is certainly impossible to find the code answer all at once. Instead, we find a keyword in an answer, and then we continue to search for keywords to obtain other information.

written examination

I don't think it will be too difficult to find a written exam for internships. Generally, if there are 4 questions, there is almost an opportunity for an interview if you can work out 1-2 questions.

LeetCode Top100. It was very painful at the beginning. I felt a little bit when I finished 40 questions. It is suggested to start from linked lists and binary trees. There are many techniques that cannot be used in array type questions.

  • :: Must use white board for training::, Must use white board, Not only for interview remember API, More importantly, after using white board skillfully, Write code will be more skilled, and thinking more independent and independent.
  • Algorithm questions are the most important. The end point is not difficult questions, but simple, medium, common, high-frequency questions. Practice makes perfect.
  • If there are problems during the written interview, Be sure to apply to use the local IDE for debugging at the first time Otherwise, the problem may not be found for a long time and the opportunity will be wasted.

interview

The interview is generally divided into two parts, the first part will ask some basic knowledge or project experience, and the second part will ask questions. In addition to using LeetCode, you should use more codeTop It's also very good. It's more targeted to brush with the company according to the frequency.

At the beginning, it is unnecessary to review the basic knowledge systematically. The first thing is to ensure that high-frequency problems will be learned For example, the computer network, operating system, and other necessary questions can be found by looking more closely at the experience, which is not a decisive influence on the more partial questions even if they are not answered.

  • Look at facial scriptures!!!!!! Don't always immerse yourself in learning. It depends on what questions people have asked.
  • For internships, See the knowledge points and common questions must be complete!!!!! , not so precise, it's not a big problem, it must be complete, it must be complete!!!!
  • Say as much as you can about what you won't do!!!! It's really not good, just go somewhere else!!! In short, it is to guide the interviewer to speak where he will.
  • The style of the written test in the interview is different from that of the previous one. The question of the written test in the interview is not too difficult, but the inspection is calm thinking, elegant code, no bugs, think clearly first!!! Writing!!!
  • When describing the difficulties of the project, don't talk about the fact that document research is a difficulty. Answering this part of the question should be a technical difficulty. Finally, what technology was used to solve this problem. This part of the technology allows the interviewer to ask more questions in order to know his technical ability.
]]>
fourteen https://www.ihewro.com/archives/1217/#comments https://www.ihewro.com/feed/
Thinking on Automatic Failover of Public CDN after the jsDelivr Accident https://www.ihewro.com/archives/1211/ https://www.ihewro.com/archives/1211/ Thu, 23 Dec 2021 19:40:00 +0800 Friend C On December 20, a network accident occurred in jsDelivr. jsDelivr lost its mainland ICP license, that is, there was no mainland node. It was interrupted for about 5 hours. Fortunately, I am a personal blog, otherwise it would be a P0 accident:: aru: maintenance::

In fact, such accidents have been encountered many times with the theme of handhome. Today, let's review:: aru: diving::

  • Historical accident

[timeline title="Public CDN Incident Timeline" type="small"]
[item date="October 15, 2017"] The handhome theme adds the function of public cdn switching to the public database used, but these resources are not localized at this time Git record: size=30% [/item]

[item date="May 17, 2018"] Some domestic nodes of bootcdn failed  Fault notification: size=30% [/item]
[item date="October 1, 2018"] The bootcdn also failed on that day Fault notification: size=30% [/item]

[item date="February 15, 2019"] Add localization options for public libraries to the handhome theme Fault notification: size=30% [/item]

[item date="December 20, 2021"] The jsDelivr public CDN fails [/item]
[/timeline]

Although localization is a solution, there is no bandwidth.

Now that jsDelivr has been restored, it should still be used, but is there a way to automatically switch it to local when there is a problem?

  • Service worker scheme

In the issue of jsDelivr's China network error, I saw that someone recommended this project:

GitHub - EtherDream/freecdn: A front-end CDN based on ServiceWorker

I took a look at the service worker. I have been using it all the time, but this project is too large. I roughly looked at the basic principle, which is to listen to the fetch event, intercept the request, and judge whether the response of the current request is successful. If it fails, it will be replaced with another URL to request. It seems simple, but in fact Judge whether the request is successful This place is not so simple.

I wrote an article about the practice of service worker a year ago [post cid="1126" cover="" size="small"/]

Now when I read back, I found two problems:

  • When installing sw for the first time, the controller range will also be triggered. As a result, the user will be prompted with "page cache update suggestion to refresh the page" when visiting the blog for the first time. This is not appropriate
  • If the fetching request in the sw fails to access, it will be cached as long as it is in the cache list white list, regardless of whether the request succeeds (such as 404 error). This will result in errors being displayed all the time (unless the sw version number is manually updated) even if the request succeeds subsequently

The first question will not be expanded in detail here. In fact, you can judge whether the status of the sw is reg.active If it indicates that sw has been installed before, and if the controllerchange appears again, a prompt box will appear to prompt the user to refresh the page.

The second question is to judge whether a request is successful. At first, I thought whether the return value of response.ok is true or whether the response status is 200. However, it is found that the response.ok is always false and the response.status value is 0 for requests from other sites.

It was later discovered that due to the security and privacy of cross domain request sites, Google will not return the real status information, which is called opaque filtered response Opaque filtering response. If you are interested, you can Poke here

There is no good way to solve this problem at present (If there is a good method, please let me know in the comment area), unless it is passed in the fetch {"mode":"cors"} It means that we make the request in a strict cross domain manner. At this time, the header of the target site response Access-Control-Allow-Origin Cannot be a wildcard * , you need to specify the domain name containing our requestor, otherwise the browser will prompt the following error:

 The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

At present, the improved fallback logic is as follows. If the response.status is 0, the loading is considered successful.

 return fetch(event.request).then(function(response) { return caches.open(CACHE_NAME).then(function(cache) { If (response. status==0 | | response. ok) cache.put(event.request, response.clone()); } else { const new_response = fetchLocal(event); if (new_response) { return new_response; } else { return response; } } return response; }); }). catch(function(error) { const response = fetchLocal(event);; if (response) { return response; } else { // console.log('Fetching request url ,' +event.request.url+' failed:', error); // throw error; } });

In fact, there are two types of request failure: one is that the server returns an error status code, such as 404502, and the other is that the server goes down directly.

The second type of request failure can be captured in the catch of the try statement.


At present, my blog has deployed a new service worker. If the jsDelivr goes down, sw will continue to request resources on my server to complete the downgrade process. This logic will also be included in the subsequent update of the handhome.

]]>
seven https://www.ihewro.com/archives/1211/#comments https://www.ihewro.com/feed/
If life deceives you https://www.ihewro.com/archives/1147/ https://www.ihewro.com/archives/1147/ Thu, 19 Nov 2020 14:32:00 +0800 Friend C Let's encourage each other!

If life deceives you,
Don't be sad or anxious!
Calm down in a blue day:
Believe it, happy days will come!
My heart always yearns for the future;
Now it is often melancholy.
Everything is instantaneous, everything will pass;
The past will become a kind nostalgia.

]]>
zero https://www.ihewro.com/archives/1147/#comments https://www.ihewro.com/feed/
Things about carbon and cocoa in Mac OS https://www.ihewro.com/archives/1144/ https://www.ihewro.com/archives/1144/ Sun, 30 Aug 2020 21:30:00 +0800 Friend C Do you know the full name of mac? Macintosh, translated as Macintosh.

The first version of Apple Computer was released in 1984, which was named Macintosh System 1 until the ninth version (version 9.0 was launched in 1999). These systems are collectively called Classic Mac OS. While Classic Mac OS initially used Pascal as the primary development language, by 1990, most of the mac software and libraries were developed using c++.

In 1985, Jobs left Apple and founded NEXT independently. He launched NeXTSTEP operating system, which is based on Mach and BSD, Based on object-c complete one The last version 3.3 was released in 1995. NEXT company later cooperated with SUN company to rename NEXTSTEP operating system as OpenStep.
In 1996, Jobs returned to Apple. two

Apple subsequently acquired NEXT and developed a new operating system Rhapsody based on OPENSTEP. In order to be compatible with the previous Classic Mac OS, the system uses a new strategy: it retains most of the OPENSTEP object libraries, migrates most of the OPENSTREP GUI apis, and is named "Yellow Box". A simulator named "Blue Box" running existing Mac OS software has been added. Run the old software in this simulator. (Because most of the past software is c++, while openstep is written based on object-c)

It can be seen that Rhapsody is a direct inheritance of openStep, but an emulator is added to be compatible with the software in the past system. That is, Rhapsody=yellow box+blue box. The yellow box is basically a reorganization of openstep code.

This change was announced at the WWDC conference in 1997. Many developers were dissatisfied. They didn't want their software to run in a "Blue Box" simulator that might not be updated. They even affectionately called the blue box "punishment box".

It is precisely this problem that Jobs announced at the WWDC conference in 1998 that Apple would release a modern version that is well compatible with the past systems.

This is the origin of the carbon library. The carbon library is written based on c. The carbon framework is also a strategy for Apple to bring Mac OSX into the market.

In order to launch carbon, Apple has modified the entire system of Rhapsody. The Rhapsody model is actually an OpenStep with an emulator. In the new system, Apple used pure c to rewrite many of the underlying code in openStep called Foundation, and named it core foundation (so core foundation is based on c and is part of the carbon framework). The code in yellowbox has gradually evolved into the cocoa framework.

In addition, carbon and cocoa share common code as much as possible. Therefore, some function mapping will be carried out between carbon and cocoa on the code in the foundation module. For example, in the foundation kit module of cocoa, you can see similar typedef CGPoint NSPoint; The data structure and api of NS are converted into CF by mapping the data structure and function of NS.

Although this has some performance impact on the project of cocoa, some functions calling cocoa also need to convert object methods to c. But according to Apple, the use of the technology of toll free bridging has reduced this impact.

Carbon was released in 2000. In 2001, Apple released the first version of Mac OSX, which means 10. Since then, almost all software has used carbon, as has Apple's official applications, such as finder.

In the new system, carbon and cocoa are peer relationships. Rhapsody evolved into macosx, while yellowbox evolved into cocoa.

The good times are not long. In 2007, Apple released Mac OS X 10.5. From this version, Apple began to transition to 64 bit applications. meanwhile, Apple announced that the 64 bit C programming environment no longer provides api compatibility related to the interface interaction of carbon. Introduction to 64-Bit Guide for Carbon Developers The home page of Apple developers of the year introduced the changes in 10.5 as follows:

Most APIs in Mac OS X v10.5 are available to both 32-bit and 64-bit applications, but some APIs commonly used by Carbon applications are not. In particular, the APIs used to implement a Carbon user interface are generally available only to 32-bit applications. If you want to create a 64-bit application for Mac OS X, you need to use Cocoa to implement its user interface.

That is, the api related to interface interaction can only be applied to 32-bit programs, otherwise you need to use cocoa to create applications.

In 2012, Apple released OS X 10.8. At this time, most of the apis of carbon have been deprecated, but they can still be used. Apple has announced that it will not update the framework content of carbon. In October 13, 2017, Apple announced that the subsequent version of Mac OS would no longer support 32-bit applications, and this decision officially took effect on Mac OS 10.15.

In the naming prefix rules, from the beginning of Mac OS X to 10.8 released in 2012, the naming prefix was changed to OS X 10.8. Until the release of 10.12 and later versions in 2016, the prefix was changed to Mac OS.


That's the end of history. Carbon has completed the mission of Mac OSX - to release a modern operating system that is compatible with old system programs. However, with the popularity of 64 bit applications, the mac no longer recommends using carbon. However, if you do not use the API related to the interface library, the carbon library can still be used in 64 bit applications.

The following is a brief introduction to the contents contained in the cocoa and carbon frameworks:
carbon #Architecture) Macintosh Toolbox , Toolbox is a library in Classic Mac OS, which is composed of many managers. It implements many advanced functions, such as drawing graphics, menu manager, memory management, and so on.

Carbon originally came from the reorganization of toolbox, so carbon is also composed of multiple managers. Most of the code added later is based on core foundation.

The core foundation includes the following modules:


cocoa )Contains

  • Foundation Kit As the legacy of openstep, its class prefix is NS, which is a general object-oriented library, providing string and value operations, containers and iterations, distributed computing, event loops (running loops), and other functions not directly bound to the graphical user interface. The owned classes are

    • 1.1 NSObject
    • 1.2 NSString and NSMutableString
    • 1.3 NSValue and NSNumber
    • 1.4 NSArray and NSMutableArray
    • 1.5 NSDictionary and NSMutableDictionary
    • 1.6 NSSet and NSMutableSet
    • 1.7 NSData and NSMutableData
    • 1.8 NSDate, NSTimeZone and NSCalendar
  • AppKit It is also the heritage of openstep. Its classes and variables are prefixed with NS, which contains code programs that can be used to create and interact with graphical user interfaces. The owned classes are:

    • NSApplication, get the object of an application
    • NSWindow: Get the object of the window
    • NSView
    • NSResponder
    • NSDocument
    • NSController
  • core data It is part of the core foundation and is also included in the cocoa.

It can be seen that although cocoa and carbon were parallel in early times, in fact, their interface libraries related to drawing windows are not the same, and the display effects of interfaces are also different. One is from toolbox and the other is from openstep.


In a nutshell

  • Cocoa=Most object libraries in openstep -->foundation+UI library in openstep -->Appkit+core data
  • Carbon=core foundation+toolbox interface library reorganized

The foundation kit has many mappings with the core foundation function, so foundation. h also contains many header files in the core foundation module.

reference material

macOS
Classic Mac OS
cocoa )
Carbon (API) )
What is Cocoa
OpenStep

The overall architecture of the mac system is complex and has a long history. If there are any intellectual mistakes, you are welcome to point them out.

]]>
one https://www.ihewro.com/archives/1144/#comments https://www.ihewro.com/feed/
Nginx current limiting module and fail2ban are used together https://www.ihewro.com/archives/1128/ https://www.ihewro.com/archives/1128/ Sat, 29 Aug 2020 16:11:00 +0800 Friend C There are three current limiting modules in ngnix:

  • Limit_conn limits the number of TCP connections for an IP or the total number of connections for a server (website)
  • Limit_rate The current data size of each request
  • Limit_req limits the number of requests for an IP

The third one has the most obvious effect limit_req , but in the pagoda panel Flow limit Only the previous two configurations are available, so traffic restriction is useless.

The difference between the number of tcp connections and the number of requests

TCP connection establishment requires three handshakes, which is time-consuming. Just like making a phone call, the two parties can communicate (request resources) only after making a phone call. Naturally, the fewer TCP links, the better.

How many TCP connections will be made when visiting a website?

If your site is http1.1, the number of connections=the number of requests/<the number of concurrent allowed by the browser>
If your site is http2.0, the number of connections=1

Http 1.1 enables the keep alive feature by default and supports tcp persistent connections. However, because the browser limits the number of concurrent connections, there are too many connections, and a second tcp connection will still be made. one Please refer to the "Number of Concurrencies Allowed by the Browser" What is the meaning of the number of concurrent requests allowed by the browser- Answer from Wang Nano

Http2 introduces multiplexing and binary frame layering features, allowing all requests to come from the same tcp. You can write the advantages of http2 in detail when you have time later.

It should be noted that http2.0 is only applicable to https sites, two And needs to be configured on the server side three
Http sites still use the http 1.1 protocol.

The following is an example of configuring http2 in the nginx configuration configuration file:

 server { listen 80; listen 443 ssl http2; }

In the chrome control panel, you can see the ID of the TCP connection established by the current website. After using http2, in addition to external resources, only one TCP link is established for the request of local resources.

 15986699997354.jpg

On your own server, you can also use the following command to view the TCP connection:

 netstat -anlp|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20 ;

netstat -anlp It is a command for Linux to view the network situation. The filter only displays the TCP related ones, but the TCP connection of the entire server is displayed here, not just a website.


The number of requests is the request number you see in the chrome panel. Of course, if it is not your own site, the number of requests for resources will not occupy the bandwidth resources of your server.


Conclusion: If you are an https site and configured with http2, that tcp connection is about equal to a real person
A real person will generate many requests.

Limit_req module

The limit_req module is used to limit the number of requests for an IP.

Configure in the http field of nginx:

 limit_req_zone $binary_remote_addr zone=www_sym:10m rate=20r/s;

Configure in the server field of a website, or in the location field below:

 limit_req zone=www_sym burst=20 nodelay;

There are several variables that need to be explained:

  • zone : Behind www_sym It is the name of the domain, and you can choose any one. The following correspondence is OK. The 10m after the colon indicates the size of the domain, that is, the module needs to open a memory space to cache the request record of nginx $binary_remote_addr To match whether the request rate exceeds the specified rate
  • rate : This is the number of requests allowed in 1 second, This place is easily misunderstood and leads to configuration errors. For example, the rate is set to 20r/s That is, only one request is allowed in the range of 0-50ms, because nginx is a millisecond rate control, and the rate here is actually a millisecond constant rate control But in fact, our site's requests are all burst traffic, that is, many requests are concurrent in a short time. So we need to use burst To receive burst traffic.
  • burst : It can be understood as a buffer queue. Assume that the value is 20. Assume that there are 21 requests in 0~50ms, then 20 of them will enter the queue.
  • nodelay This parameter is also easily misunderstood No delay means no delay. Taking the above example as an example, after 20 requests enter the cache queue, they will be immediately forwarded to nginx to request data and returned after obtaining the data. Note that the position (slot) is not released immediately after a request is out of the queue. It is also released at an interval of 50ms (rate is set to 20r/s) That is to say, if 21 requests are sent during 51~100ms, only 2 requests can be returned successfully (because only one slot is released), and the remaining 19 requests will immediately return 503 error codes.

That is, if the above configuration is followed (rate+burst+nodelay is configured at the same time), 21 burst concurrent requests can be processed normally at any time between 0 and 1000ms. If the number of requests is greater than 21, a 503 error code will be directly returned, telling the client that nginx cannot process the request currently.

It is strongly recommended to set the nodelay parameter, or not set it, so that 20 requests will not be forwarded immediately after entering the buffer queue, but will be requested and responded to at an interval of 50ms (at this time, the location of the buffer queue will also be released at this interval) * *, then the client will receive all 21 request responses at least 1s later, and this delay will be greatly increased, It is very undesirable.

If the burst parameter is not set, it is not suitable for our burst request applications. 20 of the 21 requests will directly return 503, which causes the problem that the resources of the site cannot be loaded.

For more in-depth study of this part, please refer to the following articles:

Configure the following settings in the http field to record the content of the superflow in error.log.

 limit_req_log_level error;

The log of a certain superflow is as follows:

 2020/08/25 18:09:49 [error] 10215#0: *2445032 limiting requests, excess: 10.700 by zone "www_sym", client: 120.*.3*.29, server: ***.com, request: "GET /RelatedObjectLookups.js HTTP/2.0", host: "***.com", referrer: "https://***/admin"

If the website is a reverse proxy, when the upstream website cannot be accessed, the log is as follows:

 2022/04/24 20:44:50 [error] 12985#0: *9662214 upstream timed out (110: Connection timed out) while connecting to upstream, client: 111.27.24.183, server: auth.ihewro.com, request: "GET /notice/version HTTP/2.0", upstream: "http://*****:8000/notice/version", host: "auth.ihewro.com", referrer: ""

If large-scale IP access causes PHP to fail to establish a socket, the error log is as follows:

 2022/04/24 21:49:21 [error] 12985#0: *9953796 connect() to unix:/tmp/php-cgi-74.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 23.12.64.219, server: www.ihewro.com, request: "GET / HTTP/1.1", upstream: " fastcgi://unix:/tmp/php -cgi-74.sock:", host: "www.ihewro.com", referrer: " https://www.ihewro.com "

Limit_conn module

Limit_conn is used to limit the number of TCP connections for an IP or the entire site.

!> Note that in http/2, every concurrent request is considered as a connection!!! This is very important

Http_limit_conn official document

Configure in the http field:

 limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m;

Configure in the server field:

 limit_conn perserver 200; limit_conn perip 20;

Upper middle two hundred Indicates the maximum number of connections to a server site. twenty Indicates the maximum number of connections for an IP.

If your site is configured with http2, the number of tcp connections for a user will not exceed 5 under normal circumstances. It can be configured according to specific requests.

Configure the following settings in the http field to record the content of the superflow in error.log.

 limit_conn_log_level error;

The log of a certain superflow is as follows:

 2020/08/25 18:09:49 [error] 10216#0: *2445033 limiting connections by zone "www_sym", client: 120.2.33.29, server: ***.com, request: "GET /RelatedObjectLookups.js HTTP/2.0", host: "***.com", referrer: "https://***/admin"

Limit_rate module

Configure in the server field:

 limit_rate 512k;

above 512k Indicates restrictions One request The size of does not exceed 512kB.

Use of fail2ban

The fail2ban software, as its name implies, performs ban operations based on the number of matches in the error log. It can be used not only to scan nginx logs, but also to scan any logs. You can customize the filter regular expression to match. Ban operations are not only prohibited by iptabels, but can be processed by user-defined actions.

install

 # CentOS yum install -y fail2ban #Ubuntu uses apt's system sudo apt-get install -y fail2ban

to configure

After installation, enter /etc/fail2ban , you can see the following directories and introduce their functions as follows four

  • Action. d: Operation after meeting the condition of ban
  • Filter. d: filter, which tells fail2ban how to match a line in the log
  • Jail.local: jails are prisons. Configure one or more prisons in the file, define the name of the prison, the list of monitored log files, filers, and the actions that meet the conditions
  • Jail.conf: This is an official example of multiple prisons. You can directly copy the parts you need to jail.local.

use

Edit file, nano /etc/fail2ban/jail.local , add a new prison:

 [nginxcc] enabled  = true filter   = nginx-limit-req logpath  = /www/wwwlogs/***1.com.error.log /www/wwwlogs/***2.com.error.log maxretry = 120 findtime = 60 bantime  = 120000 action   = iptables-allports[name=nginxcc] sendmail-whois-lines[name=nginxcc, dest= ihewro@163.com ]
  • The first nginxcc is the name of the prison
  • The filter uses a filter that comes with fail2ban. The file path is /etc/fail2ban/filter.d/nginx-limit-req.conf
  • Logpath is the list of monitored logs. Here I monitor errorlog instead of access.log. The reason is that the access.log log refreshes quickly when the traffic is heavy, It will cause fail2ban to fail to keep up (it is found that the ban has been dropped, but the log still shows the log matching the access of the blocked IP. It is strange that the matching speed should be very fast in theory, but we don't know why this happens) (so we need to set it well limit_req_log_level and limit_conn_log_level Is error)
  • Findtime=60 maxretry=120 means that if there are 120 times of overflow records for an IP in a 60s period, it will be blocked
  • The unit of bantime is s
  • The action blocking operation is to use the iptables tool. This action, fail2ban, has been written for us. The path is /etc/fail2ban/action.d/iptables-allports.conf

It should also be noted that, /etc/fail2ban/filter.d/nginx-limit-req.conf Only matches limit_req The module current limiting log does not match limit_conn The log of module flow restriction, so we edit the file and add a new regular match. One matching rule is one line. If there are multiple matching rules, it is multiple lines( Official document filter example )。 take failregex The value of is changed to:

 failregex = ^\s*\[[a-z]+\] \d+#\d+: \*\d+ .*, client: <HOST>,

At this point, you can use the following command to test whether your regex can match your log content normally:

 fail2ban-regex /etc/fail2ban/filter.d/test.log /etc/fail2ban/filter.d/nginx-limit-req.conf --print-all-matched

--print-all-matched The parameter is used to display all the matching lines. If this parameter is removed, the overall matching can be displayed.


In addition, you may notice that there is another action sendmail Configuration of. After this option is configured, when the prison is enabled, stopped, or an IP address is blocked, an email will be sent to your dest email address. If your server is configured sendemail modular.

 15986868197773.jpg

The default email address is fail2ban@<hostname> , the format of the message is in /etc/fail2ban/action.d/sendmail-whois-lines.conf File.

Another thing to note is that the restart of iptables will fail. After restart, your blocked IP addresses will be lost and can be modified /etc/fail2ban/action.d/iptables-allports.conf , the modified code is as follows:

 [INCLUDES] before = iptables-common.conf [Definition] actionstart = <iptables> -N f2b-<name> <iptables> -A f2b-<name> -j <returntype> <iptables> -I <chain> -p <protocol> -j f2b-<name> actionstop = <iptables> -D <chain> -p <protocol> -j f2b-<name> <actionflush> <iptables> -X f2b-<name> actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]' actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype> && service iptables save actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype> && service iptables save [Init]

That is, after the iptables operation, add service iptables save Keep records.

see

 #View the filter and ban logs of prison work tail -f /var/log/fail2ban.log #Start systemctl start fail2ban #Stop systemctl stop fail2ban #Restart systemctl restart fail2ban #Startup systemctl enable fail2ban #Check the operation status of the fail2ban module (generally used when troubleshooting the cause of errors) journalctl -r -u fail2ban.service #View prison list fail2ban-client status #Check the closure of a prison fail2ban-client status nginxcc #Delete an IP under a prison fail2ban-client set nginxcc unbanip 192.168.1.115 #Manually disable an IP fail2ban-client set nginxcc banip 192.168.1.115

Finally, remember to regularly clean your error.log and fail2ban.log logs. You can write a regular task to clean every half an hour

]]>
zero https://www.ihewro.com/archives/1128/#comments https://www.ihewro.com/feed/
Service work's scheme for updating the user's local cache https://www.ihewro.com/archives/1126/ https://www.ihewro.com/archives/1126/ Wed, 19 Aug 2020 23:20:00 +0800 Friend C Service work+cache can be used to cache some resources of the website locally, or even realize offline access (if your website is purely static).

The specific science popularization of this technology will not be repeated in this article. You can refer to this article: With the help of Service Worker and cacheStorage caching and offline development And this article PWA Service Worker: from introduction to actual combat to pit climbing

The latest version of the handhome theme also uses this technology to achieve local caching. Maybe you will feel very fast when you first enter the blog for subsequent visits. This may be the reason.

Simple implementation

Before introducing the sw update cache scheme, let's briefly introduce the working principle of sw.

We register a sw.js through the register api. At this time, the code of the js file will run in an independent js environment. It does not need to access the dom, but it has higher permissions.

 window.addEventListener('load', function() { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); });

At this point, you will enter the life cycle of the sw. The following figure shows the life cycle of the service worker Google official documents See related introduction:

 Service Worker Lifecycle

We usually judge whether to delete the old cache (based on the cache key) in the activated state.

One of the powerful functions of sw is the fetch event , can capture all requests under the current domain. We can capture requests through this event, decide whether to directly return to the cache or make network requests, and even modify the request header and response body. The results obtained from network requests can be used to determine whether caching is required.

Update Cache

This article mainly discusses how to update the local cache in the user's browser when the cached content needs to be updated.

The life cycle of sw is: install ->waiting ->activate ->fetch

That is, start registration and wait for activation. After activation, listen to the request of the page.

Sw.js uses this function navigator.serviceWorker.register(url:string) To register a service worker.

When executing this function, the browser will reinstall the new version (install ->Waiting) if it finds that the file content of this url has been modified (compared with the previously registered sw)

The browser will replace the last sw when it is idle (for example, no request occurs on the page), instead of executing it immediately, which is why there is a waiting phase.

But we can use the skipWaiting Force skip waiting.

sw.min.js :

 self.addEventListener('install', function(event) { Event. waitUntil (self. skipWaiting())//This will trigger the activate event });

Although the document says self.skipWaiting This function can jump the queue and directly force retirement of the old version. However, after specific experiments, we found that if there are multiple tabs under a domain name, we still need to wait for a short time on edge and chrome, and we can quickly replace the old version on safari and firefox. (You can see the current website's sw process in the developer tool - application - service worker process)

Therefore, this method cannot be used to directly update the local cache.

Even if it is executed serviceWorker.register You can force the old version to be replaced. When you open a web page, you will still use the resources in the cache (you need to refresh again to use the latest resources).

as a result of serviceWorker.register This is a js that executes asynchronously. Even if it is placed at the front of the page, some resources will still be loaded in the register Before execution, if these resources are previously cached, the cache will be called directly instead of the latest resources.

So the better way is to, After the new sw is successfully installed, the user is prompted to refresh the browser to update the local cache

You can monitor whether the new sw version is installed through this function provided by the browser:

 navigator.serviceWorker.addEventListener('controllerchange', function (ev) { //A prompt bar appears, prompting you to click the refresh page to update the local cache });

In this article Handle Service Worker updates carefully Method 3 is a similar idea, but it gives a prompt that if the user does not click, the new version of sw will not be installed. If the user is lazy, and has been lazy, the old version of the cache will be used consistently.

My above practice is that the user will install a new version of sw even if he does not click the prompt bar. The old version of the cache has been loaded on the current page, but the next time the user enters the page (or manually re swipes the page), it will be the latest (although he does not click the prompt bar).

]]>
four https://www.ihewro.com/archives/1126/#comments https://www.ihewro.com/feed/
Too many redirects due to incorrect cdn settings https://www.ihewro.com/archives/1120/ https://www.ihewro.com/archives/1120/ Tue, 11 Aug 2020 19:57:00 +0800 Friend C Today, I removed Baidu Cloud Acceleration, and then Re access After, discover the access http://www.ihewro.com Will display Too many redirects , but I have not modified the relevant configuration of ngnix.

The ngnix redirection of blog sites is set in two places: http ->https and Non www start -> Beginning of www The configurations of the two places are as follows:

 #Http ->https Redirection if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; } #Non www start ->www start if ($host ~ '^ihewro.com'){ return 302  http://www.ihewro.com $request_uri; }

These two configurations must be OK. They have been used before.

The reason for the final inspection is that, Problems caused by Baidu Cloud Acceleration's https setting for half way encryption

Using tools such as cdn, you can actually achieve ssl access even if you do not deploy ssl certificates on the server. If it is half way encryption, take my blog as an example. The access process is as follows:

https://www.ihewro.com (Browser) ->Baidu Cloud cdn (check whether the certificate is valid) - -- Back to source -->server (port 80)

You can see that port 80 of the back to source server is not port 443, which is half way encryption.

So we know why there are too many redirects.

https://www.ihewro.com ->Server port 80 ->trigger rewrite rule -> https://www.ihewro.com Causes a cycle.

The same meaning of no encryption, full process encryption and strict encryption is easy to understand.

  • If you choose not to encrypt, access https://www.ihewro.com The browser will display directly Does not support https, unsafe links Such errors.
  • If full process encryption is selected, the server must also deploy a self signed certificate (the validity of the server certificate is not verified when the cdn returns to the source). If no self signed certificate is deployed on the server, the browser will display Unsupported certificate Such errors)
  • If strict encryption is selected, the server needs to deploy a trusted CA certificate, otherwise the browser will display Unsupported certificate Errors like that

end.

]]>
five https://www.ihewro.com/archives/1120/#comments https://www.ihewro.com/feed/
30 minutes use dlib to classify and identify static articles https://www.ihewro.com/archives/1111/ https://www.ihewro.com/archives/1111/ Sun, 19 Jul 2020 17:01:00 +0800 Friend C To read this article, anyone only needs 30 Minutes one So that your camera can recognize one Items with fixed shape Try it.

1、 Introduction

Reference learning project: hand_gesture

This project carries out image classification and recognition, and uses image extraction Fhog feature , training and further classification. (Not cnn, so convolutional neural network is not used)

This process can be shown in the following figure two

 image.png

If you want to create object detectors then try the scan_fhog_pyramid tool first. It is quite easy to use and train and will, in many cases, give excellent results. If that doesn't give good results then try the more powerful convolutional neural network based detector. three

Also note that dlib contains more powerful CNN based object detection tooling, which will usually run slower but produce much more general and accurate detectors. four

The official website of dlib also shows that we can get good results by using fhog features for classification. If we are not satisfied with the results, we can use the cnn model for training, but it will take longer.

2、 Related nouns

2.1 Image pyramid

The size of the same problem object will vary due to the distance from the camera. The machine can also recognize it by continuously sampling the original image until the zoom is less than Scan Window The size of is stopped.

image pyramid It can be considered as a down sampling strategy, that is, given a sampling factor N, the image will be scaled every time with the N-1/N ratio. In this way, a picture will generate many pictures with a certain scale size rule in the process of down sampling, forming a pyramid, as shown in the following figure five

 image.png

The larger the N is, the smaller the size of each zoom is. Similarly, it will take more time to downsample to the same scanning window size. The more images will be generated in the pyramid, but the more information will be obtained.

2.2 Detection window

It can be simply understood that this scanning window is a fixed size matrix that slides on the image constantly, and then judges whether the features of this window conform to the features of the specified action according to the model (such as the gesture features of the likes). The extracted features are represented by fhog features. six

2.3 fhog characteristics

It is a kind of image feature Mathematical representation

Histogram of Orientated Gradient (HOG) feature is a feature descriptor used for object detection in computer vision and image processing. It computes and counts the gradient direction histogram of the local area of the image to form the feature. Hog feature combined with SVM classifier has been widely used in image recognition, especially in pedestrian detection. seven

If you want to know the calculation process, you can refer to these two articles

Fhog is an improved hog feature of Felzenszwalb.

3、 Inspection process

3.1 Model import

 //1.  Picture feature scanner typedef dlib::scan_fhog_pyramid<dlib::pyramid_down<N>> image_scanner_type; //2.  Picture position detector dlib::object_detector<image_scanner_type> thumb,thumb_mobile; //3.  The list of image position detectors. Why do you want a list std::vector<dlib::object_detector<image_scanner_type> > my_detectors; //4.  Import model dlib::deserialize(thumb_svm) >> thumb; my_detectors.push_back(thumb);

The first class in the first line scan_fhog_pyramid eight , function as name, A scanner for extracting fhog features from images It is defined as follows:

 template <typename Pyramid_type, typename Feature_extractor_type =default_fhog_feature_extractor> class scan_fhog_pyramid : noncopyable{...}

The class template itself receives two parameters:

  • The first parameter is pyramid_down , down sampling factor, which has been mentioned before
  • The second parameter is Feature_extractor_type The feature extractor has an assignment by default, that is, it uses fhog features to extract image features. nine

The second type object_detector in the second line ten , based on the image feature scanner, used to detect the position of the object to be detected in the image (such as the thumbs of thumbs).


The fourth line, deserialize We will analyze our trained model.

3.2 Testing

OK, let's start the test.

 dlib::cv_image<dlib::bgr_pixel> cimg(cvMat);// Image format required by cv:: Mat to dlib std::vector<dlib::rect_detection> &dets;// List of detection results, each containing the position of the detected object in the image double detect_shreshold = -2;// The smaller the detection threshold, the easier it is to detect evaluate_detectors(my_detectors, cimg, dets, detect_shreshold);//

We can obtain cv:: Mat from OpenCV, and then convert it to dlib, which requires image format cv_image _image[imagemage]。

rect_detection It is the container used to hold the test results, and is defined as follows:

 struct rect_detection { double detection_confidence; // Confidence of test results unsigned long weight_index; // If there are multiple models, which model serial number is the current result rectangle rect;// Location information of detection results bool operator<(const rect_detection& item) const { return detection_confidence < item.detection_confidence; } };

It looks simple, then call evaluate_detectors eleven Function to predict.

This function can Running multiple detectors , and this is faster than using this function for multiple times alone, because it will only extract the fHog feature of the image once, and then Each detector will reuse this fhog feature

If the incoming my_detectors If there are multiple detectors, the detection results may be multiple, that is, the returned dets have multiple elements. At this time, We can determine the final result by judging the confidence of multiple results. In this process, we can artificially believe one of the results according to some reasons (such as the size of the test results).

4、 Training process

The training process is not difficult.

4.1 Data acquisition

It is possible to capture images from cameras or videos. Using OpenCV, you can quickly save a frame of images to your local location. Here you can refer to Collection.cpp

4.2 Marking data

Dlib itself provides selectROI The OpenCV function takes over our mouse events, returns the position information of the circled image, and finally uses OpenCV's image processing to crop the image and save it locally. Here you can refer to boundingBox

Finally, an xml file is generated for the location of this image. This xml file records the names of all images and the location information (top, left, width, height) of the parts identified by the machine, which can be used for training. Here you can have a look here txt_to_xml.cpp

4.3 Training data

You can read this article Dlib face recognition code interpretation It was written in great detail.

Finally, a function to test the test set using the trained detector is:

 test_object_detection_function(detector, images_test, face_boxes_test)

This function returns three values that mean precision, recall, and then average precision twelve That is, accuracy rate, recall rate and average accuracy rate.

  • Recall rate=identify likes as likes/(identify likes as likes+identify likes as no likes)
  • Accuracy=identify likes as likes/(identify likes as likes+identify non likes as likes)
  • Accuracy=(identify likes as likes+identify no likes as likes)/(total number of test samples)

thirteen

Because our test set is a bit like data
The accuracy here is 1
The calculation of recall rate and accuracy rate is the same. Of course, the higher the value, the better the model training.


Finally, I recommend that I find some good articles in the process of querying materials, including writing this article, which can be further read:


Reference link:

]]>
four https://www.ihewro.com/archives/1111/#comments https://www.ihewro.com/feed/
Use of c++callback function https://www.ihewro.com/archives/1116/ https://www.ihewro.com/archives/1116/ Mon, 08 Jun 2020 21:15:00 +0800 Friend C Java implementation mode

Java callback functions may be familiar. Use Interface The callback function is defined in the interface. The function parameter can be interfance. When calling a function, the function that implements the interface is sufficient.

Simple example:

 public interface CallBack { public void execute(); } public void test(CallBack callBack){ System.out.println("callback"); callBack.execute();  } test(new CallBack() { @Override public void execute() { System.out.println("callback implement"); } });

Implementation of c++

C++is achieved through Function pointer (syntax of c) and std::function (syntax in c++11).

C++callback functions can be used in the following scenarios:

The callback function is a normal function

In general, the callback function is used in a situation where a result is generated in a function. The function does not care about the subsequent use of the result, but uses the callback function to process it.

You can define it first Function pointer of callback function , general format:

Return value (* pointer name) (parameter list)

 typedef void (*CaptureCallback)(string); void capturePic(CaptureCallback callback){ string t = "a pic"; callback(t); } void renderPic(string t){ print(t); } capturePic(renderPic);

The above is a simple example. The callback function for rendering images is used in the function for capturing images.

The callback function is a member function

In C++object-oriented, it is more common for a callback function to be a member function. This advantage is that after a function of a class A generates a result, it can call a member function of another class B. Class A does not have to have an instance of B.

Especially when there is an instance of A in B, if there is another instance of B in A, there will be a circular reference problem , which can also be solved, but this kind of coupling is easy to confuse the logic.

 typedef std::function<void (string)> CaptureCallback;   class CaptureController{ public: CaptureCallback callback; CaptureController(CaptureCallback callback):callback(callback){}; void capturePic(CaptureCallback callback){ string t = "a pic"; callback(t); } } class UI{ //Start capturing images void startCapture(){ CaptureController c(std::bind(&UI::renderPic,this,_1));  c.capturePic(); } //Render the picture as a callback function void renderPic(string t){ print(t); } } //main.cpp UI ui; ui.startCapture();

The above example is a good illustration of why callback functions are needed and how they are used.

The CaptureController header file has been referenced in the UI class. If the callback function is not used, the UI. h header file must also be referenced in CaptureController. h to access the renderPice This will cause a circular reference header file problem.

std::function

The member function of the class is different from the ordinary function as a callback function Function pointer , but Std:: function<return type (parameter type...)>function name

 typedef std::function<void (string)> CaptureCallback;
std::bind

When we pass in a function as a parameter, we need to use std::bind(oldFunName,arg_list) bind() function A new function object will be returned , arg_list Refers to the old function object oldFunName List of parameters for.

and arg_list In _1 _2 Is the parameter list of the new function object. _1 This is called a placeholder. Under the namespace of std:: placeholders.

 CaptureCallback callback = std::bind(&UI::renderPic,this,_1); callback("test");

When called callback("test") , actually calling UI Object's member function this.renderPir("test") So we need one more this Object pointer for

special, std::bind Function returned Number of arguments for the new function object Can be connected with oldFunName Number of parameters for Different.

give an example:

 void renderPic(string t,int a,char b); CaptureCallback callback = std::bind(&UI::renderPic,this,_1,2,'b'); callback("test");

Call here callback("test") , actually calling renderPic("test",2,'b') This function.

Of course, the application scenarios where the number of parameters of the callback function is different from the number of parameters of the function passed in are rare and can be ignored.


It should be noted that, std::function and std::bind Both are grammars of the c++11 standard.
It is also taken from the C++extension library boost.

The callback function can be either a normal function or a member function

In fact, the second way is to use std::function It can replace the function pointer in c language. At the same time, it should be noted that if it is passed in by ordinary functions, it is not necessary to pass in this The object pointer of the.

The callback function does not have to be used

Take the above example of camera capturing pictures ->rendering pictures.

Two methods can also be used to capture the sequence of pictures on the rendering interface:

Method 1
 void startCapture(){ string t; CaptureController c();  c.capturePic(t);// Parameter is a reference to string renderPic(t); } void renderPic(string t){ print(t); }

Through on startCapture Internal first call capturePic You can also call the renderPic function to process the result. But most application scenarios do not use threads

Method 2 can also be used for different threads.

Method 2

RenderPic can open a timer to retrieve the results generated by the capturePic function on a regular basis. However, the rhythm of renderPic is inconsistent with that of capturePic.

Therefore, whether to use the callback function needs to be selected according to the current application scenario.


Reference article:

]]>
zero https://www.ihewro.com/archives/1116/#comments https://www.ihewro.com/feed/