Skip to content

2020

Ignoring Already Modified Files in Git

I've encountered a rare scenario where a file has been modified, but I don't want to commit this change to Git. There are various methods to achieve this, such as using a .gitignore file. However, this approach doesn't work if the file is already being tracked.

The solution is to manually ignore the file by executing the following command:

    git update-index --assume-unchanged <file path>

To start tracking the file again, you can revert this action by using the following command:

    git update-index --no-assume-unchanged <file path>

Feel free to reach out if you have any questions.

在Git中忽略已修改的文件

我遇到了一種罕見的情況,一個文件已經被修改,但是我不想將這個變更提交給Git。有各種方法可以實現這一點,比如使用.gitignore文件。然而,如果文件已經被追蹤,這種方法就不起作用。

解決方案是通過執行以下命令來手動忽略文件:

    git update-index --assume-unchanged <文件路徑>

要再次追蹤文件,您可以通過使用以下命令來撤消此操作:

    git update-index --no-assume-unchanged <文件路徑>

如果您有任何問題,請隨時聯繫我。

Find and Kill Processes Locking Specific Ports on a Mac

Problem: Sometimes, when you start a local Node.js server, it may continue running in the background. If you try to start the server again, you may encounter an error indicating that the port (e.g., 8080) is already in use and locked:

    throw er; // Unhandled 'error' event
    Error: listen EADDRINUSE 127.0.0.1:8080

Solution: You can use the lsof command to identify the process locking the port:

    lsof -n -i4TCP:8080

Alternatively, you can replace 8080 with the specific port number you want to investigate. This will display a list of processes currently using that port. Identify the process you wish to terminate (for example, node running with PID 6709) and execute the following command to kill it:

    kill -9 <PID>

Finally, restart your server. It should run normally once the port has been freed.

在 Mac 上尋找並終止鎖定特定端口的進程

問題:有時候,當您啟動一個本地 Node.js 服務器時,它可能會繼續在後台運行。如果您嘗試再次啟動服務器,您可能會遇到一個錯誤,指出端口(例如,8080)已經在使用中並被鎖定:

    throw er; // Unhandled 'error' event
    Error: listen EADDRINUSE 127.0.0.1:8080

解決方案:您可以使用 lsof 命令來識別鎖定端口的進程:

    lsof -n -i4TCP:8080

或者,您可以將 8080 替換為您想要調查的特定端口號。這將顯示當前使用該端口的進程列表。識別您希望終止的進程(例如,正在運行的 node 與 PID 6709)並執行以下命令來將其殺死:

    kill -9 <PID>

最後,重新啟動您的服務器。一旦端口被釋放,它應該可以正常運行。

How to Work with a Product Manager as a Software Engineer

As a software engineer, I know how it feels to work with product managers. With years of experience, I've encountered fantastic Product Managers (PMs) as well as some less-than-ideal ones. Every day, I collaborate with PMs, and I understand the challenges that can arise, particularly when the relationship is strained. In this blog post, I'll offer advice on how to work effectively with a PM as a software engineer.

Two primary difficulties can arise when working with PMs. The first issue is that a PM without an engineering background may not understand the technical complexities you're dealing with, leading to a lack of mutual respect. Secondly, if a PM started their career as an engineer, it can be frustrating to hear them talk as if they fully understand technical subjects like blockchains, big data, or artificial intelligence when they actually don't.

To bridge these gaps, soft skills and communication abilities are essential.

Common Pitfall 1: Technological Ignorance

The worst thing to hear from a PM is something like, "It's just a simple button. Are you sure you can't finish it in five minutes?" Such comments imply that the work is straightforward and that you are incompetent. But, creating even a simple button is not trivial. For example, Google's homepage search button is not just a "simple button." Various states like hover, click, double-click, and other factors like text localization, accessibility, and multiple screen widths must be considered.

Common Mistake 2: Misunderstanding Roles and Responsibilities

PMs are responsible for the product, but they are not your bosses. This misunderstanding can be especially prevalent in hierarchical organizational structures or where an outsourced vendor manages in-house PMs. Practicing methodologies like Scrum can help set boundaries and manage expectations. Frequent changes in requirements can be detrimental to the project, leading to non-reusable code, bugs, and technical debt.

Common Error 3: Lack of Clear Objectives

It can be frustrating when a PM has no clear vision and hasn't defined specific requirements. Engineers thrive on tackling challenges and require clear goals. Poorly defined requirements lead to a product that's hard to measure in terms of impact and success.

Final Thoughts

To navigate these issues successfully, here are my three recommendations:

  1. Treat non-technical stakeholders with empathy and kindness, while educating them on the complexities of your work.
  2. Understand that the PM is not your boss; collaborate and be willing to share credit for successes.
  3. Stay informed about industry trends and be prepared to construct a persuasive argument when you think the requirements are flawed.

Remember, software development is a team sport. Like any team, success depends on effective communication, collaboration, and leadership to achieve a common goal.

作為一名軟件工程師如何與產品經理合作

作為一名軟件工程師,我知道與產品經理合作的感覺。借助多年的經驗,我遇到過優秀的產品經理(PM)以及一些不理想的PM。每天,我都會與PM進行合作,我了解到可能出現的挑戰,特別是當彼此的關係變得緊張時。在這篇博客文章中,我將提供一些作為一名軟件工程師如何有效與PM合作的建議。

與PM合作時可能出現兩個主要的困難。第一個問題是,沒有工程背景的PM可能無法理解你正在處理的技術復雜性,導致彼此之間缺乏尊重。第二,如果PM的職業生涯始於工程師,他們如果說出自己完全理解像區塊鏈、大數據或人工智能等技術主題,實際上卻不然,會讓人感到困擾。

要縮小這些隔閡,軟技能和溝通能力是必不可少的。

常見的陷阱1:對科技的無知

從PM那裡聽到最讓人惱火的一句話可能就是, "這只是一個簡單的按鈕。你確定你五分鐘內完成不了嗎?"之類的評論暗示著工作很簡單,並且你是無能的。但是,創建即使是一個簡單的按鈕也並非小事。例如,Google首頁的搜索按鈕不只是一個”簡單的按鈕”。必須要考慮各種狀況,如懸停、點擊、雙擊,以及像文本語言化,訪問性和多個屏幕寬度等其他因素。

常見的錯誤2:誤解角色和責任

PM負責產品,但他們不是你的老闆。在等級組織結構中或者是由外包廠商管理的內部PM中,這種誤解可能尤其普遍。採用像精益求精這樣的方法可以幫助設定邊界並管理期望。需求的頻繁變更可能對項目造成傷害,導致無法重用的代碼,錯誤和技術債務。

常見的錯誤3:沒有清晰的目標

在PM沒有明確的願景並沒有定義具體的需求時,可能會讓人感到沮喪。工程師擅長解決挑戰並需要清晰的目標。需求定義不明會導致產品難以衡量影響和成功。

最後的想法

為了成功地應對這些問題,這裡有我的三個建議:

  1. 以同理心和善意對待非技術的利益相關者,同時讓他們了解你工作的復雜性。
  2. 理解PM並不是你的老闆;願意與他們合作並願意分享成功的成果。
  3. 對行業趨勢保持了解,並準備好在你認為需求有誤時進行有說服力的論述。

請記住,軟件開發是一個團隊運動。像任何隊伍一樣,成功取決於有效的溝通,合作和領導以實現共同的目標。

Registering Sling Servlets in Adobe Experience Manager

In Adobe Experience Manager (AEM), a Sling servlet can be utilized to handle certain RESTful request-response AJAX calls. Written in the Java programming language, these servlets can be registered as OSGi (Open Services Gateway Initiative) services. There are two methods to register a servlet in AEM: 1) By Path, and 2) By resourceType. Details for both are explained below:

1. Register by Path

For instance, if you want to execute a form POST request to the path /bin/payment from the client-side to the Sling servlet class, you can use the annotation below:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    paths = "/bin/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // Perform your tasks here
    }
}

When there's a POST request to http://localhost:4502/bin/payment, the servlet will be triggered, and the doPost method will be invoked.

Prerequisites include having a local AEM instance up and running on port 4502 and installing the bundle module via the Maven bundle plugin. You can verify the installation of the bundle by navigating to http://localhost:4502/system/console/bundles. If it's not installed, you can manually upload the JAR file.

If you encounter a "forbidden" error and cannot serve the request to /bin/payment, follow these steps:

  1. Go to http://localhost:4502/system/console/configMgr.
  2. Search for 'Apache Sling Referrer Filter'.
  3. Remove the POST method from the filter. This will allow you to trigger the POST method from any source.
  4. Locate Adobe Granite CSRF Filter.
  5. Remove POST from the filter methods.
  6. Save the changes and test the servlet again.

The servlet should now trigger as expected.

2. Register by resourceType

To avoid the issues mentioned above, a better approach is to register the servlet by resourceType. Refactor the servlet as follows:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    resourceTypes = "services/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // Perform your tasks here
    }
}

Next, you'll need to create a page to trigger this resource:

  1. Go to CRXDE Lite at http://localhost:4502/crx/de/index.jsp.
  2. Inside the /content folder, create a page (e.g., http://localhost:4502/content/submitPage.html).
  3. In the resourceType properties, enter services/payment or whatever matches your servlet above.
  4. Save your changes and test the POST request to http://localhost:4502/content/submitPage.html. It should work as expected.

Extra Tips: You can also use the Apache Sling Resource Resolver to verify if the servlet has been registered successfully at http://localhost:4502/system/console/jcrresolver.

Feel free to leave any questions in the comments below.

在Adobe Experience Manager中註冊Sling Servlets

在Adobe Experience Manager (AEM) 中,Sling servlet可以被用來處理某些RESTful的請求-回應的AJAX調用。寫在Java編程語言中的Servlets可以被註冊為OSGi(開放服務網關協議)服務。在AEM中註冊servlet有兩種方法:1) 通過路徑,和 2) 通過資源類型。以下是兩種方法的詳細說明:

1. 通過路徑註冊

例如,如果您希望從客戶端發送一個表單POST請求到路徑/bin/payment 到Sling servlet類,您可以使用以下的註解:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    paths = "/bin/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // 在這裡執行你的任務
    }
}

當有一個POST請求到 http://localhost:4502/bin/payment 時,servlet將被觸發,並調用 doPost 方法。

前提條件包括在端口4502上運行本地AEM實例,並通過Maven Bundle插件安裝bundle模組。您可以通過導航到 http://localhost:4502/system/console/bundles來驗證bundle的安裝。如果沒有安裝,您可以手動上傳JAR文件。

如果您遭遇“禁止”的錯誤,無法服務 /bin/payment 的請求,請按照以下步驟操作:

  1. 轉到 http://localhost:4502/system/console/configMgr
  2. 搜索 'Apache Sling Referrer Filter'。
  3. 從篩選器中刪除POST方法。這將允許您從任何來源觸發POST方法。
  4. 搜索Adobe Granite CSRF Filter。
  5. 從篩選方法中刪除POST。
  6. 保存更改並再次測試servlet。

Servlet現在應該按預期觸發。

2. 通過資源類型註冊

為了避免上述問題,更好的方法是通過資源類型註冊servlet。重構servlet如下:

@SlingServlet(
    metatype = true,
    methods = { "POST" },
    resourceTypes = "services/payment"
)
public class YourServlet extends SlingSafeMethodsServlet {

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException {
        // 在這裡執行你的任務
    }
}

接下來,您需要創建一個頁面來觸發此資源:

  1. 轉到 http://localhost:4502/crx/de/index.jsp的CRXDE Lite。
  2. /content資料夾內,創建一個頁面(例如,http://localhost:4502/content/submitPage.html)。
  3. 在resourceType屬性中,輸入 services/payment 或其他匹配您上述的servlet。
  4. 保存更改並測試POST請求到 http://localhost:4502/content/submitPage.html。 應該可以按预期工作。

額外提示: 您也可以使用Apache Sling Resource Resolver來驗證servlet是否已成功註冊在http://localhost:4502/system/console/jcrresolver

如果有任何問題,可以在下面的評論中留言。