xujing 发布的文章

作为程序员,职业素养是非常重要的,它涉及到你作为一名专业人士所应具备的道德、职业道德和工作态度。以下是一些程序员应该具备的职业素养:

1.专业知识:作为程序员,你应该持续学习和提升自己的专业知识。这意味着你需要了解最新的编程语言、框架和技术趋势,并不断跟进行业的发展。

2.代码质量:编写高质量的代码是程序员的基本素养。你应该注重代码的可读性、可维护性和可扩展性,遵循良好的编程实践和标准,编写清晰、简洁、高效的代码。

3.合作与沟通:程序员通常是团队中的一员,良好的合作和沟通能力是至关重要的。你应该能够与团队成员有效地合作,分享知识、经验和资源,并能够清晰地表达自己的想法和观点。

4.问题解决能力:作为程序员,你将面对各种技术和逻辑问题。你应该具备良好的问题解决能力,能够分析和理解问题,并提供有效的解决方案。这包括独立思考、调试代码、查找文档和寻求帮助等。

5.职业道德:作为一名程序员,你应该遵守职业道德准则。这包括保护用户隐私和数据安全,遵循法律和法规,尊重知识产权,不参与非法活动,以及对项目和客户的机密信息保密等。

6.持续学习:技术行业的发展非常迅速,作为程序员,你应该具备持续学习的精神。不断探索新技术、学习新工具和框架,参加培训和研讨会,与同行交流经验,保持自己的竞争力。

7.项目管理和时间管理:作为程序员,你经常需要同时处理多个项目和任务。你应该具备良好的项目管理和时间管理能力,能够合理安排工作,掌握优先级,保证项目按时交付。

8.责任心:作为程序员,你对自己的工作应该有责任心。你应该对自己的代码质量负责,并能够承担自己的工作结果。

总而言之,程序员的职业素养不仅包括技术能力,还包括道德和职业道德、合作与沟通能力、问题解决能力、职业道德、持续学习、项目管理和时间管理,以及责任心。通过遵循这些职业素养,你可以成为一名优秀的程序员,并在职业生涯中取得成功。

此外,还有一些其他的职业素养也值得注意,例如:

9.团队合作:作为程序员,你很可能是一个团队的一部分。你应该能够与团队成员协作,互相支持和理解,以实现共同的目标。

10.客户服务:如果你的工作涉及与客户或用户直接交互,你需要具备良好的客户服务能力。这包括善于倾听客户需求、及时回应客户问题和反馈,并提供专业的支持和解决方案。

11.文档和注释:良好的文档和注释是优秀程序员的标志之一。你应该编写清晰、详细的文档,解释代码的功能和设计原理,并为代码添加有意义的注释,以便其他人能够理解和维护你的代码。

12.自我管理:作为程序员,你通常需要在工作中具备自律和自我管理的能力。这包括制定合理的工作计划、管理时间和优先级、保持专注和高效,以及平衡工作与生活。

综上所述,程序员的职业素养涉及多个方面,包括专业知识、代码质量、合作与沟通、问题解决能力、职业道德、持续学习、项目管理和时间管理、责任心,以及其他一些能力。通过不断发展和提升这些素养,你可以成为一名出色的程序员,并在职业生涯中获得成功。

最近在使用甲骨文云的免费VPS进行搭建Web服务器,过程也是一波三折,有几个坑,记录一下,希望有遇到相同问题的朋友能避过;

  1. 如果操作系统选择的ubantu,请不要选择最新的22版本,因为22版本在连接的时候会报错,无法连接,请选择20.04,可以正常连接;
  2. 甲骨文云的免费VPS只提供密钥方式连接,所以在创建VPS时,如果本地没有密钥对可用,一定要记住下载他的公钥和私钥,否则以后连接会非常麻烦;
  3. 搭建Web服务器免不了要打开80,443端口,这里需要要VPS的管理界面找到 “主要 VNIC”--“子网:xxx”,点击连接,进入界面,点击“安全列表”,添加入站规则,把80,443都添加进去,如果你觉得到这一步就完事了,那可就错了,你会发现,你的网站依然无法打开,接下来,还需要在ubantu里打开端口,具体命令如下:

    sudo iptables -I INPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    sudo iptables -I OUTPUT -p tcp --sport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT
    sudo iptables -I INPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
    sudo iptables -I OUTPUT -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
    这样才能打开端口,网站才能正确运行。

在项目编辑的时候,遇到一个问题,一直报错,

> Failed to apply plugin 'com.android.internal.application'.
> Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.

后来查阅了一下资料,原来可以针对不同项目设置不同的JDK,像以下这样设置,就可以了,记录一下。
2022-10-12T02:54:17.png

最近项目中接了一个第三方的SDK,SDK的提供方为了能让开发人员在xcode模拟器下也可以运行调试,所以在一些framework中包含了x86_64框架,可是如果打iOS包的话,这里可以通过把“Validate Workspace”设置为“YES”来解决打包报错的问题,可以正常出包了。(“Validate Workspace”的设置请参考下图)
2022-10-10T02:48:33.png

但是新的问题出现了,就是在苹果后台上传包里会报错,如下:

Asset validation failed (90087)
Unsupported Architectures. The executable for XXXX.app/Frameworks/AgoraRtcWrapper.framework contains unsupported architectures '[x86_64]'. (ID: 643f96cf-cd6b-4ad6-bc53-ebb77eab54dd)

说这个库里包含了不支持的框架,上传失败,此时我们需要做的是,把这个x86_64的框架从这个framework中删除,再重新打包;

在mac下,我们可以直接使用lipo -info 来查看framework包含哪些框架,例如上面这个

 lipo -info AgoraRtcWrapper.framework/AgoraRtcWrapper

会输出

AgoraRtcWrapper.framework/AgoraRtcWrapper are: armv7 x86_64 arm64 

可以看到确实包含了x86_64框架,那如何删除x86_64框架呢?还是用lipo命令,如下:

lipo -remove x86_64 AgoraRtcWrapper.framework/AipBase -o AgoraRtcWrapper.framework/AipBase

这样就可以把x86_64删除之后,再写回到原来的路径,最后我们再查看一下删除了x86_64的库,如下:

AgoraRtcWrapper.framework/AgoraRtcWrapper are: armv7 arm64

这里只剩下了armv7 arm64了。重新打包,这里已经不需要把“Validate Workspace”设置为“YES”了,打包后,上传,一次通过。

在要Unity Editor下查找一个资源,是否被其它预制(prefab)引用,AssetDatabase并没有给出现成的API,AssetDatabase只能查找一个游戏对象依赖了哪些资源,我们可以在启动的时候,使用AssetDatabase对每个资源建议反向索引,再进行查找,但是建议反向索引的过程还是比较耗时的,项目越大,资源越多,耗时越久。
这样的方式虽然能达到查找资源被依赖的目的,但是还不够高效,下面我们讲一下,在Mac系统下,使用系统索引的方式,快速进行资源被依赖的方法,可以在1秒内,找到资源的被依赖对象,因为Mac系统已经为文件建立好了索引,所以可以直接使用,以下是已经集成好的代码工具,可以拷贝到项目里直接使用,上代码:

using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class FindProject
{
#if UNITY_EDITOR_OSX
    private static string _curFileName;
    private static readonly List<string> References = new List<string>();

    private static bool _canOutResult;
    private static string _selectedAssetPath;
    
    [MenuItem("Assets/Find References In Project", false, 2000)]
    private static void FindProjectReferences()
    {
        var appDataPath = Application.dataPath;
        _selectedAssetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
        

        _curFileName = Path.GetFileName(_selectedAssetPath);

        var guid = AssetDatabase.AssetPathToGUID(_selectedAssetPath);

        var psi = new System.Diagnostics.ProcessStartInfo
        {
            WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized,
            FileName = "/usr/bin/mdfind",
            Arguments = "-onlyin " + Application.dataPath + " " + guid,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };
        
        EditorApplication.update += OnUpdate;

        var process = new System.Diagnostics.Process();
        process.StartInfo = psi;

        process.OutputDataReceived += (sender, e) =>
        {

            if (string.IsNullOrEmpty(e.Data))
            {
                _canOutResult = true;
            }
            else
            {
                var fileName = Path.GetFileName(e.Data);

                if (fileName.Contains(_curFileName))
                {
                    return;
                }

                var relativePath = "Assets" + e.Data.Replace(appDataPath, "");
                References.Add(relativePath);
            }

        };
        process.ErrorDataReceived += (sender, e) =>
        {
            if (string.IsNullOrEmpty(e.Data))
                return;

            // output += "Error: " + e.Data + "\n";
        };
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
    }
    
    private static void OnUpdate()
    {
        if (!_canOutResult) return;
        _canOutResult = false;
        
        var rawObj = AssetDatabase.LoadAssetAtPath<Object>(_selectedAssetPath);
        Debug.Log($"<color=aqua><b>{References.Count}</b></color> 个对象引用了 <color=fuchsia><b>{_curFileName}</b></color>", rawObj);
        
        foreach (var file in References)
        {
            var findObj = AssetDatabase.LoadAssetAtPath<Object>(file);
            Debug.Log( $"<color=lime>引用者:</color> <color=yellow>{file}</color>", findObj);
        }
    }

#endif
}